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" 165ffd83dbSDimitry Andric #include "llvm/ADT/ArrayRef.h" 17349cc55cSDimitry Andric #include "llvm/Analysis/AliasAnalysis.h" 1804eeddc0SDimitry Andric #include "llvm/Analysis/InstSimplifyFolder.h" 190b57cec5SDimitry Andric #include "llvm/Analysis/LoopAccessAnalysis.h" 200b57cec5SDimitry Andric #include "llvm/Analysis/LoopInfo.h" 21e8d8bef9SDimitry Andric #include "llvm/Analysis/ScalarEvolution.h" 22e8d8bef9SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h" 230b57cec5SDimitry Andric #include "llvm/IR/Dominators.h" 240b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h" 25e8d8bef9SDimitry Andric #include "llvm/IR/PassManager.h" 26480093f4SDimitry Andric #include "llvm/Support/CommandLine.h" 270b57cec5SDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h" 280b57cec5SDimitry Andric #include "llvm/Transforms/Utils/Cloning.h" 295ffd83dbSDimitry Andric #include "llvm/Transforms/Utils/ScalarEvolutionExpander.h" 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric using namespace llvm; 320b57cec5SDimitry Andric 3306c3fb27SDimitry Andric #define DEBUG_TYPE "loop-versioning" 3406c3fb27SDimitry Andric 350b57cec5SDimitry Andric static cl::opt<bool> 360b57cec5SDimitry Andric AnnotateNoAlias("loop-version-annotate-no-alias", cl::init(true), 370b57cec5SDimitry Andric cl::Hidden, 380b57cec5SDimitry Andric cl::desc("Add no-alias annotation for instructions that " 390b57cec5SDimitry Andric "are disambiguated by memchecks")); 400b57cec5SDimitry Andric 41e8d8bef9SDimitry Andric LoopVersioning::LoopVersioning(const LoopAccessInfo &LAI, 42e8d8bef9SDimitry Andric ArrayRef<RuntimePointerCheck> Checks, Loop *L, 43e8d8bef9SDimitry Andric LoopInfo *LI, DominatorTree *DT, 44e8d8bef9SDimitry Andric ScalarEvolution *SE) 4581ad6265SDimitry Andric : VersionedLoop(L), AliasChecks(Checks.begin(), Checks.end()), 4681ad6265SDimitry Andric Preds(LAI.getPSE().getPredicate()), LAI(LAI), LI(LI), DT(DT), 470b57cec5SDimitry Andric SE(SE) { 480b57cec5SDimitry Andric } 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric void LoopVersioning::versionLoop( 510b57cec5SDimitry Andric const SmallVectorImpl<Instruction *> &DefsUsedOutside) { 52fe6060f1SDimitry Andric assert(VersionedLoop->getUniqueExitBlock() && "No single exit block"); 53e8d8bef9SDimitry Andric assert(VersionedLoop->isLoopSimplifyForm() && 54e8d8bef9SDimitry Andric "Loop is not in loop-simplify form"); 55e8d8bef9SDimitry Andric 56349cc55cSDimitry Andric Value *MemRuntimeCheck; 570b57cec5SDimitry Andric Value *SCEVRuntimeCheck; 580b57cec5SDimitry Andric Value *RuntimeCheck = nullptr; 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric // Add the memcheck in the original preheader (this is empty initially). 610b57cec5SDimitry Andric BasicBlock *RuntimeCheckBB = VersionedLoop->getLoopPreheader(); 625ffd83dbSDimitry Andric const auto &RtPtrChecking = *LAI.getRuntimePointerChecking(); 63fe6060f1SDimitry Andric 64fe6060f1SDimitry Andric SCEVExpander Exp2(*RtPtrChecking.getSE(), 65*0fca6ea1SDimitry Andric VersionedLoop->getHeader()->getDataLayout(), 66fe6060f1SDimitry Andric "induction"); 67349cc55cSDimitry Andric MemRuntimeCheck = addRuntimeChecks(RuntimeCheckBB->getTerminator(), 68349cc55cSDimitry Andric VersionedLoop, AliasChecks, Exp2); 690b57cec5SDimitry Andric 70*0fca6ea1SDimitry Andric SCEVExpander Exp(*SE, RuntimeCheckBB->getDataLayout(), 710b57cec5SDimitry Andric "scev.check"); 720b57cec5SDimitry Andric SCEVRuntimeCheck = 73e8d8bef9SDimitry Andric Exp.expandCodeForPredicate(&Preds, RuntimeCheckBB->getTerminator()); 740b57cec5SDimitry Andric 7504eeddc0SDimitry Andric IRBuilder<InstSimplifyFolder> Builder( 7604eeddc0SDimitry Andric RuntimeCheckBB->getContext(), 77*0fca6ea1SDimitry Andric InstSimplifyFolder(RuntimeCheckBB->getDataLayout())); 780b57cec5SDimitry Andric if (MemRuntimeCheck && SCEVRuntimeCheck) { 7904eeddc0SDimitry Andric Builder.SetInsertPoint(RuntimeCheckBB->getTerminator()); 8004eeddc0SDimitry Andric RuntimeCheck = 8104eeddc0SDimitry Andric Builder.CreateOr(MemRuntimeCheck, SCEVRuntimeCheck, "lver.safe"); 820b57cec5SDimitry Andric } else 830b57cec5SDimitry Andric RuntimeCheck = MemRuntimeCheck ? MemRuntimeCheck : SCEVRuntimeCheck; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric assert(RuntimeCheck && "called even though we don't need " 860b57cec5SDimitry Andric "any runtime checks"); 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric // Rename the block to make the IR more readable. 890b57cec5SDimitry Andric RuntimeCheckBB->setName(VersionedLoop->getHeader()->getName() + 900b57cec5SDimitry Andric ".lver.check"); 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric // Create empty preheader for the loop (and after cloning for the 930b57cec5SDimitry Andric // non-versioned loop). 940b57cec5SDimitry Andric BasicBlock *PH = 958bcb0991SDimitry Andric SplitBlock(RuntimeCheckBB, RuntimeCheckBB->getTerminator(), DT, LI, 968bcb0991SDimitry Andric nullptr, VersionedLoop->getHeader()->getName() + ".ph"); 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric // Clone the loop including the preheader. 990b57cec5SDimitry Andric // 1000b57cec5SDimitry Andric // FIXME: This does not currently preserve SimplifyLoop because the exit 1010b57cec5SDimitry Andric // block is a join between the two loops. 1020b57cec5SDimitry Andric SmallVector<BasicBlock *, 8> NonVersionedLoopBlocks; 1030b57cec5SDimitry Andric NonVersionedLoop = 1040b57cec5SDimitry Andric cloneLoopWithPreheader(PH, RuntimeCheckBB, VersionedLoop, VMap, 1050b57cec5SDimitry Andric ".lver.orig", LI, DT, NonVersionedLoopBlocks); 1060b57cec5SDimitry Andric remapInstructionsInBlocks(NonVersionedLoopBlocks, VMap); 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric // Insert the conditional branch based on the result of the memchecks. 1090b57cec5SDimitry Andric Instruction *OrigTerm = RuntimeCheckBB->getTerminator(); 11004eeddc0SDimitry Andric Builder.SetInsertPoint(OrigTerm); 11104eeddc0SDimitry Andric Builder.CreateCondBr(RuntimeCheck, NonVersionedLoop->getLoopPreheader(), 11204eeddc0SDimitry Andric VersionedLoop->getLoopPreheader()); 1130b57cec5SDimitry Andric OrigTerm->eraseFromParent(); 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric // The loops merge in the original exit block. This is now dominated by the 1160b57cec5SDimitry Andric // memchecking block. 1170b57cec5SDimitry Andric DT->changeImmediateDominator(VersionedLoop->getExitBlock(), RuntimeCheckBB); 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric // Adds the necessary PHI nodes for the versioned loops based on the 1200b57cec5SDimitry Andric // loop-defined values used outside of the loop. 1210b57cec5SDimitry Andric addPHINodes(DefsUsedOutside); 122e8d8bef9SDimitry Andric formDedicatedExitBlocks(NonVersionedLoop, DT, LI, nullptr, true); 123e8d8bef9SDimitry Andric formDedicatedExitBlocks(VersionedLoop, DT, LI, nullptr, true); 124e8d8bef9SDimitry Andric assert(NonVersionedLoop->isLoopSimplifyForm() && 125e8d8bef9SDimitry Andric VersionedLoop->isLoopSimplifyForm() && 126e8d8bef9SDimitry Andric "The versioned loops should be in simplify form."); 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric void LoopVersioning::addPHINodes( 1300b57cec5SDimitry Andric const SmallVectorImpl<Instruction *> &DefsUsedOutside) { 1310b57cec5SDimitry Andric BasicBlock *PHIBlock = VersionedLoop->getExitBlock(); 1320b57cec5SDimitry Andric assert(PHIBlock && "No single successor to loop exit block"); 1330b57cec5SDimitry Andric PHINode *PN; 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric // First add a single-operand PHI for each DefsUsedOutside if one does not 1360b57cec5SDimitry Andric // exists yet. 1370b57cec5SDimitry Andric for (auto *Inst : DefsUsedOutside) { 1380b57cec5SDimitry Andric // See if we have a single-operand PHI with the value defined by the 1390b57cec5SDimitry Andric // original loop. 1400b57cec5SDimitry Andric for (auto I = PHIBlock->begin(); (PN = dyn_cast<PHINode>(I)); ++I) { 1416246ae0bSDimitry Andric if (PN->getIncomingValue(0) == Inst) { 1426246ae0bSDimitry Andric SE->forgetValue(PN); 1430b57cec5SDimitry Andric break; 1440b57cec5SDimitry Andric } 1456246ae0bSDimitry Andric } 1460b57cec5SDimitry Andric // If not create it. 1470b57cec5SDimitry Andric if (!PN) { 1485f757f3fSDimitry Andric PN = PHINode::Create(Inst->getType(), 2, Inst->getName() + ".lver"); 1495f757f3fSDimitry Andric PN->insertBefore(PHIBlock->begin()); 1500b57cec5SDimitry Andric SmallVector<User*, 8> UsersToUpdate; 1510b57cec5SDimitry Andric for (User *U : Inst->users()) 1520b57cec5SDimitry Andric if (!VersionedLoop->contains(cast<Instruction>(U)->getParent())) 1530b57cec5SDimitry Andric UsersToUpdate.push_back(U); 1540b57cec5SDimitry Andric for (User *U : UsersToUpdate) 1550b57cec5SDimitry Andric U->replaceUsesOfWith(Inst, PN); 1560b57cec5SDimitry Andric PN->addIncoming(Inst, VersionedLoop->getExitingBlock()); 1570b57cec5SDimitry Andric } 1580b57cec5SDimitry Andric } 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric // Then for each PHI add the operand for the edge from the cloned loop. 1610b57cec5SDimitry Andric for (auto I = PHIBlock->begin(); (PN = dyn_cast<PHINode>(I)); ++I) { 1620b57cec5SDimitry Andric assert(PN->getNumOperands() == 1 && 1630b57cec5SDimitry Andric "Exit block should only have on predecessor"); 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric // If the definition was cloned used that otherwise use the same value. 1660b57cec5SDimitry Andric Value *ClonedValue = PN->getIncomingValue(0); 1670b57cec5SDimitry Andric auto Mapped = VMap.find(ClonedValue); 1680b57cec5SDimitry Andric if (Mapped != VMap.end()) 1690b57cec5SDimitry Andric ClonedValue = Mapped->second; 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric PN->addIncoming(ClonedValue, NonVersionedLoop->getExitingBlock()); 1720b57cec5SDimitry Andric } 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric void LoopVersioning::prepareNoAliasMetadata() { 1760b57cec5SDimitry Andric // We need to turn the no-alias relation between pointer checking groups into 1770b57cec5SDimitry Andric // no-aliasing annotations between instructions. 1780b57cec5SDimitry Andric // 1790b57cec5SDimitry Andric // We accomplish this by mapping each pointer checking group (a set of 1800b57cec5SDimitry Andric // pointers memchecked together) to an alias scope and then also mapping each 1810b57cec5SDimitry Andric // group to the list of scopes it can't alias. 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric const RuntimePointerChecking *RtPtrChecking = LAI.getRuntimePointerChecking(); 1840b57cec5SDimitry Andric LLVMContext &Context = VersionedLoop->getHeader()->getContext(); 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric // First allocate an aliasing scope for each pointer checking group. 1870b57cec5SDimitry Andric // 1880b57cec5SDimitry Andric // While traversing through the checking groups in the loop, also create a 1890b57cec5SDimitry Andric // reverse map from pointers to the pointer checking group they were assigned 1900b57cec5SDimitry Andric // to. 1910b57cec5SDimitry Andric MDBuilder MDB(Context); 1920b57cec5SDimitry Andric MDNode *Domain = MDB.createAnonymousAliasScopeDomain("LVerDomain"); 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric for (const auto &Group : RtPtrChecking->CheckingGroups) { 1950b57cec5SDimitry Andric GroupToScope[&Group] = MDB.createAnonymousAliasScope(Domain); 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric for (unsigned PtrIdx : Group.Members) 1980b57cec5SDimitry Andric PtrToGroup[RtPtrChecking->getPointerInfo(PtrIdx).PointerValue] = &Group; 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric // Go through the checks and for each pointer group, collect the scopes for 2020b57cec5SDimitry Andric // each non-aliasing pointer group. 2035ffd83dbSDimitry Andric DenseMap<const RuntimeCheckingPtrGroup *, SmallVector<Metadata *, 4>> 2040b57cec5SDimitry Andric GroupToNonAliasingScopes; 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric for (const auto &Check : AliasChecks) 2070b57cec5SDimitry Andric GroupToNonAliasingScopes[Check.first].push_back(GroupToScope[Check.second]); 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric // Finally, transform the above to actually map to scope list which is what 2100b57cec5SDimitry Andric // the metadata uses. 2110b57cec5SDimitry Andric 21206c3fb27SDimitry Andric for (const auto &Pair : GroupToNonAliasingScopes) 2130b57cec5SDimitry Andric GroupToNonAliasingScopeList[Pair.first] = MDNode::get(Context, Pair.second); 2140b57cec5SDimitry Andric } 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric void LoopVersioning::annotateLoopWithNoAlias() { 2170b57cec5SDimitry Andric if (!AnnotateNoAlias) 2180b57cec5SDimitry Andric return; 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric // First prepare the maps. 2210b57cec5SDimitry Andric prepareNoAliasMetadata(); 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric // Add the scope and no-alias metadata to the instructions. 2240b57cec5SDimitry Andric for (Instruction *I : LAI.getDepChecker().getMemoryInstructions()) { 2250b57cec5SDimitry Andric annotateInstWithNoAlias(I); 2260b57cec5SDimitry Andric } 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric void LoopVersioning::annotateInstWithNoAlias(Instruction *VersionedInst, 2300b57cec5SDimitry Andric const Instruction *OrigInst) { 2310b57cec5SDimitry Andric if (!AnnotateNoAlias) 2320b57cec5SDimitry Andric return; 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric LLVMContext &Context = VersionedLoop->getHeader()->getContext(); 2350b57cec5SDimitry Andric const Value *Ptr = isa<LoadInst>(OrigInst) 2360b57cec5SDimitry Andric ? cast<LoadInst>(OrigInst)->getPointerOperand() 2370b57cec5SDimitry Andric : cast<StoreInst>(OrigInst)->getPointerOperand(); 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric // Find the group for the pointer and then add the scope metadata. 2400b57cec5SDimitry Andric auto Group = PtrToGroup.find(Ptr); 2410b57cec5SDimitry Andric if (Group != PtrToGroup.end()) { 2420b57cec5SDimitry Andric VersionedInst->setMetadata( 2430b57cec5SDimitry Andric LLVMContext::MD_alias_scope, 2440b57cec5SDimitry Andric MDNode::concatenate( 2450b57cec5SDimitry Andric VersionedInst->getMetadata(LLVMContext::MD_alias_scope), 2460b57cec5SDimitry Andric MDNode::get(Context, GroupToScope[Group->second]))); 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric // Add the no-alias metadata. 2490b57cec5SDimitry Andric auto NonAliasingScopeList = GroupToNonAliasingScopeList.find(Group->second); 2500b57cec5SDimitry Andric if (NonAliasingScopeList != GroupToNonAliasingScopeList.end()) 2510b57cec5SDimitry Andric VersionedInst->setMetadata( 2520b57cec5SDimitry Andric LLVMContext::MD_noalias, 2530b57cec5SDimitry Andric MDNode::concatenate( 2540b57cec5SDimitry Andric VersionedInst->getMetadata(LLVMContext::MD_noalias), 2550b57cec5SDimitry Andric NonAliasingScopeList->second)); 2560b57cec5SDimitry Andric } 2570b57cec5SDimitry Andric } 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric namespace { 260bdd1243dSDimitry Andric bool runImpl(LoopInfo *LI, LoopAccessInfoManager &LAIs, DominatorTree *DT, 261bdd1243dSDimitry Andric ScalarEvolution *SE) { 2620b57cec5SDimitry Andric // Build up a worklist of inner-loops to version. This is necessary as the 2630b57cec5SDimitry Andric // act of versioning a loop creates new loops and can invalidate iterators 2640b57cec5SDimitry Andric // across the loops. 2650b57cec5SDimitry Andric SmallVector<Loop *, 8> Worklist; 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric for (Loop *TopLevelLoop : *LI) 2680b57cec5SDimitry Andric for (Loop *L : depth_first(TopLevelLoop)) 2690b57cec5SDimitry Andric // We only handle inner-most loops. 270e8d8bef9SDimitry Andric if (L->isInnermost()) 2710b57cec5SDimitry Andric Worklist.push_back(L); 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andric // Now walk the identified inner loops. 2740b57cec5SDimitry Andric bool Changed = false; 2750b57cec5SDimitry Andric for (Loop *L : Worklist) { 276e8d8bef9SDimitry Andric if (!L->isLoopSimplifyForm() || !L->isRotatedForm() || 277e8d8bef9SDimitry Andric !L->getExitingBlock()) 278e8d8bef9SDimitry Andric continue; 279bdd1243dSDimitry Andric const LoopAccessInfo &LAI = LAIs.getInfo(*L); 280e8d8bef9SDimitry Andric if (!LAI.hasConvergentOp() && 2810b57cec5SDimitry Andric (LAI.getNumRuntimePointerChecks() || 28281ad6265SDimitry Andric !LAI.getPSE().getPredicate().isAlwaysTrue())) { 283e8d8bef9SDimitry Andric LoopVersioning LVer(LAI, LAI.getRuntimePointerChecking()->getChecks(), L, 284e8d8bef9SDimitry Andric LI, DT, SE); 2850b57cec5SDimitry Andric LVer.versionLoop(); 2860b57cec5SDimitry Andric LVer.annotateLoopWithNoAlias(); 2870b57cec5SDimitry Andric Changed = true; 288bdd1243dSDimitry Andric LAIs.clear(); 2890b57cec5SDimitry Andric } 2900b57cec5SDimitry Andric } 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric return Changed; 2930b57cec5SDimitry Andric } 2940b57cec5SDimitry Andric } 295e8d8bef9SDimitry Andric 296e8d8bef9SDimitry Andric PreservedAnalyses LoopVersioningPass::run(Function &F, 297e8d8bef9SDimitry Andric FunctionAnalysisManager &AM) { 298e8d8bef9SDimitry Andric auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F); 299e8d8bef9SDimitry Andric auto &LI = AM.getResult<LoopAnalysis>(F); 300bdd1243dSDimitry Andric LoopAccessInfoManager &LAIs = AM.getResult<LoopAccessAnalysis>(F); 301e8d8bef9SDimitry Andric auto &DT = AM.getResult<DominatorTreeAnalysis>(F); 302e8d8bef9SDimitry Andric 303bdd1243dSDimitry Andric if (runImpl(&LI, LAIs, &DT, &SE)) 304e8d8bef9SDimitry Andric return PreservedAnalyses::none(); 305e8d8bef9SDimitry Andric return PreservedAnalyses::all(); 3060b57cec5SDimitry Andric } 307