xref: /aosp_15_r20/external/llvm/lib/Transforms/Utils/LoopVersioning.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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