10b57cec5SDimitry Andric //===- LoopVersioningLICM.cpp - LICM Loop Versioning ----------------------===// 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 // When alias analysis is uncertain about the aliasing between any two accesses, 100b57cec5SDimitry Andric // it will return MayAlias. This uncertainty from alias analysis restricts LICM 110b57cec5SDimitry Andric // from proceeding further. In cases where alias analysis is uncertain we might 120b57cec5SDimitry Andric // use loop versioning as an alternative. 130b57cec5SDimitry Andric // 140b57cec5SDimitry Andric // Loop Versioning will create a version of the loop with aggressive aliasing 150b57cec5SDimitry Andric // assumptions in addition to the original with conservative (default) aliasing 160b57cec5SDimitry Andric // assumptions. The version of the loop making aggressive aliasing assumptions 170b57cec5SDimitry Andric // will have all the memory accesses marked as no-alias. These two versions of 180b57cec5SDimitry Andric // loop will be preceded by a memory runtime check. This runtime check consists 190b57cec5SDimitry Andric // of bound checks for all unique memory accessed in loop, and it ensures the 200b57cec5SDimitry Andric // lack of memory aliasing. The result of the runtime check determines which of 210b57cec5SDimitry Andric // the loop versions is executed: If the runtime check detects any memory 220b57cec5SDimitry Andric // aliasing, then the original loop is executed. Otherwise, the version with 230b57cec5SDimitry Andric // aggressive aliasing assumptions is used. 240b57cec5SDimitry Andric // 250b57cec5SDimitry Andric // Following are the top level steps: 260b57cec5SDimitry Andric // 270b57cec5SDimitry Andric // a) Perform LoopVersioningLICM's feasibility check. 280b57cec5SDimitry Andric // b) If loop is a candidate for versioning then create a memory bound check, 290b57cec5SDimitry Andric // by considering all the memory accesses in loop body. 300b57cec5SDimitry Andric // c) Clone original loop and set all memory accesses as no-alias in new loop. 310b57cec5SDimitry Andric // d) Set original loop & versioned loop as a branch target of the runtime check 320b57cec5SDimitry Andric // result. 330b57cec5SDimitry Andric // 340b57cec5SDimitry Andric // It transforms loop as shown below: 350b57cec5SDimitry Andric // 360b57cec5SDimitry Andric // +----------------+ 370b57cec5SDimitry Andric // |Runtime Memcheck| 380b57cec5SDimitry Andric // +----------------+ 390b57cec5SDimitry Andric // | 400b57cec5SDimitry Andric // +----------+----------------+----------+ 410b57cec5SDimitry Andric // | | 420b57cec5SDimitry Andric // +---------+----------+ +-----------+----------+ 430b57cec5SDimitry Andric // |Orig Loop Preheader | |Cloned Loop Preheader | 440b57cec5SDimitry Andric // +--------------------+ +----------------------+ 450b57cec5SDimitry Andric // | | 460b57cec5SDimitry Andric // +--------------------+ +----------------------+ 470b57cec5SDimitry Andric // |Orig Loop Body | |Cloned Loop Body | 480b57cec5SDimitry Andric // +--------------------+ +----------------------+ 490b57cec5SDimitry Andric // | | 500b57cec5SDimitry Andric // +--------------------+ +----------------------+ 510b57cec5SDimitry Andric // |Orig Loop Exit Block| |Cloned Loop Exit Block| 520b57cec5SDimitry Andric // +--------------------+ +-----------+----------+ 530b57cec5SDimitry Andric // | | 540b57cec5SDimitry Andric // +----------+--------------+-----------+ 550b57cec5SDimitry Andric // | 560b57cec5SDimitry Andric // +-----+----+ 570b57cec5SDimitry Andric // |Join Block| 580b57cec5SDimitry Andric // +----------+ 590b57cec5SDimitry Andric // 600b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 610b57cec5SDimitry Andric 62e8d8bef9SDimitry Andric #include "llvm/Transforms/Scalar/LoopVersioningLICM.h" 630b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 640b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 650b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h" 660b57cec5SDimitry Andric #include "llvm/Analysis/AliasSetTracker.h" 670b57cec5SDimitry Andric #include "llvm/Analysis/GlobalsModRef.h" 680b57cec5SDimitry Andric #include "llvm/Analysis/LoopAccessAnalysis.h" 690b57cec5SDimitry Andric #include "llvm/Analysis/LoopInfo.h" 700b57cec5SDimitry Andric #include "llvm/Analysis/LoopPass.h" 710b57cec5SDimitry Andric #include "llvm/Analysis/OptimizationRemarkEmitter.h" 720b57cec5SDimitry Andric #include "llvm/Analysis/ScalarEvolution.h" 730b57cec5SDimitry Andric #include "llvm/IR/Dominators.h" 740b57cec5SDimitry Andric #include "llvm/IR/Instruction.h" 750b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 760b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h" 770b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h" 780b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 790b57cec5SDimitry Andric #include "llvm/IR/Value.h" 800b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 810b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 820b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 830b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 840b57cec5SDimitry Andric #include "llvm/Transforms/Utils.h" 850b57cec5SDimitry Andric #include "llvm/Transforms/Utils/LoopUtils.h" 860b57cec5SDimitry Andric #include "llvm/Transforms/Utils/LoopVersioning.h" 870b57cec5SDimitry Andric #include <cassert> 880b57cec5SDimitry Andric #include <memory> 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric using namespace llvm; 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric #define DEBUG_TYPE "loop-versioning-licm" 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric static const char *LICMVersioningMetaData = "llvm.loop.licm_versioning.disable"; 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric /// Threshold minimum allowed percentage for possible 970b57cec5SDimitry Andric /// invariant instructions in a loop. 980b57cec5SDimitry Andric static cl::opt<float> 990b57cec5SDimitry Andric LVInvarThreshold("licm-versioning-invariant-threshold", 1000b57cec5SDimitry Andric cl::desc("LoopVersioningLICM's minimum allowed percentage" 1010b57cec5SDimitry Andric "of possible invariant instructions per loop"), 1020b57cec5SDimitry Andric cl::init(25), cl::Hidden); 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric /// Threshold for maximum allowed loop nest/depth 1050b57cec5SDimitry Andric static cl::opt<unsigned> LVLoopDepthThreshold( 1060b57cec5SDimitry Andric "licm-versioning-max-depth-threshold", 1070b57cec5SDimitry Andric cl::desc( 1080b57cec5SDimitry Andric "LoopVersioningLICM's threshold for maximum allowed loop nest/depth"), 1090b57cec5SDimitry Andric cl::init(2), cl::Hidden); 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric namespace { 1120b57cec5SDimitry Andric 113e8d8bef9SDimitry Andric struct LoopVersioningLICM { 114e8d8bef9SDimitry Andric // We don't explicitly pass in LoopAccessInfo to the constructor since the 115e8d8bef9SDimitry Andric // loop versioning might return early due to instructions that are not safe 116e8d8bef9SDimitry Andric // for versioning. By passing the proxy instead the construction of 117e8d8bef9SDimitry Andric // LoopAccessInfo will take place only when it's necessary. 118e8d8bef9SDimitry Andric LoopVersioningLICM(AliasAnalysis *AA, ScalarEvolution *SE, 119e8d8bef9SDimitry Andric OptimizationRemarkEmitter *ORE, 120bdd1243dSDimitry Andric LoopAccessInfoManager &LAIs, LoopInfo &LI, 121bdd1243dSDimitry Andric Loop *CurLoop) 122bdd1243dSDimitry Andric : AA(AA), SE(SE), LAIs(LAIs), LI(LI), CurLoop(CurLoop), 123e8d8bef9SDimitry Andric LoopDepthThreshold(LVLoopDepthThreshold), 124e8d8bef9SDimitry Andric InvariantThreshold(LVInvarThreshold), ORE(ORE) {} 125e8d8bef9SDimitry Andric 126bdd1243dSDimitry Andric bool run(DominatorTree *DT); 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric private: 1290b57cec5SDimitry Andric // Current AliasAnalysis information 130bdd1243dSDimitry Andric AliasAnalysis *AA; 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric // Current ScalarEvolution 133bdd1243dSDimitry Andric ScalarEvolution *SE; 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric // Current Loop's LoopAccessInfo 1360b57cec5SDimitry Andric const LoopAccessInfo *LAI = nullptr; 1370b57cec5SDimitry Andric 138e8d8bef9SDimitry Andric // Proxy for retrieving LoopAccessInfo. 139bdd1243dSDimitry Andric LoopAccessInfoManager &LAIs; 140bdd1243dSDimitry Andric 141bdd1243dSDimitry Andric LoopInfo &LI; 142e8d8bef9SDimitry Andric 1430b57cec5SDimitry Andric // The current loop we are working on. 144bdd1243dSDimitry Andric Loop *CurLoop; 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric // Maximum loop nest threshold 1470b57cec5SDimitry Andric unsigned LoopDepthThreshold; 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric // Minimum invariant threshold 1500b57cec5SDimitry Andric float InvariantThreshold; 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric // Counter to track num of load & store 1530b57cec5SDimitry Andric unsigned LoadAndStoreCounter = 0; 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric // Counter to track num of invariant 1560b57cec5SDimitry Andric unsigned InvariantCounter = 0; 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric // Read only loop marker. 1590b57cec5SDimitry Andric bool IsReadOnlyLoop = true; 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric // OptimizationRemarkEmitter 1620b57cec5SDimitry Andric OptimizationRemarkEmitter *ORE; 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric bool isLegalForVersioning(); 1650b57cec5SDimitry Andric bool legalLoopStructure(); 1660b57cec5SDimitry Andric bool legalLoopInstructions(); 1670b57cec5SDimitry Andric bool legalLoopMemoryAccesses(); 1680b57cec5SDimitry Andric bool isLoopAlreadyVisited(); 1690b57cec5SDimitry Andric void setNoAliasToLoop(Loop *VerLoop); 1700b57cec5SDimitry Andric bool instructionSafeForVersioning(Instruction *I); 1710b57cec5SDimitry Andric }; 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric } // end anonymous namespace 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric /// Check loop structure and confirms it's good for LoopVersioningLICM. 1760b57cec5SDimitry Andric bool LoopVersioningLICM::legalLoopStructure() { 1770b57cec5SDimitry Andric // Loop must be in loop simplify form. 1780b57cec5SDimitry Andric if (!CurLoop->isLoopSimplifyForm()) { 1790b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " loop is not in loop-simplify form.\n"); 1800b57cec5SDimitry Andric return false; 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric // Loop should be innermost loop, if not return false. 1830b57cec5SDimitry Andric if (!CurLoop->getSubLoops().empty()) { 1840b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " loop is not innermost\n"); 1850b57cec5SDimitry Andric return false; 1860b57cec5SDimitry Andric } 1870b57cec5SDimitry Andric // Loop should have a single backedge, if not return false. 1880b57cec5SDimitry Andric if (CurLoop->getNumBackEdges() != 1) { 1890b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " loop has multiple backedges\n"); 1900b57cec5SDimitry Andric return false; 1910b57cec5SDimitry Andric } 1920b57cec5SDimitry Andric // Loop must have a single exiting block, if not return false. 1930b57cec5SDimitry Andric if (!CurLoop->getExitingBlock()) { 1940b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " loop has multiple exiting block\n"); 1950b57cec5SDimitry Andric return false; 1960b57cec5SDimitry Andric } 1970b57cec5SDimitry Andric // We only handle bottom-tested loop, i.e. loop in which the condition is 1980b57cec5SDimitry Andric // checked at the end of each iteration. With that we can assume that all 1990b57cec5SDimitry Andric // instructions in the loop are executed the same number of times. 2000b57cec5SDimitry Andric if (CurLoop->getExitingBlock() != CurLoop->getLoopLatch()) { 2010b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " loop is not bottom tested\n"); 2020b57cec5SDimitry Andric return false; 2030b57cec5SDimitry Andric } 2040b57cec5SDimitry Andric // Parallel loops must not have aliasing loop-invariant memory accesses. 2050b57cec5SDimitry Andric // Hence we don't need to version anything in this case. 2060b57cec5SDimitry Andric if (CurLoop->isAnnotatedParallel()) { 2070b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " Parallel loop is not worth versioning\n"); 2080b57cec5SDimitry Andric return false; 2090b57cec5SDimitry Andric } 2100b57cec5SDimitry Andric // Loop depth more then LoopDepthThreshold are not allowed 2110b57cec5SDimitry Andric if (CurLoop->getLoopDepth() > LoopDepthThreshold) { 2120b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " loop depth is more then threshold\n"); 2130b57cec5SDimitry Andric return false; 2140b57cec5SDimitry Andric } 2150b57cec5SDimitry Andric // We need to be able to compute the loop trip count in order 2160b57cec5SDimitry Andric // to generate the bound checks. 2170b57cec5SDimitry Andric const SCEV *ExitCount = SE->getBackedgeTakenCount(CurLoop); 218e8d8bef9SDimitry Andric if (isa<SCEVCouldNotCompute>(ExitCount)) { 2190b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " loop does not has trip count\n"); 2200b57cec5SDimitry Andric return false; 2210b57cec5SDimitry Andric } 2220b57cec5SDimitry Andric return true; 2230b57cec5SDimitry Andric } 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric /// Check memory accesses in loop and confirms it's good for 2260b57cec5SDimitry Andric /// LoopVersioningLICM. 2270b57cec5SDimitry Andric bool LoopVersioningLICM::legalLoopMemoryAccesses() { 228bdd1243dSDimitry Andric // Loop over the body of this loop, construct AST. 229bdd1243dSDimitry Andric BatchAAResults BAA(*AA); 230bdd1243dSDimitry Andric AliasSetTracker AST(BAA); 231bdd1243dSDimitry Andric for (auto *Block : CurLoop->getBlocks()) { 232bdd1243dSDimitry Andric // Ignore blocks in subloops. 233bdd1243dSDimitry Andric if (LI.getLoopFor(Block) == CurLoop) 234bdd1243dSDimitry Andric AST.add(*Block); 235bdd1243dSDimitry Andric } 236bdd1243dSDimitry Andric 2370b57cec5SDimitry Andric // Memory check: 2380b57cec5SDimitry Andric // Transform phase will generate a versioned loop and also a runtime check to 2390b57cec5SDimitry Andric // ensure the pointers are independent and they don’t alias. 2400b57cec5SDimitry Andric // In version variant of loop, alias meta data asserts that all access are 2410b57cec5SDimitry Andric // mutually independent. 2420b57cec5SDimitry Andric // 2430b57cec5SDimitry Andric // Pointers aliasing in alias domain are avoided because with multiple 2440b57cec5SDimitry Andric // aliasing domains we may not be able to hoist potential loop invariant 2450b57cec5SDimitry Andric // access out of the loop. 2460b57cec5SDimitry Andric // 2470b57cec5SDimitry Andric // Iterate over alias tracker sets, and confirm AliasSets doesn't have any 2480b57cec5SDimitry Andric // must alias set. 249bdd1243dSDimitry Andric bool HasMayAlias = false; 250bdd1243dSDimitry Andric bool TypeSafety = false; 251bdd1243dSDimitry Andric bool HasMod = false; 252bdd1243dSDimitry Andric for (const auto &I : AST) { 2530b57cec5SDimitry Andric const AliasSet &AS = I; 2540b57cec5SDimitry Andric // Skip Forward Alias Sets, as this should be ignored as part of 2550b57cec5SDimitry Andric // the AliasSetTracker object. 2560b57cec5SDimitry Andric if (AS.isForwardingAliasSet()) 2570b57cec5SDimitry Andric continue; 2580b57cec5SDimitry Andric // With MustAlias its not worth adding runtime bound check. 2590b57cec5SDimitry Andric if (AS.isMustAlias()) 2600b57cec5SDimitry Andric return false; 2617a6dacacSDimitry Andric const Value *SomePtr = AS.begin()->Ptr; 2620b57cec5SDimitry Andric bool TypeCheck = true; 2630b57cec5SDimitry Andric // Check for Mod & MayAlias 2640b57cec5SDimitry Andric HasMayAlias |= AS.isMayAlias(); 2650b57cec5SDimitry Andric HasMod |= AS.isMod(); 2667a6dacacSDimitry Andric for (const auto &MemLoc : AS) { 2677a6dacacSDimitry Andric const Value *Ptr = MemLoc.Ptr; 2680b57cec5SDimitry Andric // Alias tracker should have pointers of same data type. 2695f757f3fSDimitry Andric // 2705f757f3fSDimitry Andric // FIXME: check no longer effective since opaque pointers? 2715f757f3fSDimitry Andric // If the intent is to check that the memory accesses use the 2725f757f3fSDimitry Andric // same data type (such that LICM can promote them), then we 2735f757f3fSDimitry Andric // can no longer see this from the pointer value types. 2740b57cec5SDimitry Andric TypeCheck = (TypeCheck && (SomePtr->getType() == Ptr->getType())); 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric // At least one alias tracker should have pointers of same data type. 2770b57cec5SDimitry Andric TypeSafety |= TypeCheck; 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric // Ensure types should be of same type. 2800b57cec5SDimitry Andric if (!TypeSafety) { 2810b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " Alias tracker type safety failed!\n"); 2820b57cec5SDimitry Andric return false; 2830b57cec5SDimitry Andric } 2840b57cec5SDimitry Andric // Ensure loop body shouldn't be read only. 2850b57cec5SDimitry Andric if (!HasMod) { 2860b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " No memory modified in loop body\n"); 2870b57cec5SDimitry Andric return false; 2880b57cec5SDimitry Andric } 2890b57cec5SDimitry Andric // Make sure alias set has may alias case. 2900b57cec5SDimitry Andric // If there no alias memory ambiguity, return false. 2910b57cec5SDimitry Andric if (!HasMayAlias) { 2920b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " No ambiguity in memory access.\n"); 2930b57cec5SDimitry Andric return false; 2940b57cec5SDimitry Andric } 2950b57cec5SDimitry Andric return true; 2960b57cec5SDimitry Andric } 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric /// Check loop instructions safe for Loop versioning. 2990b57cec5SDimitry Andric /// It returns true if it's safe else returns false. 3000b57cec5SDimitry Andric /// Consider following: 3010b57cec5SDimitry Andric /// 1) Check all load store in loop body are non atomic & non volatile. 3020b57cec5SDimitry Andric /// 2) Check function call safety, by ensuring its not accessing memory. 3030b57cec5SDimitry Andric /// 3) Loop body shouldn't have any may throw instruction. 3040b57cec5SDimitry Andric /// 4) Loop body shouldn't have any convergent or noduplicate instructions. 3050b57cec5SDimitry Andric bool LoopVersioningLICM::instructionSafeForVersioning(Instruction *I) { 3060b57cec5SDimitry Andric assert(I != nullptr && "Null instruction found!"); 3070b57cec5SDimitry Andric // Check function call safety 3080b57cec5SDimitry Andric if (auto *Call = dyn_cast<CallBase>(I)) { 3090b57cec5SDimitry Andric if (Call->isConvergent() || Call->cannotDuplicate()) { 3100b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " Convergent call site found.\n"); 3110b57cec5SDimitry Andric return false; 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric if (!AA->doesNotAccessMemory(Call)) { 3150b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " Unsafe call site found.\n"); 3160b57cec5SDimitry Andric return false; 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric } 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric // Avoid loops with possiblity of throw 3210b57cec5SDimitry Andric if (I->mayThrow()) { 3220b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " May throw instruction found in loop body\n"); 3230b57cec5SDimitry Andric return false; 3240b57cec5SDimitry Andric } 3250b57cec5SDimitry Andric // If current instruction is load instructions 3260b57cec5SDimitry Andric // make sure it's a simple load (non atomic & non volatile) 3270b57cec5SDimitry Andric if (I->mayReadFromMemory()) { 3280b57cec5SDimitry Andric LoadInst *Ld = dyn_cast<LoadInst>(I); 3290b57cec5SDimitry Andric if (!Ld || !Ld->isSimple()) { 3300b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " Found a non-simple load.\n"); 3310b57cec5SDimitry Andric return false; 3320b57cec5SDimitry Andric } 3330b57cec5SDimitry Andric LoadAndStoreCounter++; 3340b57cec5SDimitry Andric Value *Ptr = Ld->getPointerOperand(); 3350b57cec5SDimitry Andric // Check loop invariant. 3360b57cec5SDimitry Andric if (SE->isLoopInvariant(SE->getSCEV(Ptr), CurLoop)) 3370b57cec5SDimitry Andric InvariantCounter++; 3380b57cec5SDimitry Andric } 3390b57cec5SDimitry Andric // If current instruction is store instruction 3400b57cec5SDimitry Andric // make sure it's a simple store (non atomic & non volatile) 3410b57cec5SDimitry Andric else if (I->mayWriteToMemory()) { 3420b57cec5SDimitry Andric StoreInst *St = dyn_cast<StoreInst>(I); 3430b57cec5SDimitry Andric if (!St || !St->isSimple()) { 3440b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " Found a non-simple store.\n"); 3450b57cec5SDimitry Andric return false; 3460b57cec5SDimitry Andric } 3470b57cec5SDimitry Andric LoadAndStoreCounter++; 3480b57cec5SDimitry Andric Value *Ptr = St->getPointerOperand(); 3490b57cec5SDimitry Andric // Check loop invariant. 3500b57cec5SDimitry Andric if (SE->isLoopInvariant(SE->getSCEV(Ptr), CurLoop)) 3510b57cec5SDimitry Andric InvariantCounter++; 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric IsReadOnlyLoop = false; 3540b57cec5SDimitry Andric } 3550b57cec5SDimitry Andric return true; 3560b57cec5SDimitry Andric } 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric /// Check loop instructions and confirms it's good for 3590b57cec5SDimitry Andric /// LoopVersioningLICM. 3600b57cec5SDimitry Andric bool LoopVersioningLICM::legalLoopInstructions() { 3610b57cec5SDimitry Andric // Resetting counters. 3620b57cec5SDimitry Andric LoadAndStoreCounter = 0; 3630b57cec5SDimitry Andric InvariantCounter = 0; 3640b57cec5SDimitry Andric IsReadOnlyLoop = true; 3650b57cec5SDimitry Andric using namespace ore; 3660b57cec5SDimitry Andric // Iterate over loop blocks and instructions of each block and check 3670b57cec5SDimitry Andric // instruction safety. 3680b57cec5SDimitry Andric for (auto *Block : CurLoop->getBlocks()) 3690b57cec5SDimitry Andric for (auto &Inst : *Block) { 3700b57cec5SDimitry Andric // If instruction is unsafe just return false. 3710b57cec5SDimitry Andric if (!instructionSafeForVersioning(&Inst)) { 3720b57cec5SDimitry Andric ORE->emit([&]() { 3730b57cec5SDimitry Andric return OptimizationRemarkMissed(DEBUG_TYPE, "IllegalLoopInst", &Inst) 3740b57cec5SDimitry Andric << " Unsafe Loop Instruction"; 3750b57cec5SDimitry Andric }); 3760b57cec5SDimitry Andric return false; 3770b57cec5SDimitry Andric } 3780b57cec5SDimitry Andric } 379e8d8bef9SDimitry Andric // Get LoopAccessInfo from current loop via the proxy. 380bdd1243dSDimitry Andric LAI = &LAIs.getInfo(*CurLoop); 3810b57cec5SDimitry Andric // Check LoopAccessInfo for need of runtime check. 3820b57cec5SDimitry Andric if (LAI->getRuntimePointerChecking()->getChecks().empty()) { 3830b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " LAA: Runtime check not found !!\n"); 3840b57cec5SDimitry Andric return false; 3850b57cec5SDimitry Andric } 3860b57cec5SDimitry Andric // Number of runtime-checks should be less then RuntimeMemoryCheckThreshold 3870b57cec5SDimitry Andric if (LAI->getNumRuntimePointerChecks() > 3880b57cec5SDimitry Andric VectorizerParams::RuntimeMemoryCheckThreshold) { 3890b57cec5SDimitry Andric LLVM_DEBUG( 3900b57cec5SDimitry Andric dbgs() << " LAA: Runtime checks are more than threshold !!\n"); 3910b57cec5SDimitry Andric ORE->emit([&]() { 3920b57cec5SDimitry Andric return OptimizationRemarkMissed(DEBUG_TYPE, "RuntimeCheck", 3930b57cec5SDimitry Andric CurLoop->getStartLoc(), 3940b57cec5SDimitry Andric CurLoop->getHeader()) 3950b57cec5SDimitry Andric << "Number of runtime checks " 3960b57cec5SDimitry Andric << NV("RuntimeChecks", LAI->getNumRuntimePointerChecks()) 3970b57cec5SDimitry Andric << " exceeds threshold " 3980b57cec5SDimitry Andric << NV("Threshold", VectorizerParams::RuntimeMemoryCheckThreshold); 3990b57cec5SDimitry Andric }); 4000b57cec5SDimitry Andric return false; 4010b57cec5SDimitry Andric } 4020b57cec5SDimitry Andric // Loop should have at least one invariant load or store instruction. 4030b57cec5SDimitry Andric if (!InvariantCounter) { 4040b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " Invariant not found !!\n"); 4050b57cec5SDimitry Andric return false; 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric // Read only loop not allowed. 4080b57cec5SDimitry Andric if (IsReadOnlyLoop) { 4090b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " Found a read-only loop!\n"); 4100b57cec5SDimitry Andric return false; 4110b57cec5SDimitry Andric } 4120b57cec5SDimitry Andric // Profitablity check: 4130b57cec5SDimitry Andric // Check invariant threshold, should be in limit. 4140b57cec5SDimitry Andric if (InvariantCounter * 100 < InvariantThreshold * LoadAndStoreCounter) { 4150b57cec5SDimitry Andric LLVM_DEBUG( 4160b57cec5SDimitry Andric dbgs() 4170b57cec5SDimitry Andric << " Invariant load & store are less then defined threshold\n"); 4180b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " Invariant loads & stores: " 4190b57cec5SDimitry Andric << ((InvariantCounter * 100) / LoadAndStoreCounter) 4200b57cec5SDimitry Andric << "%\n"); 4210b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " Invariant loads & store threshold: " 4220b57cec5SDimitry Andric << InvariantThreshold << "%\n"); 4230b57cec5SDimitry Andric ORE->emit([&]() { 4240b57cec5SDimitry Andric return OptimizationRemarkMissed(DEBUG_TYPE, "InvariantThreshold", 4250b57cec5SDimitry Andric CurLoop->getStartLoc(), 4260b57cec5SDimitry Andric CurLoop->getHeader()) 4270b57cec5SDimitry Andric << "Invariant load & store " 4280b57cec5SDimitry Andric << NV("LoadAndStoreCounter", 4290b57cec5SDimitry Andric ((InvariantCounter * 100) / LoadAndStoreCounter)) 4300b57cec5SDimitry Andric << " are less then defined threshold " 4310b57cec5SDimitry Andric << NV("Threshold", InvariantThreshold); 4320b57cec5SDimitry Andric }); 4330b57cec5SDimitry Andric return false; 4340b57cec5SDimitry Andric } 4350b57cec5SDimitry Andric return true; 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andric /// It checks loop is already visited or not. 4390b57cec5SDimitry Andric /// check loop meta data, if loop revisited return true 4400b57cec5SDimitry Andric /// else false. 4410b57cec5SDimitry Andric bool LoopVersioningLICM::isLoopAlreadyVisited() { 4420b57cec5SDimitry Andric // Check LoopVersioningLICM metadata into loop 4430b57cec5SDimitry Andric if (findStringMetadataForLoop(CurLoop, LICMVersioningMetaData)) { 4440b57cec5SDimitry Andric return true; 4450b57cec5SDimitry Andric } 4460b57cec5SDimitry Andric return false; 4470b57cec5SDimitry Andric } 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric /// Checks legality for LoopVersioningLICM by considering following: 4500b57cec5SDimitry Andric /// a) loop structure legality b) loop instruction legality 4510b57cec5SDimitry Andric /// c) loop memory access legality. 4520b57cec5SDimitry Andric /// Return true if legal else returns false. 4530b57cec5SDimitry Andric bool LoopVersioningLICM::isLegalForVersioning() { 4540b57cec5SDimitry Andric using namespace ore; 4550b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Loop: " << *CurLoop); 4560b57cec5SDimitry Andric // Make sure not re-visiting same loop again. 4570b57cec5SDimitry Andric if (isLoopAlreadyVisited()) { 4580b57cec5SDimitry Andric LLVM_DEBUG( 4590b57cec5SDimitry Andric dbgs() << " Revisiting loop in LoopVersioningLICM not allowed.\n\n"); 4600b57cec5SDimitry Andric return false; 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric // Check loop structure leagality. 4630b57cec5SDimitry Andric if (!legalLoopStructure()) { 4640b57cec5SDimitry Andric LLVM_DEBUG( 4650b57cec5SDimitry Andric dbgs() << " Loop structure not suitable for LoopVersioningLICM\n\n"); 4660b57cec5SDimitry Andric ORE->emit([&]() { 4670b57cec5SDimitry Andric return OptimizationRemarkMissed(DEBUG_TYPE, "IllegalLoopStruct", 4680b57cec5SDimitry Andric CurLoop->getStartLoc(), 4690b57cec5SDimitry Andric CurLoop->getHeader()) 4700b57cec5SDimitry Andric << " Unsafe Loop structure"; 4710b57cec5SDimitry Andric }); 4720b57cec5SDimitry Andric return false; 4730b57cec5SDimitry Andric } 4740b57cec5SDimitry Andric // Check loop instruction leagality. 4750b57cec5SDimitry Andric if (!legalLoopInstructions()) { 4760b57cec5SDimitry Andric LLVM_DEBUG( 4770b57cec5SDimitry Andric dbgs() 4780b57cec5SDimitry Andric << " Loop instructions not suitable for LoopVersioningLICM\n\n"); 4790b57cec5SDimitry Andric return false; 4800b57cec5SDimitry Andric } 4810b57cec5SDimitry Andric // Check loop memory access leagality. 4820b57cec5SDimitry Andric if (!legalLoopMemoryAccesses()) { 4830b57cec5SDimitry Andric LLVM_DEBUG( 4840b57cec5SDimitry Andric dbgs() 4850b57cec5SDimitry Andric << " Loop memory access not suitable for LoopVersioningLICM\n\n"); 4860b57cec5SDimitry Andric ORE->emit([&]() { 4870b57cec5SDimitry Andric return OptimizationRemarkMissed(DEBUG_TYPE, "IllegalLoopMemoryAccess", 4880b57cec5SDimitry Andric CurLoop->getStartLoc(), 4890b57cec5SDimitry Andric CurLoop->getHeader()) 4900b57cec5SDimitry Andric << " Unsafe Loop memory access"; 4910b57cec5SDimitry Andric }); 4920b57cec5SDimitry Andric return false; 4930b57cec5SDimitry Andric } 4940b57cec5SDimitry Andric // Loop versioning is feasible, return true. 4950b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " Loop Versioning found to be beneficial\n\n"); 4960b57cec5SDimitry Andric ORE->emit([&]() { 4970b57cec5SDimitry Andric return OptimizationRemark(DEBUG_TYPE, "IsLegalForVersioning", 4980b57cec5SDimitry Andric CurLoop->getStartLoc(), CurLoop->getHeader()) 4990b57cec5SDimitry Andric << " Versioned loop for LICM." 5000b57cec5SDimitry Andric << " Number of runtime checks we had to insert " 5010b57cec5SDimitry Andric << NV("RuntimeChecks", LAI->getNumRuntimePointerChecks()); 5020b57cec5SDimitry Andric }); 5030b57cec5SDimitry Andric return true; 5040b57cec5SDimitry Andric } 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric /// Update loop with aggressive aliasing assumptions. 5070b57cec5SDimitry Andric /// It marks no-alias to any pairs of memory operations by assuming 5080b57cec5SDimitry Andric /// loop should not have any must-alias memory accesses pairs. 5090b57cec5SDimitry Andric /// During LoopVersioningLICM legality we ignore loops having must 5100b57cec5SDimitry Andric /// aliasing memory accesses. 5110b57cec5SDimitry Andric void LoopVersioningLICM::setNoAliasToLoop(Loop *VerLoop) { 5120b57cec5SDimitry Andric // Get latch terminator instruction. 5130b57cec5SDimitry Andric Instruction *I = VerLoop->getLoopLatch()->getTerminator(); 5140b57cec5SDimitry Andric // Create alias scope domain. 5150b57cec5SDimitry Andric MDBuilder MDB(I->getContext()); 5160b57cec5SDimitry Andric MDNode *NewDomain = MDB.createAnonymousAliasScopeDomain("LVDomain"); 5170b57cec5SDimitry Andric StringRef Name = "LVAliasScope"; 5180b57cec5SDimitry Andric MDNode *NewScope = MDB.createAnonymousAliasScope(NewDomain, Name); 519e8d8bef9SDimitry Andric SmallVector<Metadata *, 4> Scopes{NewScope}, NoAliases{NewScope}; 5200b57cec5SDimitry Andric // Iterate over each instruction of loop. 5210b57cec5SDimitry Andric // set no-alias for all load & store instructions. 5220b57cec5SDimitry Andric for (auto *Block : CurLoop->getBlocks()) { 5230b57cec5SDimitry Andric for (auto &Inst : *Block) { 5240b57cec5SDimitry Andric // Only interested in instruction that may modify or read memory. 5250b57cec5SDimitry Andric if (!Inst.mayReadFromMemory() && !Inst.mayWriteToMemory()) 5260b57cec5SDimitry Andric continue; 5270b57cec5SDimitry Andric // Set no-alias for current instruction. 5280b57cec5SDimitry Andric Inst.setMetadata( 5290b57cec5SDimitry Andric LLVMContext::MD_noalias, 5300b57cec5SDimitry Andric MDNode::concatenate(Inst.getMetadata(LLVMContext::MD_noalias), 5310b57cec5SDimitry Andric MDNode::get(Inst.getContext(), NoAliases))); 5320b57cec5SDimitry Andric // set alias-scope for current instruction. 5330b57cec5SDimitry Andric Inst.setMetadata( 5340b57cec5SDimitry Andric LLVMContext::MD_alias_scope, 5350b57cec5SDimitry Andric MDNode::concatenate(Inst.getMetadata(LLVMContext::MD_alias_scope), 5360b57cec5SDimitry Andric MDNode::get(Inst.getContext(), Scopes))); 5370b57cec5SDimitry Andric } 5380b57cec5SDimitry Andric } 5390b57cec5SDimitry Andric } 5400b57cec5SDimitry Andric 541bdd1243dSDimitry Andric bool LoopVersioningLICM::run(DominatorTree *DT) { 5420b57cec5SDimitry Andric // Do not do the transformation if disabled by metadata. 543bdd1243dSDimitry Andric if (hasLICMVersioningTransformation(CurLoop) & TM_Disable) 5440b57cec5SDimitry Andric return false; 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric bool Changed = false; 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric // Check feasiblity of LoopVersioningLICM. 5490b57cec5SDimitry Andric // If versioning found to be feasible and beneficial then proceed 5500b57cec5SDimitry Andric // else simply return, by cleaning up memory. 5510b57cec5SDimitry Andric if (isLegalForVersioning()) { 5520b57cec5SDimitry Andric // Do loop versioning. 5530b57cec5SDimitry Andric // Create memcheck for memory accessed inside loop. 5540b57cec5SDimitry Andric // Clone original loop, and set blocks properly. 555e8d8bef9SDimitry Andric LoopVersioning LVer(*LAI, LAI->getRuntimePointerChecking()->getChecks(), 556bdd1243dSDimitry Andric CurLoop, &LI, DT, SE); 5570b57cec5SDimitry Andric LVer.versionLoop(); 5580b57cec5SDimitry Andric // Set Loop Versioning metaData for original loop. 5590b57cec5SDimitry Andric addStringMetadataToLoop(LVer.getNonVersionedLoop(), LICMVersioningMetaData); 5600b57cec5SDimitry Andric // Set Loop Versioning metaData for version loop. 5610b57cec5SDimitry Andric addStringMetadataToLoop(LVer.getVersionedLoop(), LICMVersioningMetaData); 5620b57cec5SDimitry Andric // Set "llvm.mem.parallel_loop_access" metaData to versioned loop. 5630b57cec5SDimitry Andric // FIXME: "llvm.mem.parallel_loop_access" annotates memory access 5640b57cec5SDimitry Andric // instructions, not loops. 5650b57cec5SDimitry Andric addStringMetadataToLoop(LVer.getVersionedLoop(), 5660b57cec5SDimitry Andric "llvm.mem.parallel_loop_access"); 5670b57cec5SDimitry Andric // Update version loop with aggressive aliasing assumption. 5680b57cec5SDimitry Andric setNoAliasToLoop(LVer.getVersionedLoop()); 5690b57cec5SDimitry Andric Changed = true; 5700b57cec5SDimitry Andric } 5710b57cec5SDimitry Andric return Changed; 5720b57cec5SDimitry Andric } 5730b57cec5SDimitry Andric 574e8d8bef9SDimitry Andric namespace llvm { 575e8d8bef9SDimitry Andric 576e8d8bef9SDimitry Andric PreservedAnalyses LoopVersioningLICMPass::run(Loop &L, LoopAnalysisManager &AM, 577e8d8bef9SDimitry Andric LoopStandardAnalysisResults &LAR, 578e8d8bef9SDimitry Andric LPMUpdater &U) { 579e8d8bef9SDimitry Andric AliasAnalysis *AA = &LAR.AA; 580e8d8bef9SDimitry Andric ScalarEvolution *SE = &LAR.SE; 581e8d8bef9SDimitry Andric DominatorTree *DT = &LAR.DT; 582e8d8bef9SDimitry Andric const Function *F = L.getHeader()->getParent(); 583e8d8bef9SDimitry Andric OptimizationRemarkEmitter ORE(F); 584e8d8bef9SDimitry Andric 585*0fca6ea1SDimitry Andric LoopAccessInfoManager LAIs(*SE, *AA, *DT, LAR.LI, nullptr, nullptr); 586bdd1243dSDimitry Andric if (!LoopVersioningLICM(AA, SE, &ORE, LAIs, LAR.LI, &L).run(DT)) 587e8d8bef9SDimitry Andric return PreservedAnalyses::all(); 588e8d8bef9SDimitry Andric return getLoopPassPreservedAnalyses(); 589e8d8bef9SDimitry Andric } 590e8d8bef9SDimitry Andric } // namespace llvm 591