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