xref: /freebsd-src/contrib/llvm-project/llvm/lib/Transforms/Scalar/LoopVersioningLICM.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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