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