1*9880d681SAndroid Build Coastguard Worker //===- LoopVersioning.cpp - Utility to version a loop ---------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file defines a utility class to perform loop versioning. The versioned
11*9880d681SAndroid Build Coastguard Worker // loop speculates that otherwise may-aliasing memory accesses don't overlap and
12*9880d681SAndroid Build Coastguard Worker // emits checks to prove this.
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/LoopVersioning.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/LoopAccessAnalysis.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/LoopInfo.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ScalarEvolutionExpander.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Dominators.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/MDBuilder.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/BasicBlockUtils.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/Cloning.h"
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker using namespace llvm;
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
28*9880d681SAndroid Build Coastguard Worker AnnotateNoAlias("loop-version-annotate-no-alias", cl::init(true),
29*9880d681SAndroid Build Coastguard Worker cl::Hidden,
30*9880d681SAndroid Build Coastguard Worker cl::desc("Add no-alias annotation for instructions that "
31*9880d681SAndroid Build Coastguard Worker "are disambiguated by memchecks"));
32*9880d681SAndroid Build Coastguard Worker
LoopVersioning(const LoopAccessInfo & LAI,Loop * L,LoopInfo * LI,DominatorTree * DT,ScalarEvolution * SE,bool UseLAIChecks)33*9880d681SAndroid Build Coastguard Worker LoopVersioning::LoopVersioning(const LoopAccessInfo &LAI, Loop *L, LoopInfo *LI,
34*9880d681SAndroid Build Coastguard Worker DominatorTree *DT, ScalarEvolution *SE,
35*9880d681SAndroid Build Coastguard Worker bool UseLAIChecks)
36*9880d681SAndroid Build Coastguard Worker : VersionedLoop(L), NonVersionedLoop(nullptr), LAI(LAI), LI(LI), DT(DT),
37*9880d681SAndroid Build Coastguard Worker SE(SE) {
38*9880d681SAndroid Build Coastguard Worker assert(L->getExitBlock() && "No single exit block");
39*9880d681SAndroid Build Coastguard Worker assert(L->getLoopPreheader() && "No preheader");
40*9880d681SAndroid Build Coastguard Worker if (UseLAIChecks) {
41*9880d681SAndroid Build Coastguard Worker setAliasChecks(LAI.getRuntimePointerChecking()->getChecks());
42*9880d681SAndroid Build Coastguard Worker setSCEVChecks(LAI.getPSE().getUnionPredicate());
43*9880d681SAndroid Build Coastguard Worker }
44*9880d681SAndroid Build Coastguard Worker }
45*9880d681SAndroid Build Coastguard Worker
setAliasChecks(SmallVector<RuntimePointerChecking::PointerCheck,4> Checks)46*9880d681SAndroid Build Coastguard Worker void LoopVersioning::setAliasChecks(
47*9880d681SAndroid Build Coastguard Worker SmallVector<RuntimePointerChecking::PointerCheck, 4> Checks) {
48*9880d681SAndroid Build Coastguard Worker AliasChecks = std::move(Checks);
49*9880d681SAndroid Build Coastguard Worker }
50*9880d681SAndroid Build Coastguard Worker
setSCEVChecks(SCEVUnionPredicate Check)51*9880d681SAndroid Build Coastguard Worker void LoopVersioning::setSCEVChecks(SCEVUnionPredicate Check) {
52*9880d681SAndroid Build Coastguard Worker Preds = std::move(Check);
53*9880d681SAndroid Build Coastguard Worker }
54*9880d681SAndroid Build Coastguard Worker
versionLoop(const SmallVectorImpl<Instruction * > & DefsUsedOutside)55*9880d681SAndroid Build Coastguard Worker void LoopVersioning::versionLoop(
56*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<Instruction *> &DefsUsedOutside) {
57*9880d681SAndroid Build Coastguard Worker Instruction *FirstCheckInst;
58*9880d681SAndroid Build Coastguard Worker Instruction *MemRuntimeCheck;
59*9880d681SAndroid Build Coastguard Worker Value *SCEVRuntimeCheck;
60*9880d681SAndroid Build Coastguard Worker Value *RuntimeCheck = nullptr;
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker // Add the memcheck in the original preheader (this is empty initially).
63*9880d681SAndroid Build Coastguard Worker BasicBlock *RuntimeCheckBB = VersionedLoop->getLoopPreheader();
64*9880d681SAndroid Build Coastguard Worker std::tie(FirstCheckInst, MemRuntimeCheck) =
65*9880d681SAndroid Build Coastguard Worker LAI.addRuntimeChecks(RuntimeCheckBB->getTerminator(), AliasChecks);
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker const SCEVUnionPredicate &Pred = LAI.getPSE().getUnionPredicate();
68*9880d681SAndroid Build Coastguard Worker SCEVExpander Exp(*SE, RuntimeCheckBB->getModule()->getDataLayout(),
69*9880d681SAndroid Build Coastguard Worker "scev.check");
70*9880d681SAndroid Build Coastguard Worker SCEVRuntimeCheck =
71*9880d681SAndroid Build Coastguard Worker Exp.expandCodeForPredicate(&Pred, RuntimeCheckBB->getTerminator());
72*9880d681SAndroid Build Coastguard Worker auto *CI = dyn_cast<ConstantInt>(SCEVRuntimeCheck);
73*9880d681SAndroid Build Coastguard Worker
74*9880d681SAndroid Build Coastguard Worker // Discard the SCEV runtime check if it is always true.
75*9880d681SAndroid Build Coastguard Worker if (CI && CI->isZero())
76*9880d681SAndroid Build Coastguard Worker SCEVRuntimeCheck = nullptr;
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker if (MemRuntimeCheck && SCEVRuntimeCheck) {
79*9880d681SAndroid Build Coastguard Worker RuntimeCheck = BinaryOperator::Create(Instruction::Or, MemRuntimeCheck,
80*9880d681SAndroid Build Coastguard Worker SCEVRuntimeCheck, "lver.safe");
81*9880d681SAndroid Build Coastguard Worker if (auto *I = dyn_cast<Instruction>(RuntimeCheck))
82*9880d681SAndroid Build Coastguard Worker I->insertBefore(RuntimeCheckBB->getTerminator());
83*9880d681SAndroid Build Coastguard Worker } else
84*9880d681SAndroid Build Coastguard Worker RuntimeCheck = MemRuntimeCheck ? MemRuntimeCheck : SCEVRuntimeCheck;
85*9880d681SAndroid Build Coastguard Worker
86*9880d681SAndroid Build Coastguard Worker assert(RuntimeCheck && "called even though we don't need "
87*9880d681SAndroid Build Coastguard Worker "any runtime checks");
88*9880d681SAndroid Build Coastguard Worker
89*9880d681SAndroid Build Coastguard Worker // Rename the block to make the IR more readable.
90*9880d681SAndroid Build Coastguard Worker RuntimeCheckBB->setName(VersionedLoop->getHeader()->getName() +
91*9880d681SAndroid Build Coastguard Worker ".lver.check");
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Worker // Create empty preheader for the loop (and after cloning for the
94*9880d681SAndroid Build Coastguard Worker // non-versioned loop).
95*9880d681SAndroid Build Coastguard Worker BasicBlock *PH =
96*9880d681SAndroid Build Coastguard Worker SplitBlock(RuntimeCheckBB, RuntimeCheckBB->getTerminator(), DT, LI);
97*9880d681SAndroid Build Coastguard Worker PH->setName(VersionedLoop->getHeader()->getName() + ".ph");
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker // Clone the loop including the preheader.
100*9880d681SAndroid Build Coastguard Worker //
101*9880d681SAndroid Build Coastguard Worker // FIXME: This does not currently preserve SimplifyLoop because the exit
102*9880d681SAndroid Build Coastguard Worker // block is a join between the two loops.
103*9880d681SAndroid Build Coastguard Worker SmallVector<BasicBlock *, 8> NonVersionedLoopBlocks;
104*9880d681SAndroid Build Coastguard Worker NonVersionedLoop =
105*9880d681SAndroid Build Coastguard Worker cloneLoopWithPreheader(PH, RuntimeCheckBB, VersionedLoop, VMap,
106*9880d681SAndroid Build Coastguard Worker ".lver.orig", LI, DT, NonVersionedLoopBlocks);
107*9880d681SAndroid Build Coastguard Worker remapInstructionsInBlocks(NonVersionedLoopBlocks, VMap);
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker // Insert the conditional branch based on the result of the memchecks.
110*9880d681SAndroid Build Coastguard Worker Instruction *OrigTerm = RuntimeCheckBB->getTerminator();
111*9880d681SAndroid Build Coastguard Worker BranchInst::Create(NonVersionedLoop->getLoopPreheader(),
112*9880d681SAndroid Build Coastguard Worker VersionedLoop->getLoopPreheader(), RuntimeCheck, OrigTerm);
113*9880d681SAndroid Build Coastguard Worker OrigTerm->eraseFromParent();
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker // The loops merge in the original exit block. This is now dominated by the
116*9880d681SAndroid Build Coastguard Worker // memchecking block.
117*9880d681SAndroid Build Coastguard Worker DT->changeImmediateDominator(VersionedLoop->getExitBlock(), RuntimeCheckBB);
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker // Adds the necessary PHI nodes for the versioned loops based on the
120*9880d681SAndroid Build Coastguard Worker // loop-defined values used outside of the loop.
121*9880d681SAndroid Build Coastguard Worker addPHINodes(DefsUsedOutside);
122*9880d681SAndroid Build Coastguard Worker }
123*9880d681SAndroid Build Coastguard Worker
addPHINodes(const SmallVectorImpl<Instruction * > & DefsUsedOutside)124*9880d681SAndroid Build Coastguard Worker void LoopVersioning::addPHINodes(
125*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<Instruction *> &DefsUsedOutside) {
126*9880d681SAndroid Build Coastguard Worker BasicBlock *PHIBlock = VersionedLoop->getExitBlock();
127*9880d681SAndroid Build Coastguard Worker assert(PHIBlock && "No single successor to loop exit block");
128*9880d681SAndroid Build Coastguard Worker PHINode *PN;
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker // First add a single-operand PHI for each DefsUsedOutside if one does not
131*9880d681SAndroid Build Coastguard Worker // exists yet.
132*9880d681SAndroid Build Coastguard Worker for (auto *Inst : DefsUsedOutside) {
133*9880d681SAndroid Build Coastguard Worker // See if we have a single-operand PHI with the value defined by the
134*9880d681SAndroid Build Coastguard Worker // original loop.
135*9880d681SAndroid Build Coastguard Worker for (auto I = PHIBlock->begin(); (PN = dyn_cast<PHINode>(I)); ++I) {
136*9880d681SAndroid Build Coastguard Worker if (PN->getIncomingValue(0) == Inst)
137*9880d681SAndroid Build Coastguard Worker break;
138*9880d681SAndroid Build Coastguard Worker }
139*9880d681SAndroid Build Coastguard Worker // If not create it.
140*9880d681SAndroid Build Coastguard Worker if (!PN) {
141*9880d681SAndroid Build Coastguard Worker PN = PHINode::Create(Inst->getType(), 2, Inst->getName() + ".lver",
142*9880d681SAndroid Build Coastguard Worker &PHIBlock->front());
143*9880d681SAndroid Build Coastguard Worker for (auto *User : Inst->users())
144*9880d681SAndroid Build Coastguard Worker if (!VersionedLoop->contains(cast<Instruction>(User)->getParent()))
145*9880d681SAndroid Build Coastguard Worker User->replaceUsesOfWith(Inst, PN);
146*9880d681SAndroid Build Coastguard Worker PN->addIncoming(Inst, VersionedLoop->getExitingBlock());
147*9880d681SAndroid Build Coastguard Worker }
148*9880d681SAndroid Build Coastguard Worker }
149*9880d681SAndroid Build Coastguard Worker
150*9880d681SAndroid Build Coastguard Worker // Then for each PHI add the operand for the edge from the cloned loop.
151*9880d681SAndroid Build Coastguard Worker for (auto I = PHIBlock->begin(); (PN = dyn_cast<PHINode>(I)); ++I) {
152*9880d681SAndroid Build Coastguard Worker assert(PN->getNumOperands() == 1 &&
153*9880d681SAndroid Build Coastguard Worker "Exit block should only have on predecessor");
154*9880d681SAndroid Build Coastguard Worker
155*9880d681SAndroid Build Coastguard Worker // If the definition was cloned used that otherwise use the same value.
156*9880d681SAndroid Build Coastguard Worker Value *ClonedValue = PN->getIncomingValue(0);
157*9880d681SAndroid Build Coastguard Worker auto Mapped = VMap.find(ClonedValue);
158*9880d681SAndroid Build Coastguard Worker if (Mapped != VMap.end())
159*9880d681SAndroid Build Coastguard Worker ClonedValue = Mapped->second;
160*9880d681SAndroid Build Coastguard Worker
161*9880d681SAndroid Build Coastguard Worker PN->addIncoming(ClonedValue, NonVersionedLoop->getExitingBlock());
162*9880d681SAndroid Build Coastguard Worker }
163*9880d681SAndroid Build Coastguard Worker }
164*9880d681SAndroid Build Coastguard Worker
prepareNoAliasMetadata()165*9880d681SAndroid Build Coastguard Worker void LoopVersioning::prepareNoAliasMetadata() {
166*9880d681SAndroid Build Coastguard Worker // We need to turn the no-alias relation between pointer checking groups into
167*9880d681SAndroid Build Coastguard Worker // no-aliasing annotations between instructions.
168*9880d681SAndroid Build Coastguard Worker //
169*9880d681SAndroid Build Coastguard Worker // We accomplish this by mapping each pointer checking group (a set of
170*9880d681SAndroid Build Coastguard Worker // pointers memchecked together) to an alias scope and then also mapping each
171*9880d681SAndroid Build Coastguard Worker // group to the list of scopes it can't alias.
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Worker const RuntimePointerChecking *RtPtrChecking = LAI.getRuntimePointerChecking();
174*9880d681SAndroid Build Coastguard Worker LLVMContext &Context = VersionedLoop->getHeader()->getContext();
175*9880d681SAndroid Build Coastguard Worker
176*9880d681SAndroid Build Coastguard Worker // First allocate an aliasing scope for each pointer checking group.
177*9880d681SAndroid Build Coastguard Worker //
178*9880d681SAndroid Build Coastguard Worker // While traversing through the checking groups in the loop, also create a
179*9880d681SAndroid Build Coastguard Worker // reverse map from pointers to the pointer checking group they were assigned
180*9880d681SAndroid Build Coastguard Worker // to.
181*9880d681SAndroid Build Coastguard Worker MDBuilder MDB(Context);
182*9880d681SAndroid Build Coastguard Worker MDNode *Domain = MDB.createAnonymousAliasScopeDomain("LVerDomain");
183*9880d681SAndroid Build Coastguard Worker
184*9880d681SAndroid Build Coastguard Worker for (const auto &Group : RtPtrChecking->CheckingGroups) {
185*9880d681SAndroid Build Coastguard Worker GroupToScope[&Group] = MDB.createAnonymousAliasScope(Domain);
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard Worker for (unsigned PtrIdx : Group.Members)
188*9880d681SAndroid Build Coastguard Worker PtrToGroup[RtPtrChecking->getPointerInfo(PtrIdx).PointerValue] = &Group;
189*9880d681SAndroid Build Coastguard Worker }
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Worker // Go through the checks and for each pointer group, collect the scopes for
192*9880d681SAndroid Build Coastguard Worker // each non-aliasing pointer group.
193*9880d681SAndroid Build Coastguard Worker DenseMap<const RuntimePointerChecking::CheckingPtrGroup *,
194*9880d681SAndroid Build Coastguard Worker SmallVector<Metadata *, 4>>
195*9880d681SAndroid Build Coastguard Worker GroupToNonAliasingScopes;
196*9880d681SAndroid Build Coastguard Worker
197*9880d681SAndroid Build Coastguard Worker for (const auto &Check : AliasChecks)
198*9880d681SAndroid Build Coastguard Worker GroupToNonAliasingScopes[Check.first].push_back(GroupToScope[Check.second]);
199*9880d681SAndroid Build Coastguard Worker
200*9880d681SAndroid Build Coastguard Worker // Finally, transform the above to actually map to scope list which is what
201*9880d681SAndroid Build Coastguard Worker // the metadata uses.
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Worker for (auto Pair : GroupToNonAliasingScopes)
204*9880d681SAndroid Build Coastguard Worker GroupToNonAliasingScopeList[Pair.first] = MDNode::get(Context, Pair.second);
205*9880d681SAndroid Build Coastguard Worker }
206*9880d681SAndroid Build Coastguard Worker
annotateLoopWithNoAlias()207*9880d681SAndroid Build Coastguard Worker void LoopVersioning::annotateLoopWithNoAlias() {
208*9880d681SAndroid Build Coastguard Worker if (!AnnotateNoAlias)
209*9880d681SAndroid Build Coastguard Worker return;
210*9880d681SAndroid Build Coastguard Worker
211*9880d681SAndroid Build Coastguard Worker // First prepare the maps.
212*9880d681SAndroid Build Coastguard Worker prepareNoAliasMetadata();
213*9880d681SAndroid Build Coastguard Worker
214*9880d681SAndroid Build Coastguard Worker // Add the scope and no-alias metadata to the instructions.
215*9880d681SAndroid Build Coastguard Worker for (Instruction *I : LAI.getDepChecker().getMemoryInstructions()) {
216*9880d681SAndroid Build Coastguard Worker annotateInstWithNoAlias(I);
217*9880d681SAndroid Build Coastguard Worker }
218*9880d681SAndroid Build Coastguard Worker }
219*9880d681SAndroid Build Coastguard Worker
annotateInstWithNoAlias(Instruction * VersionedInst,const Instruction * OrigInst)220*9880d681SAndroid Build Coastguard Worker void LoopVersioning::annotateInstWithNoAlias(Instruction *VersionedInst,
221*9880d681SAndroid Build Coastguard Worker const Instruction *OrigInst) {
222*9880d681SAndroid Build Coastguard Worker if (!AnnotateNoAlias)
223*9880d681SAndroid Build Coastguard Worker return;
224*9880d681SAndroid Build Coastguard Worker
225*9880d681SAndroid Build Coastguard Worker LLVMContext &Context = VersionedLoop->getHeader()->getContext();
226*9880d681SAndroid Build Coastguard Worker const Value *Ptr = isa<LoadInst>(OrigInst)
227*9880d681SAndroid Build Coastguard Worker ? cast<LoadInst>(OrigInst)->getPointerOperand()
228*9880d681SAndroid Build Coastguard Worker : cast<StoreInst>(OrigInst)->getPointerOperand();
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard Worker // Find the group for the pointer and then add the scope metadata.
231*9880d681SAndroid Build Coastguard Worker auto Group = PtrToGroup.find(Ptr);
232*9880d681SAndroid Build Coastguard Worker if (Group != PtrToGroup.end()) {
233*9880d681SAndroid Build Coastguard Worker VersionedInst->setMetadata(
234*9880d681SAndroid Build Coastguard Worker LLVMContext::MD_alias_scope,
235*9880d681SAndroid Build Coastguard Worker MDNode::concatenate(
236*9880d681SAndroid Build Coastguard Worker VersionedInst->getMetadata(LLVMContext::MD_alias_scope),
237*9880d681SAndroid Build Coastguard Worker MDNode::get(Context, GroupToScope[Group->second])));
238*9880d681SAndroid Build Coastguard Worker
239*9880d681SAndroid Build Coastguard Worker // Add the no-alias metadata.
240*9880d681SAndroid Build Coastguard Worker auto NonAliasingScopeList = GroupToNonAliasingScopeList.find(Group->second);
241*9880d681SAndroid Build Coastguard Worker if (NonAliasingScopeList != GroupToNonAliasingScopeList.end())
242*9880d681SAndroid Build Coastguard Worker VersionedInst->setMetadata(
243*9880d681SAndroid Build Coastguard Worker LLVMContext::MD_noalias,
244*9880d681SAndroid Build Coastguard Worker MDNode::concatenate(
245*9880d681SAndroid Build Coastguard Worker VersionedInst->getMetadata(LLVMContext::MD_noalias),
246*9880d681SAndroid Build Coastguard Worker NonAliasingScopeList->second));
247*9880d681SAndroid Build Coastguard Worker }
248*9880d681SAndroid Build Coastguard Worker }
249*9880d681SAndroid Build Coastguard Worker
250*9880d681SAndroid Build Coastguard Worker namespace {
251*9880d681SAndroid Build Coastguard Worker /// \brief Also expose this is a pass. Currently this is only used for
252*9880d681SAndroid Build Coastguard Worker /// unit-testing. It adds all memchecks necessary to remove all may-aliasing
253*9880d681SAndroid Build Coastguard Worker /// array accesses from the loop.
254*9880d681SAndroid Build Coastguard Worker class LoopVersioningPass : public FunctionPass {
255*9880d681SAndroid Build Coastguard Worker public:
LoopVersioningPass()256*9880d681SAndroid Build Coastguard Worker LoopVersioningPass() : FunctionPass(ID) {
257*9880d681SAndroid Build Coastguard Worker initializeLoopVersioningPassPass(*PassRegistry::getPassRegistry());
258*9880d681SAndroid Build Coastguard Worker }
259*9880d681SAndroid Build Coastguard Worker
runOnFunction(Function & F)260*9880d681SAndroid Build Coastguard Worker bool runOnFunction(Function &F) override {
261*9880d681SAndroid Build Coastguard Worker auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
262*9880d681SAndroid Build Coastguard Worker auto *LAA = &getAnalysis<LoopAccessLegacyAnalysis>();
263*9880d681SAndroid Build Coastguard Worker auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
264*9880d681SAndroid Build Coastguard Worker auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
265*9880d681SAndroid Build Coastguard Worker
266*9880d681SAndroid Build Coastguard Worker // Build up a worklist of inner-loops to version. This is necessary as the
267*9880d681SAndroid Build Coastguard Worker // act of versioning a loop creates new loops and can invalidate iterators
268*9880d681SAndroid Build Coastguard Worker // across the loops.
269*9880d681SAndroid Build Coastguard Worker SmallVector<Loop *, 8> Worklist;
270*9880d681SAndroid Build Coastguard Worker
271*9880d681SAndroid Build Coastguard Worker for (Loop *TopLevelLoop : *LI)
272*9880d681SAndroid Build Coastguard Worker for (Loop *L : depth_first(TopLevelLoop))
273*9880d681SAndroid Build Coastguard Worker // We only handle inner-most loops.
274*9880d681SAndroid Build Coastguard Worker if (L->empty())
275*9880d681SAndroid Build Coastguard Worker Worklist.push_back(L);
276*9880d681SAndroid Build Coastguard Worker
277*9880d681SAndroid Build Coastguard Worker // Now walk the identified inner loops.
278*9880d681SAndroid Build Coastguard Worker bool Changed = false;
279*9880d681SAndroid Build Coastguard Worker for (Loop *L : Worklist) {
280*9880d681SAndroid Build Coastguard Worker const LoopAccessInfo &LAI = LAA->getInfo(L);
281*9880d681SAndroid Build Coastguard Worker if (LAI.getNumRuntimePointerChecks() ||
282*9880d681SAndroid Build Coastguard Worker !LAI.getPSE().getUnionPredicate().isAlwaysTrue()) {
283*9880d681SAndroid Build Coastguard Worker LoopVersioning LVer(LAI, L, LI, DT, SE);
284*9880d681SAndroid Build Coastguard Worker LVer.versionLoop();
285*9880d681SAndroid Build Coastguard Worker LVer.annotateLoopWithNoAlias();
286*9880d681SAndroid Build Coastguard Worker Changed = true;
287*9880d681SAndroid Build Coastguard Worker }
288*9880d681SAndroid Build Coastguard Worker }
289*9880d681SAndroid Build Coastguard Worker
290*9880d681SAndroid Build Coastguard Worker return Changed;
291*9880d681SAndroid Build Coastguard Worker }
292*9880d681SAndroid Build Coastguard Worker
getAnalysisUsage(AnalysisUsage & AU) const293*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &AU) const override {
294*9880d681SAndroid Build Coastguard Worker AU.addRequired<LoopInfoWrapperPass>();
295*9880d681SAndroid Build Coastguard Worker AU.addPreserved<LoopInfoWrapperPass>();
296*9880d681SAndroid Build Coastguard Worker AU.addRequired<LoopAccessLegacyAnalysis>();
297*9880d681SAndroid Build Coastguard Worker AU.addRequired<DominatorTreeWrapperPass>();
298*9880d681SAndroid Build Coastguard Worker AU.addPreserved<DominatorTreeWrapperPass>();
299*9880d681SAndroid Build Coastguard Worker AU.addRequired<ScalarEvolutionWrapperPass>();
300*9880d681SAndroid Build Coastguard Worker }
301*9880d681SAndroid Build Coastguard Worker
302*9880d681SAndroid Build Coastguard Worker static char ID;
303*9880d681SAndroid Build Coastguard Worker };
304*9880d681SAndroid Build Coastguard Worker }
305*9880d681SAndroid Build Coastguard Worker
306*9880d681SAndroid Build Coastguard Worker #define LVER_OPTION "loop-versioning"
307*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE LVER_OPTION
308*9880d681SAndroid Build Coastguard Worker
309*9880d681SAndroid Build Coastguard Worker char LoopVersioningPass::ID;
310*9880d681SAndroid Build Coastguard Worker static const char LVer_name[] = "Loop Versioning";
311*9880d681SAndroid Build Coastguard Worker
312*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_BEGIN(LoopVersioningPass, LVER_OPTION, LVer_name, false, false)
313*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
314*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(LoopAccessLegacyAnalysis)
315*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
316*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
317*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_END(LoopVersioningPass, LVER_OPTION, LVer_name, false, false)
318*9880d681SAndroid Build Coastguard Worker
319*9880d681SAndroid Build Coastguard Worker namespace llvm {
createLoopVersioningPass()320*9880d681SAndroid Build Coastguard Worker FunctionPass *createLoopVersioningPass() {
321*9880d681SAndroid Build Coastguard Worker return new LoopVersioningPass();
322*9880d681SAndroid Build Coastguard Worker }
323*9880d681SAndroid Build Coastguard Worker }
324