1875ed548SDimitry Andric //===- LoopVersioning.cpp - Utility to version a loop ---------------------===//
2875ed548SDimitry Andric //
3875ed548SDimitry Andric //                     The LLVM Compiler Infrastructure
4875ed548SDimitry Andric //
5875ed548SDimitry Andric // This file is distributed under the University of Illinois Open Source
6875ed548SDimitry Andric // License. See LICENSE.TXT for details.
7875ed548SDimitry Andric //
8875ed548SDimitry Andric //===----------------------------------------------------------------------===//
9875ed548SDimitry Andric //
10875ed548SDimitry Andric // This file defines a utility class to perform loop versioning.  The versioned
11875ed548SDimitry Andric // loop speculates that otherwise may-aliasing memory accesses don't overlap and
12875ed548SDimitry Andric // emits checks to prove this.
13875ed548SDimitry Andric //
14875ed548SDimitry Andric //===----------------------------------------------------------------------===//
15875ed548SDimitry Andric 
167d523365SDimitry Andric #include "llvm/Transforms/Utils/LoopVersioning.h"
17875ed548SDimitry Andric #include "llvm/Analysis/LoopAccessAnalysis.h"
18875ed548SDimitry Andric #include "llvm/Analysis/LoopInfo.h"
197d523365SDimitry Andric #include "llvm/Analysis/ScalarEvolutionExpander.h"
20875ed548SDimitry Andric #include "llvm/IR/Dominators.h"
213ca95b02SDimitry Andric #include "llvm/IR/MDBuilder.h"
22875ed548SDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h"
23875ed548SDimitry Andric #include "llvm/Transforms/Utils/Cloning.h"
24875ed548SDimitry Andric 
25875ed548SDimitry Andric using namespace llvm;
26875ed548SDimitry Andric 
273ca95b02SDimitry Andric static cl::opt<bool>
283ca95b02SDimitry Andric     AnnotateNoAlias("loop-version-annotate-no-alias", cl::init(true),
293ca95b02SDimitry Andric                     cl::Hidden,
303ca95b02SDimitry Andric                     cl::desc("Add no-alias annotation for instructions that "
313ca95b02SDimitry Andric                              "are disambiguated by memchecks"));
323ca95b02SDimitry Andric 
LoopVersioning(const LoopAccessInfo & LAI,Loop * L,LoopInfo * LI,DominatorTree * DT,ScalarEvolution * SE,bool UseLAIChecks)33875ed548SDimitry Andric LoopVersioning::LoopVersioning(const LoopAccessInfo &LAI, Loop *L, LoopInfo *LI,
347d523365SDimitry Andric                                DominatorTree *DT, ScalarEvolution *SE,
357d523365SDimitry Andric                                bool UseLAIChecks)
367d523365SDimitry Andric     : VersionedLoop(L), NonVersionedLoop(nullptr), LAI(LAI), LI(LI), DT(DT),
377d523365SDimitry Andric       SE(SE) {
38875ed548SDimitry Andric   assert(L->getExitBlock() && "No single exit block");
39d88c1a5aSDimitry Andric   assert(L->isLoopSimplifyForm() && "Loop is not in loop-simplify form");
407d523365SDimitry Andric   if (UseLAIChecks) {
417d523365SDimitry Andric     setAliasChecks(LAI.getRuntimePointerChecking()->getChecks());
423ca95b02SDimitry Andric     setSCEVChecks(LAI.getPSE().getUnionPredicate());
437d523365SDimitry Andric   }
44875ed548SDimitry Andric }
45875ed548SDimitry Andric 
setAliasChecks(SmallVector<RuntimePointerChecking::PointerCheck,4> Checks)467d523365SDimitry Andric void LoopVersioning::setAliasChecks(
473ca95b02SDimitry Andric     SmallVector<RuntimePointerChecking::PointerCheck, 4> Checks) {
487d523365SDimitry Andric   AliasChecks = std::move(Checks);
49875ed548SDimitry Andric }
50875ed548SDimitry Andric 
setSCEVChecks(SCEVUnionPredicate Check)517d523365SDimitry Andric void LoopVersioning::setSCEVChecks(SCEVUnionPredicate Check) {
527d523365SDimitry Andric   Preds = std::move(Check);
537d523365SDimitry Andric }
547d523365SDimitry Andric 
versionLoop(const SmallVectorImpl<Instruction * > & DefsUsedOutside)557d523365SDimitry Andric void LoopVersioning::versionLoop(
567d523365SDimitry Andric     const SmallVectorImpl<Instruction *> &DefsUsedOutside) {
57875ed548SDimitry Andric   Instruction *FirstCheckInst;
58875ed548SDimitry Andric   Instruction *MemRuntimeCheck;
597d523365SDimitry Andric   Value *SCEVRuntimeCheck;
607d523365SDimitry Andric   Value *RuntimeCheck = nullptr;
617d523365SDimitry Andric 
62875ed548SDimitry Andric   // Add the memcheck in the original preheader (this is empty initially).
637d523365SDimitry Andric   BasicBlock *RuntimeCheckBB = VersionedLoop->getLoopPreheader();
64875ed548SDimitry Andric   std::tie(FirstCheckInst, MemRuntimeCheck) =
657d523365SDimitry Andric       LAI.addRuntimeChecks(RuntimeCheckBB->getTerminator(), AliasChecks);
66875ed548SDimitry Andric 
673ca95b02SDimitry Andric   const SCEVUnionPredicate &Pred = LAI.getPSE().getUnionPredicate();
687d523365SDimitry Andric   SCEVExpander Exp(*SE, RuntimeCheckBB->getModule()->getDataLayout(),
697d523365SDimitry Andric                    "scev.check");
707d523365SDimitry Andric   SCEVRuntimeCheck =
717d523365SDimitry Andric       Exp.expandCodeForPredicate(&Pred, RuntimeCheckBB->getTerminator());
727d523365SDimitry Andric   auto *CI = dyn_cast<ConstantInt>(SCEVRuntimeCheck);
737d523365SDimitry Andric 
747d523365SDimitry Andric   // Discard the SCEV runtime check if it is always true.
757d523365SDimitry Andric   if (CI && CI->isZero())
767d523365SDimitry Andric     SCEVRuntimeCheck = nullptr;
777d523365SDimitry Andric 
787d523365SDimitry Andric   if (MemRuntimeCheck && SCEVRuntimeCheck) {
797d523365SDimitry Andric     RuntimeCheck = BinaryOperator::Create(Instruction::Or, MemRuntimeCheck,
803ca95b02SDimitry Andric                                           SCEVRuntimeCheck, "lver.safe");
817d523365SDimitry Andric     if (auto *I = dyn_cast<Instruction>(RuntimeCheck))
827d523365SDimitry Andric       I->insertBefore(RuntimeCheckBB->getTerminator());
837d523365SDimitry Andric   } else
847d523365SDimitry Andric     RuntimeCheck = MemRuntimeCheck ? MemRuntimeCheck : SCEVRuntimeCheck;
857d523365SDimitry Andric 
867d523365SDimitry Andric   assert(RuntimeCheck && "called even though we don't need "
877d523365SDimitry Andric                          "any runtime checks");
887d523365SDimitry Andric 
89875ed548SDimitry Andric   // Rename the block to make the IR more readable.
907d523365SDimitry Andric   RuntimeCheckBB->setName(VersionedLoop->getHeader()->getName() +
917d523365SDimitry Andric                           ".lver.check");
92875ed548SDimitry Andric 
93875ed548SDimitry Andric   // Create empty preheader for the loop (and after cloning for the
94875ed548SDimitry Andric   // non-versioned loop).
957d523365SDimitry Andric   BasicBlock *PH =
967d523365SDimitry Andric       SplitBlock(RuntimeCheckBB, RuntimeCheckBB->getTerminator(), DT, LI);
97875ed548SDimitry Andric   PH->setName(VersionedLoop->getHeader()->getName() + ".ph");
98875ed548SDimitry Andric 
99875ed548SDimitry Andric   // Clone the loop including the preheader.
100875ed548SDimitry Andric   //
101875ed548SDimitry Andric   // FIXME: This does not currently preserve SimplifyLoop because the exit
102875ed548SDimitry Andric   // block is a join between the two loops.
103875ed548SDimitry Andric   SmallVector<BasicBlock *, 8> NonVersionedLoopBlocks;
104875ed548SDimitry Andric   NonVersionedLoop =
1057d523365SDimitry Andric       cloneLoopWithPreheader(PH, RuntimeCheckBB, VersionedLoop, VMap,
1067d523365SDimitry Andric                              ".lver.orig", LI, DT, NonVersionedLoopBlocks);
107875ed548SDimitry Andric   remapInstructionsInBlocks(NonVersionedLoopBlocks, VMap);
108875ed548SDimitry Andric 
109875ed548SDimitry Andric   // Insert the conditional branch based on the result of the memchecks.
1107d523365SDimitry Andric   Instruction *OrigTerm = RuntimeCheckBB->getTerminator();
111875ed548SDimitry Andric   BranchInst::Create(NonVersionedLoop->getLoopPreheader(),
1127d523365SDimitry Andric                      VersionedLoop->getLoopPreheader(), RuntimeCheck, OrigTerm);
113875ed548SDimitry Andric   OrigTerm->eraseFromParent();
114875ed548SDimitry Andric 
115875ed548SDimitry Andric   // The loops merge in the original exit block.  This is now dominated by the
116875ed548SDimitry Andric   // memchecking block.
1177d523365SDimitry Andric   DT->changeImmediateDominator(VersionedLoop->getExitBlock(), RuntimeCheckBB);
1187d523365SDimitry Andric 
1197d523365SDimitry Andric   // Adds the necessary PHI nodes for the versioned loops based on the
1207d523365SDimitry Andric   // loop-defined values used outside of the loop.
1217d523365SDimitry Andric   addPHINodes(DefsUsedOutside);
122875ed548SDimitry Andric }
123875ed548SDimitry Andric 
addPHINodes(const SmallVectorImpl<Instruction * > & DefsUsedOutside)124875ed548SDimitry Andric void LoopVersioning::addPHINodes(
125875ed548SDimitry Andric     const SmallVectorImpl<Instruction *> &DefsUsedOutside) {
126875ed548SDimitry Andric   BasicBlock *PHIBlock = VersionedLoop->getExitBlock();
127875ed548SDimitry Andric   assert(PHIBlock && "No single successor to loop exit block");
128875ed548SDimitry Andric   PHINode *PN;
129875ed548SDimitry Andric 
1303ca95b02SDimitry Andric   // First add a single-operand PHI for each DefsUsedOutside if one does not
1313ca95b02SDimitry Andric   // exists yet.
1323ca95b02SDimitry Andric   for (auto *Inst : DefsUsedOutside) {
1333ca95b02SDimitry Andric     // See if we have a single-operand PHI with the value defined by the
134875ed548SDimitry Andric     // original loop.
135875ed548SDimitry Andric     for (auto I = PHIBlock->begin(); (PN = dyn_cast<PHINode>(I)); ++I) {
136875ed548SDimitry Andric       if (PN->getIncomingValue(0) == Inst)
137875ed548SDimitry Andric         break;
138875ed548SDimitry Andric     }
139875ed548SDimitry Andric     // If not create it.
140875ed548SDimitry Andric     if (!PN) {
141875ed548SDimitry Andric       PN = PHINode::Create(Inst->getType(), 2, Inst->getName() + ".lver",
1427d523365SDimitry Andric                            &PHIBlock->front());
143*4ba319b5SDimitry Andric       SmallVector<User*, 8> UsersToUpdate;
144*4ba319b5SDimitry Andric       for (User *U : Inst->users())
145*4ba319b5SDimitry Andric         if (!VersionedLoop->contains(cast<Instruction>(U)->getParent()))
146*4ba319b5SDimitry Andric           UsersToUpdate.push_back(U);
147*4ba319b5SDimitry Andric       for (User *U : UsersToUpdate)
148*4ba319b5SDimitry Andric         U->replaceUsesOfWith(Inst, PN);
149875ed548SDimitry Andric       PN->addIncoming(Inst, VersionedLoop->getExitingBlock());
150875ed548SDimitry Andric     }
1513ca95b02SDimitry Andric   }
1523ca95b02SDimitry Andric 
1533ca95b02SDimitry Andric   // Then for each PHI add the operand for the edge from the cloned loop.
1543ca95b02SDimitry Andric   for (auto I = PHIBlock->begin(); (PN = dyn_cast<PHINode>(I)); ++I) {
1553ca95b02SDimitry Andric     assert(PN->getNumOperands() == 1 &&
1563ca95b02SDimitry Andric            "Exit block should only have on predecessor");
1573ca95b02SDimitry Andric 
1583ca95b02SDimitry Andric     // If the definition was cloned used that otherwise use the same value.
1593ca95b02SDimitry Andric     Value *ClonedValue = PN->getIncomingValue(0);
1603ca95b02SDimitry Andric     auto Mapped = VMap.find(ClonedValue);
1613ca95b02SDimitry Andric     if (Mapped != VMap.end())
1623ca95b02SDimitry Andric       ClonedValue = Mapped->second;
1633ca95b02SDimitry Andric 
1643ca95b02SDimitry Andric     PN->addIncoming(ClonedValue, NonVersionedLoop->getExitingBlock());
1653ca95b02SDimitry Andric   }
1663ca95b02SDimitry Andric }
1673ca95b02SDimitry Andric 
prepareNoAliasMetadata()1683ca95b02SDimitry Andric void LoopVersioning::prepareNoAliasMetadata() {
1693ca95b02SDimitry Andric   // We need to turn the no-alias relation between pointer checking groups into
1703ca95b02SDimitry Andric   // no-aliasing annotations between instructions.
1713ca95b02SDimitry Andric   //
1723ca95b02SDimitry Andric   // We accomplish this by mapping each pointer checking group (a set of
1733ca95b02SDimitry Andric   // pointers memchecked together) to an alias scope and then also mapping each
1743ca95b02SDimitry Andric   // group to the list of scopes it can't alias.
1753ca95b02SDimitry Andric 
1763ca95b02SDimitry Andric   const RuntimePointerChecking *RtPtrChecking = LAI.getRuntimePointerChecking();
1773ca95b02SDimitry Andric   LLVMContext &Context = VersionedLoop->getHeader()->getContext();
1783ca95b02SDimitry Andric 
1793ca95b02SDimitry Andric   // First allocate an aliasing scope for each pointer checking group.
1803ca95b02SDimitry Andric   //
1813ca95b02SDimitry Andric   // While traversing through the checking groups in the loop, also create a
1823ca95b02SDimitry Andric   // reverse map from pointers to the pointer checking group they were assigned
1833ca95b02SDimitry Andric   // to.
1843ca95b02SDimitry Andric   MDBuilder MDB(Context);
1853ca95b02SDimitry Andric   MDNode *Domain = MDB.createAnonymousAliasScopeDomain("LVerDomain");
1863ca95b02SDimitry Andric 
1873ca95b02SDimitry Andric   for (const auto &Group : RtPtrChecking->CheckingGroups) {
1883ca95b02SDimitry Andric     GroupToScope[&Group] = MDB.createAnonymousAliasScope(Domain);
1893ca95b02SDimitry Andric 
1903ca95b02SDimitry Andric     for (unsigned PtrIdx : Group.Members)
1913ca95b02SDimitry Andric       PtrToGroup[RtPtrChecking->getPointerInfo(PtrIdx).PointerValue] = &Group;
1923ca95b02SDimitry Andric   }
1933ca95b02SDimitry Andric 
1943ca95b02SDimitry Andric   // Go through the checks and for each pointer group, collect the scopes for
1953ca95b02SDimitry Andric   // each non-aliasing pointer group.
1963ca95b02SDimitry Andric   DenseMap<const RuntimePointerChecking::CheckingPtrGroup *,
1973ca95b02SDimitry Andric            SmallVector<Metadata *, 4>>
1983ca95b02SDimitry Andric       GroupToNonAliasingScopes;
1993ca95b02SDimitry Andric 
2003ca95b02SDimitry Andric   for (const auto &Check : AliasChecks)
2013ca95b02SDimitry Andric     GroupToNonAliasingScopes[Check.first].push_back(GroupToScope[Check.second]);
2023ca95b02SDimitry Andric 
2033ca95b02SDimitry Andric   // Finally, transform the above to actually map to scope list which is what
2043ca95b02SDimitry Andric   // the metadata uses.
2053ca95b02SDimitry Andric 
2063ca95b02SDimitry Andric   for (auto Pair : GroupToNonAliasingScopes)
2073ca95b02SDimitry Andric     GroupToNonAliasingScopeList[Pair.first] = MDNode::get(Context, Pair.second);
2083ca95b02SDimitry Andric }
2093ca95b02SDimitry Andric 
annotateLoopWithNoAlias()2103ca95b02SDimitry Andric void LoopVersioning::annotateLoopWithNoAlias() {
2113ca95b02SDimitry Andric   if (!AnnotateNoAlias)
2123ca95b02SDimitry Andric     return;
2133ca95b02SDimitry Andric 
2143ca95b02SDimitry Andric   // First prepare the maps.
2153ca95b02SDimitry Andric   prepareNoAliasMetadata();
2163ca95b02SDimitry Andric 
2173ca95b02SDimitry Andric   // Add the scope and no-alias metadata to the instructions.
2183ca95b02SDimitry Andric   for (Instruction *I : LAI.getDepChecker().getMemoryInstructions()) {
2193ca95b02SDimitry Andric     annotateInstWithNoAlias(I);
2203ca95b02SDimitry Andric   }
2213ca95b02SDimitry Andric }
2223ca95b02SDimitry Andric 
annotateInstWithNoAlias(Instruction * VersionedInst,const Instruction * OrigInst)2233ca95b02SDimitry Andric void LoopVersioning::annotateInstWithNoAlias(Instruction *VersionedInst,
2243ca95b02SDimitry Andric                                              const Instruction *OrigInst) {
2253ca95b02SDimitry Andric   if (!AnnotateNoAlias)
2263ca95b02SDimitry Andric     return;
2273ca95b02SDimitry Andric 
2283ca95b02SDimitry Andric   LLVMContext &Context = VersionedLoop->getHeader()->getContext();
2293ca95b02SDimitry Andric   const Value *Ptr = isa<LoadInst>(OrigInst)
2303ca95b02SDimitry Andric                          ? cast<LoadInst>(OrigInst)->getPointerOperand()
2313ca95b02SDimitry Andric                          : cast<StoreInst>(OrigInst)->getPointerOperand();
2323ca95b02SDimitry Andric 
2333ca95b02SDimitry Andric   // Find the group for the pointer and then add the scope metadata.
2343ca95b02SDimitry Andric   auto Group = PtrToGroup.find(Ptr);
2353ca95b02SDimitry Andric   if (Group != PtrToGroup.end()) {
2363ca95b02SDimitry Andric     VersionedInst->setMetadata(
2373ca95b02SDimitry Andric         LLVMContext::MD_alias_scope,
2383ca95b02SDimitry Andric         MDNode::concatenate(
2393ca95b02SDimitry Andric             VersionedInst->getMetadata(LLVMContext::MD_alias_scope),
2403ca95b02SDimitry Andric             MDNode::get(Context, GroupToScope[Group->second])));
2413ca95b02SDimitry Andric 
2423ca95b02SDimitry Andric     // Add the no-alias metadata.
2433ca95b02SDimitry Andric     auto NonAliasingScopeList = GroupToNonAliasingScopeList.find(Group->second);
2443ca95b02SDimitry Andric     if (NonAliasingScopeList != GroupToNonAliasingScopeList.end())
2453ca95b02SDimitry Andric       VersionedInst->setMetadata(
2463ca95b02SDimitry Andric           LLVMContext::MD_noalias,
2473ca95b02SDimitry Andric           MDNode::concatenate(
2483ca95b02SDimitry Andric               VersionedInst->getMetadata(LLVMContext::MD_noalias),
2493ca95b02SDimitry Andric               NonAliasingScopeList->second));
2503ca95b02SDimitry Andric   }
2513ca95b02SDimitry Andric }
2523ca95b02SDimitry Andric 
2533ca95b02SDimitry Andric namespace {
254*4ba319b5SDimitry Andric /// Also expose this is a pass.  Currently this is only used for
2553ca95b02SDimitry Andric /// unit-testing.  It adds all memchecks necessary to remove all may-aliasing
2563ca95b02SDimitry Andric /// array accesses from the loop.
2573ca95b02SDimitry Andric class LoopVersioningPass : public FunctionPass {
2583ca95b02SDimitry Andric public:
LoopVersioningPass()2593ca95b02SDimitry Andric   LoopVersioningPass() : FunctionPass(ID) {
2603ca95b02SDimitry Andric     initializeLoopVersioningPassPass(*PassRegistry::getPassRegistry());
2613ca95b02SDimitry Andric   }
2623ca95b02SDimitry Andric 
runOnFunction(Function & F)2633ca95b02SDimitry Andric   bool runOnFunction(Function &F) override {
2643ca95b02SDimitry Andric     auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
2653ca95b02SDimitry Andric     auto *LAA = &getAnalysis<LoopAccessLegacyAnalysis>();
2663ca95b02SDimitry Andric     auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
2673ca95b02SDimitry Andric     auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
2683ca95b02SDimitry Andric 
2693ca95b02SDimitry Andric     // Build up a worklist of inner-loops to version. This is necessary as the
2703ca95b02SDimitry Andric     // act of versioning a loop creates new loops and can invalidate iterators
2713ca95b02SDimitry Andric     // across the loops.
2723ca95b02SDimitry Andric     SmallVector<Loop *, 8> Worklist;
2733ca95b02SDimitry Andric 
2743ca95b02SDimitry Andric     for (Loop *TopLevelLoop : *LI)
2753ca95b02SDimitry Andric       for (Loop *L : depth_first(TopLevelLoop))
2763ca95b02SDimitry Andric         // We only handle inner-most loops.
2773ca95b02SDimitry Andric         if (L->empty())
2783ca95b02SDimitry Andric           Worklist.push_back(L);
2793ca95b02SDimitry Andric 
2803ca95b02SDimitry Andric     // Now walk the identified inner loops.
2813ca95b02SDimitry Andric     bool Changed = false;
2823ca95b02SDimitry Andric     for (Loop *L : Worklist) {
2833ca95b02SDimitry Andric       const LoopAccessInfo &LAI = LAA->getInfo(L);
284d88c1a5aSDimitry Andric       if (L->isLoopSimplifyForm() && (LAI.getNumRuntimePointerChecks() ||
285d88c1a5aSDimitry Andric           !LAI.getPSE().getUnionPredicate().isAlwaysTrue())) {
2863ca95b02SDimitry Andric         LoopVersioning LVer(LAI, L, LI, DT, SE);
2873ca95b02SDimitry Andric         LVer.versionLoop();
2883ca95b02SDimitry Andric         LVer.annotateLoopWithNoAlias();
2893ca95b02SDimitry Andric         Changed = true;
2903ca95b02SDimitry Andric       }
2913ca95b02SDimitry Andric     }
2923ca95b02SDimitry Andric 
2933ca95b02SDimitry Andric     return Changed;
2943ca95b02SDimitry Andric   }
2953ca95b02SDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const2963ca95b02SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override {
2973ca95b02SDimitry Andric     AU.addRequired<LoopInfoWrapperPass>();
2983ca95b02SDimitry Andric     AU.addPreserved<LoopInfoWrapperPass>();
2993ca95b02SDimitry Andric     AU.addRequired<LoopAccessLegacyAnalysis>();
3003ca95b02SDimitry Andric     AU.addRequired<DominatorTreeWrapperPass>();
3013ca95b02SDimitry Andric     AU.addPreserved<DominatorTreeWrapperPass>();
3023ca95b02SDimitry Andric     AU.addRequired<ScalarEvolutionWrapperPass>();
3033ca95b02SDimitry Andric   }
3043ca95b02SDimitry Andric 
3053ca95b02SDimitry Andric   static char ID;
3063ca95b02SDimitry Andric };
3073ca95b02SDimitry Andric }
3083ca95b02SDimitry Andric 
3093ca95b02SDimitry Andric #define LVER_OPTION "loop-versioning"
3103ca95b02SDimitry Andric #define DEBUG_TYPE LVER_OPTION
3113ca95b02SDimitry Andric 
3123ca95b02SDimitry Andric char LoopVersioningPass::ID;
3133ca95b02SDimitry Andric static const char LVer_name[] = "Loop Versioning";
3143ca95b02SDimitry Andric 
3153ca95b02SDimitry Andric INITIALIZE_PASS_BEGIN(LoopVersioningPass, LVER_OPTION, LVer_name, false, false)
3163ca95b02SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
3173ca95b02SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LoopAccessLegacyAnalysis)
3183ca95b02SDimitry Andric INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
3193ca95b02SDimitry Andric INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
3203ca95b02SDimitry Andric INITIALIZE_PASS_END(LoopVersioningPass, LVER_OPTION, LVer_name, false, false)
3213ca95b02SDimitry Andric 
3223ca95b02SDimitry Andric namespace llvm {
createLoopVersioningPass()3233ca95b02SDimitry Andric FunctionPass *createLoopVersioningPass() {
3243ca95b02SDimitry Andric   return new LoopVersioningPass();
325875ed548SDimitry Andric }
326875ed548SDimitry Andric }
327