10b57cec5SDimitry Andric //===- LoopVersioning.cpp - Utility to version a loop ---------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines a utility class to perform loop versioning. The versioned 100b57cec5SDimitry Andric // loop speculates that otherwise may-aliasing memory accesses don't overlap and 110b57cec5SDimitry Andric // emits checks to prove this. 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #include "llvm/Transforms/Utils/LoopVersioning.h" 160b57cec5SDimitry Andric #include "llvm/Analysis/LoopAccessAnalysis.h" 170b57cec5SDimitry Andric #include "llvm/Analysis/LoopInfo.h" 180b57cec5SDimitry Andric #include "llvm/Analysis/ScalarEvolutionExpander.h" 190b57cec5SDimitry Andric #include "llvm/IR/Dominators.h" 200b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h" 21*480093f4SDimitry Andric #include "llvm/InitializePasses.h" 22*480093f4SDimitry Andric #include "llvm/Support/CommandLine.h" 230b57cec5SDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h" 240b57cec5SDimitry Andric #include "llvm/Transforms/Utils/Cloning.h" 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric using namespace llvm; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric static cl::opt<bool> 290b57cec5SDimitry Andric AnnotateNoAlias("loop-version-annotate-no-alias", cl::init(true), 300b57cec5SDimitry Andric cl::Hidden, 310b57cec5SDimitry Andric cl::desc("Add no-alias annotation for instructions that " 320b57cec5SDimitry Andric "are disambiguated by memchecks")); 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric LoopVersioning::LoopVersioning(const LoopAccessInfo &LAI, Loop *L, LoopInfo *LI, 350b57cec5SDimitry Andric DominatorTree *DT, ScalarEvolution *SE, 360b57cec5SDimitry Andric bool UseLAIChecks) 370b57cec5SDimitry Andric : VersionedLoop(L), NonVersionedLoop(nullptr), LAI(LAI), LI(LI), DT(DT), 380b57cec5SDimitry Andric SE(SE) { 390b57cec5SDimitry Andric assert(L->getExitBlock() && "No single exit block"); 400b57cec5SDimitry Andric assert(L->isLoopSimplifyForm() && "Loop is not in loop-simplify form"); 410b57cec5SDimitry Andric if (UseLAIChecks) { 420b57cec5SDimitry Andric setAliasChecks(LAI.getRuntimePointerChecking()->getChecks()); 430b57cec5SDimitry Andric setSCEVChecks(LAI.getPSE().getUnionPredicate()); 440b57cec5SDimitry Andric } 450b57cec5SDimitry Andric } 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric void LoopVersioning::setAliasChecks( 480b57cec5SDimitry Andric SmallVector<RuntimePointerChecking::PointerCheck, 4> Checks) { 490b57cec5SDimitry Andric AliasChecks = std::move(Checks); 500b57cec5SDimitry Andric } 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric void LoopVersioning::setSCEVChecks(SCEVUnionPredicate Check) { 530b57cec5SDimitry Andric Preds = std::move(Check); 540b57cec5SDimitry Andric } 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric void LoopVersioning::versionLoop( 570b57cec5SDimitry Andric const SmallVectorImpl<Instruction *> &DefsUsedOutside) { 580b57cec5SDimitry Andric Instruction *FirstCheckInst; 590b57cec5SDimitry Andric Instruction *MemRuntimeCheck; 600b57cec5SDimitry Andric Value *SCEVRuntimeCheck; 610b57cec5SDimitry Andric Value *RuntimeCheck = nullptr; 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric // Add the memcheck in the original preheader (this is empty initially). 640b57cec5SDimitry Andric BasicBlock *RuntimeCheckBB = VersionedLoop->getLoopPreheader(); 650b57cec5SDimitry Andric std::tie(FirstCheckInst, MemRuntimeCheck) = 660b57cec5SDimitry Andric LAI.addRuntimeChecks(RuntimeCheckBB->getTerminator(), AliasChecks); 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric const SCEVUnionPredicate &Pred = LAI.getPSE().getUnionPredicate(); 690b57cec5SDimitry Andric SCEVExpander Exp(*SE, RuntimeCheckBB->getModule()->getDataLayout(), 700b57cec5SDimitry Andric "scev.check"); 710b57cec5SDimitry Andric SCEVRuntimeCheck = 720b57cec5SDimitry Andric Exp.expandCodeForPredicate(&Pred, RuntimeCheckBB->getTerminator()); 730b57cec5SDimitry Andric auto *CI = dyn_cast<ConstantInt>(SCEVRuntimeCheck); 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric // Discard the SCEV runtime check if it is always true. 760b57cec5SDimitry Andric if (CI && CI->isZero()) 770b57cec5SDimitry Andric SCEVRuntimeCheck = nullptr; 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric if (MemRuntimeCheck && SCEVRuntimeCheck) { 800b57cec5SDimitry Andric RuntimeCheck = BinaryOperator::Create(Instruction::Or, MemRuntimeCheck, 810b57cec5SDimitry Andric SCEVRuntimeCheck, "lver.safe"); 820b57cec5SDimitry Andric if (auto *I = dyn_cast<Instruction>(RuntimeCheck)) 830b57cec5SDimitry Andric I->insertBefore(RuntimeCheckBB->getTerminator()); 840b57cec5SDimitry Andric } else 850b57cec5SDimitry Andric RuntimeCheck = MemRuntimeCheck ? MemRuntimeCheck : SCEVRuntimeCheck; 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric assert(RuntimeCheck && "called even though we don't need " 880b57cec5SDimitry Andric "any runtime checks"); 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric // Rename the block to make the IR more readable. 910b57cec5SDimitry Andric RuntimeCheckBB->setName(VersionedLoop->getHeader()->getName() + 920b57cec5SDimitry Andric ".lver.check"); 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric // Create empty preheader for the loop (and after cloning for the 950b57cec5SDimitry Andric // non-versioned loop). 960b57cec5SDimitry Andric BasicBlock *PH = 978bcb0991SDimitry Andric SplitBlock(RuntimeCheckBB, RuntimeCheckBB->getTerminator(), DT, LI, 988bcb0991SDimitry Andric nullptr, VersionedLoop->getHeader()->getName() + ".ph"); 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric // Clone the loop including the preheader. 1010b57cec5SDimitry Andric // 1020b57cec5SDimitry Andric // FIXME: This does not currently preserve SimplifyLoop because the exit 1030b57cec5SDimitry Andric // block is a join between the two loops. 1040b57cec5SDimitry Andric SmallVector<BasicBlock *, 8> NonVersionedLoopBlocks; 1050b57cec5SDimitry Andric NonVersionedLoop = 1060b57cec5SDimitry Andric cloneLoopWithPreheader(PH, RuntimeCheckBB, VersionedLoop, VMap, 1070b57cec5SDimitry Andric ".lver.orig", LI, DT, NonVersionedLoopBlocks); 1080b57cec5SDimitry Andric remapInstructionsInBlocks(NonVersionedLoopBlocks, VMap); 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric // Insert the conditional branch based on the result of the memchecks. 1110b57cec5SDimitry Andric Instruction *OrigTerm = RuntimeCheckBB->getTerminator(); 1120b57cec5SDimitry Andric BranchInst::Create(NonVersionedLoop->getLoopPreheader(), 1130b57cec5SDimitry Andric VersionedLoop->getLoopPreheader(), RuntimeCheck, OrigTerm); 1140b57cec5SDimitry Andric OrigTerm->eraseFromParent(); 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric // The loops merge in the original exit block. This is now dominated by the 1170b57cec5SDimitry Andric // memchecking block. 1180b57cec5SDimitry Andric DT->changeImmediateDominator(VersionedLoop->getExitBlock(), RuntimeCheckBB); 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric // Adds the necessary PHI nodes for the versioned loops based on the 1210b57cec5SDimitry Andric // loop-defined values used outside of the loop. 1220b57cec5SDimitry Andric addPHINodes(DefsUsedOutside); 1230b57cec5SDimitry Andric } 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric void LoopVersioning::addPHINodes( 1260b57cec5SDimitry Andric const SmallVectorImpl<Instruction *> &DefsUsedOutside) { 1270b57cec5SDimitry Andric BasicBlock *PHIBlock = VersionedLoop->getExitBlock(); 1280b57cec5SDimitry Andric assert(PHIBlock && "No single successor to loop exit block"); 1290b57cec5SDimitry Andric PHINode *PN; 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric // First add a single-operand PHI for each DefsUsedOutside if one does not 1320b57cec5SDimitry Andric // exists yet. 1330b57cec5SDimitry Andric for (auto *Inst : DefsUsedOutside) { 1340b57cec5SDimitry Andric // See if we have a single-operand PHI with the value defined by the 1350b57cec5SDimitry Andric // original loop. 1360b57cec5SDimitry Andric for (auto I = PHIBlock->begin(); (PN = dyn_cast<PHINode>(I)); ++I) { 1370b57cec5SDimitry Andric if (PN->getIncomingValue(0) == Inst) 1380b57cec5SDimitry Andric break; 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric // If not create it. 1410b57cec5SDimitry Andric if (!PN) { 1420b57cec5SDimitry Andric PN = PHINode::Create(Inst->getType(), 2, Inst->getName() + ".lver", 1430b57cec5SDimitry Andric &PHIBlock->front()); 1440b57cec5SDimitry Andric SmallVector<User*, 8> UsersToUpdate; 1450b57cec5SDimitry Andric for (User *U : Inst->users()) 1460b57cec5SDimitry Andric if (!VersionedLoop->contains(cast<Instruction>(U)->getParent())) 1470b57cec5SDimitry Andric UsersToUpdate.push_back(U); 1480b57cec5SDimitry Andric for (User *U : UsersToUpdate) 1490b57cec5SDimitry Andric U->replaceUsesOfWith(Inst, PN); 1500b57cec5SDimitry Andric PN->addIncoming(Inst, VersionedLoop->getExitingBlock()); 1510b57cec5SDimitry Andric } 1520b57cec5SDimitry Andric } 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric // Then for each PHI add the operand for the edge from the cloned loop. 1550b57cec5SDimitry Andric for (auto I = PHIBlock->begin(); (PN = dyn_cast<PHINode>(I)); ++I) { 1560b57cec5SDimitry Andric assert(PN->getNumOperands() == 1 && 1570b57cec5SDimitry Andric "Exit block should only have on predecessor"); 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric // If the definition was cloned used that otherwise use the same value. 1600b57cec5SDimitry Andric Value *ClonedValue = PN->getIncomingValue(0); 1610b57cec5SDimitry Andric auto Mapped = VMap.find(ClonedValue); 1620b57cec5SDimitry Andric if (Mapped != VMap.end()) 1630b57cec5SDimitry Andric ClonedValue = Mapped->second; 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric PN->addIncoming(ClonedValue, NonVersionedLoop->getExitingBlock()); 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric } 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric void LoopVersioning::prepareNoAliasMetadata() { 1700b57cec5SDimitry Andric // We need to turn the no-alias relation between pointer checking groups into 1710b57cec5SDimitry Andric // no-aliasing annotations between instructions. 1720b57cec5SDimitry Andric // 1730b57cec5SDimitry Andric // We accomplish this by mapping each pointer checking group (a set of 1740b57cec5SDimitry Andric // pointers memchecked together) to an alias scope and then also mapping each 1750b57cec5SDimitry Andric // group to the list of scopes it can't alias. 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric const RuntimePointerChecking *RtPtrChecking = LAI.getRuntimePointerChecking(); 1780b57cec5SDimitry Andric LLVMContext &Context = VersionedLoop->getHeader()->getContext(); 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric // First allocate an aliasing scope for each pointer checking group. 1810b57cec5SDimitry Andric // 1820b57cec5SDimitry Andric // While traversing through the checking groups in the loop, also create a 1830b57cec5SDimitry Andric // reverse map from pointers to the pointer checking group they were assigned 1840b57cec5SDimitry Andric // to. 1850b57cec5SDimitry Andric MDBuilder MDB(Context); 1860b57cec5SDimitry Andric MDNode *Domain = MDB.createAnonymousAliasScopeDomain("LVerDomain"); 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric for (const auto &Group : RtPtrChecking->CheckingGroups) { 1890b57cec5SDimitry Andric GroupToScope[&Group] = MDB.createAnonymousAliasScope(Domain); 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric for (unsigned PtrIdx : Group.Members) 1920b57cec5SDimitry Andric PtrToGroup[RtPtrChecking->getPointerInfo(PtrIdx).PointerValue] = &Group; 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric // Go through the checks and for each pointer group, collect the scopes for 1960b57cec5SDimitry Andric // each non-aliasing pointer group. 1970b57cec5SDimitry Andric DenseMap<const RuntimePointerChecking::CheckingPtrGroup *, 1980b57cec5SDimitry Andric SmallVector<Metadata *, 4>> 1990b57cec5SDimitry Andric GroupToNonAliasingScopes; 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric for (const auto &Check : AliasChecks) 2020b57cec5SDimitry Andric GroupToNonAliasingScopes[Check.first].push_back(GroupToScope[Check.second]); 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric // Finally, transform the above to actually map to scope list which is what 2050b57cec5SDimitry Andric // the metadata uses. 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric for (auto Pair : GroupToNonAliasingScopes) 2080b57cec5SDimitry Andric GroupToNonAliasingScopeList[Pair.first] = MDNode::get(Context, Pair.second); 2090b57cec5SDimitry Andric } 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric void LoopVersioning::annotateLoopWithNoAlias() { 2120b57cec5SDimitry Andric if (!AnnotateNoAlias) 2130b57cec5SDimitry Andric return; 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric // First prepare the maps. 2160b57cec5SDimitry Andric prepareNoAliasMetadata(); 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric // Add the scope and no-alias metadata to the instructions. 2190b57cec5SDimitry Andric for (Instruction *I : LAI.getDepChecker().getMemoryInstructions()) { 2200b57cec5SDimitry Andric annotateInstWithNoAlias(I); 2210b57cec5SDimitry Andric } 2220b57cec5SDimitry Andric } 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric void LoopVersioning::annotateInstWithNoAlias(Instruction *VersionedInst, 2250b57cec5SDimitry Andric const Instruction *OrigInst) { 2260b57cec5SDimitry Andric if (!AnnotateNoAlias) 2270b57cec5SDimitry Andric return; 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric LLVMContext &Context = VersionedLoop->getHeader()->getContext(); 2300b57cec5SDimitry Andric const Value *Ptr = isa<LoadInst>(OrigInst) 2310b57cec5SDimitry Andric ? cast<LoadInst>(OrigInst)->getPointerOperand() 2320b57cec5SDimitry Andric : cast<StoreInst>(OrigInst)->getPointerOperand(); 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric // Find the group for the pointer and then add the scope metadata. 2350b57cec5SDimitry Andric auto Group = PtrToGroup.find(Ptr); 2360b57cec5SDimitry Andric if (Group != PtrToGroup.end()) { 2370b57cec5SDimitry Andric VersionedInst->setMetadata( 2380b57cec5SDimitry Andric LLVMContext::MD_alias_scope, 2390b57cec5SDimitry Andric MDNode::concatenate( 2400b57cec5SDimitry Andric VersionedInst->getMetadata(LLVMContext::MD_alias_scope), 2410b57cec5SDimitry Andric MDNode::get(Context, GroupToScope[Group->second]))); 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric // Add the no-alias metadata. 2440b57cec5SDimitry Andric auto NonAliasingScopeList = GroupToNonAliasingScopeList.find(Group->second); 2450b57cec5SDimitry Andric if (NonAliasingScopeList != GroupToNonAliasingScopeList.end()) 2460b57cec5SDimitry Andric VersionedInst->setMetadata( 2470b57cec5SDimitry Andric LLVMContext::MD_noalias, 2480b57cec5SDimitry Andric MDNode::concatenate( 2490b57cec5SDimitry Andric VersionedInst->getMetadata(LLVMContext::MD_noalias), 2500b57cec5SDimitry Andric NonAliasingScopeList->second)); 2510b57cec5SDimitry Andric } 2520b57cec5SDimitry Andric } 2530b57cec5SDimitry Andric 2540b57cec5SDimitry Andric namespace { 2550b57cec5SDimitry Andric /// Also expose this is a pass. Currently this is only used for 2560b57cec5SDimitry Andric /// unit-testing. It adds all memchecks necessary to remove all may-aliasing 2570b57cec5SDimitry Andric /// array accesses from the loop. 2580b57cec5SDimitry Andric class LoopVersioningPass : public FunctionPass { 2590b57cec5SDimitry Andric public: 2600b57cec5SDimitry Andric LoopVersioningPass() : FunctionPass(ID) { 2610b57cec5SDimitry Andric initializeLoopVersioningPassPass(*PassRegistry::getPassRegistry()); 2620b57cec5SDimitry Andric } 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric bool runOnFunction(Function &F) override { 2650b57cec5SDimitry Andric auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); 2660b57cec5SDimitry Andric auto *LAA = &getAnalysis<LoopAccessLegacyAnalysis>(); 2670b57cec5SDimitry Andric auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 2680b57cec5SDimitry Andric auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE(); 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric // Build up a worklist of inner-loops to version. This is necessary as the 2710b57cec5SDimitry Andric // act of versioning a loop creates new loops and can invalidate iterators 2720b57cec5SDimitry Andric // across the loops. 2730b57cec5SDimitry Andric SmallVector<Loop *, 8> Worklist; 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric for (Loop *TopLevelLoop : *LI) 2760b57cec5SDimitry Andric for (Loop *L : depth_first(TopLevelLoop)) 2770b57cec5SDimitry Andric // We only handle inner-most loops. 2780b57cec5SDimitry Andric if (L->empty()) 2790b57cec5SDimitry Andric Worklist.push_back(L); 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric // Now walk the identified inner loops. 2820b57cec5SDimitry Andric bool Changed = false; 2830b57cec5SDimitry Andric for (Loop *L : Worklist) { 2840b57cec5SDimitry Andric const LoopAccessInfo &LAI = LAA->getInfo(L); 2850b57cec5SDimitry Andric if (L->isLoopSimplifyForm() && !LAI.hasConvergentOp() && 2860b57cec5SDimitry Andric (LAI.getNumRuntimePointerChecks() || 2870b57cec5SDimitry Andric !LAI.getPSE().getUnionPredicate().isAlwaysTrue())) { 2880b57cec5SDimitry Andric LoopVersioning LVer(LAI, L, LI, DT, SE); 2890b57cec5SDimitry Andric LVer.versionLoop(); 2900b57cec5SDimitry Andric LVer.annotateLoopWithNoAlias(); 2910b57cec5SDimitry Andric Changed = true; 2920b57cec5SDimitry Andric } 2930b57cec5SDimitry Andric } 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric return Changed; 2960b57cec5SDimitry Andric } 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 2990b57cec5SDimitry Andric AU.addRequired<LoopInfoWrapperPass>(); 3000b57cec5SDimitry Andric AU.addPreserved<LoopInfoWrapperPass>(); 3010b57cec5SDimitry Andric AU.addRequired<LoopAccessLegacyAnalysis>(); 3020b57cec5SDimitry Andric AU.addRequired<DominatorTreeWrapperPass>(); 3030b57cec5SDimitry Andric AU.addPreserved<DominatorTreeWrapperPass>(); 3040b57cec5SDimitry Andric AU.addRequired<ScalarEvolutionWrapperPass>(); 3050b57cec5SDimitry Andric } 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric static char ID; 3080b57cec5SDimitry Andric }; 3090b57cec5SDimitry Andric } 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric #define LVER_OPTION "loop-versioning" 3120b57cec5SDimitry Andric #define DEBUG_TYPE LVER_OPTION 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric char LoopVersioningPass::ID; 3150b57cec5SDimitry Andric static const char LVer_name[] = "Loop Versioning"; 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(LoopVersioningPass, LVER_OPTION, LVer_name, false, false) 3180b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) 3190b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LoopAccessLegacyAnalysis) 3200b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 3210b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) 3220b57cec5SDimitry Andric INITIALIZE_PASS_END(LoopVersioningPass, LVER_OPTION, LVer_name, false, false) 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric namespace llvm { 3250b57cec5SDimitry Andric FunctionPass *createLoopVersioningPass() { 3260b57cec5SDimitry Andric return new LoopVersioningPass(); 3270b57cec5SDimitry Andric } 3280b57cec5SDimitry Andric } 329