diff options
Diffstat (limited to 'lib/Transforms/Scalar/LoopVersioningLICM.cpp')
| -rw-r--r-- | lib/Transforms/Scalar/LoopVersioningLICM.cpp | 148 |
1 files changed, 103 insertions, 45 deletions
diff --git a/lib/Transforms/Scalar/LoopVersioningLICM.cpp b/lib/Transforms/Scalar/LoopVersioningLICM.cpp index 53b25e688e82..06e86081e8a0 100644 --- a/lib/Transforms/Scalar/LoopVersioningLICM.cpp +++ b/lib/Transforms/Scalar/LoopVersioningLICM.cpp @@ -68,6 +68,7 @@ #include "llvm/Analysis/LoopAccessAnalysis.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" @@ -85,6 +86,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils.h" #include "llvm/Transforms/Utils/LoopUtils.h" #include "llvm/Transforms/Utils/LoopVersioning.h" #include <cassert> @@ -111,7 +113,7 @@ static cl::opt<unsigned> LVLoopDepthThreshold( "LoopVersioningLICM's threshold for maximum allowed loop nest/depth"), cl::init(2), cl::Hidden); -/// \brief Create MDNode for input string. +/// Create MDNode for input string. static MDNode *createStringMetadata(Loop *TheLoop, StringRef Name, unsigned V) { LLVMContext &Context = TheLoop->getHeader()->getContext(); Metadata *MDs[] = { @@ -120,7 +122,7 @@ static MDNode *createStringMetadata(Loop *TheLoop, StringRef Name, unsigned V) { return MDNode::get(Context, MDs); } -/// \brief Set input string into loop metadata by keeping other values intact. +/// Set input string into loop metadata by keeping other values intact. void llvm::addStringMetadataToLoop(Loop *TheLoop, const char *MDString, unsigned V) { SmallVector<Metadata *, 4> MDs(1); @@ -166,6 +168,7 @@ struct LoopVersioningLICM : public LoopPass { AU.addRequired<ScalarEvolutionWrapperPass>(); AU.addPreserved<AAResultsWrapperPass>(); AU.addPreserved<GlobalsAAWrapperPass>(); + AU.addRequired<OptimizationRemarkEmitterWrapperPass>(); } StringRef getPassName() const override { return "Loop Versioning for LICM"; } @@ -178,6 +181,7 @@ struct LoopVersioningLICM : public LoopPass { LoadAndStoreCounter = 0; InvariantCounter = 0; IsReadOnlyLoop = true; + ORE = nullptr; CurAST.reset(); } @@ -207,7 +211,7 @@ private: Loop *CurLoop = nullptr; // AliasSet information for the current loop. - std::unique_ptr<AliasSetTracker> CurAST; + std::unique_ptr<AliasSetTracker> CurAST; // Maximum loop nest threshold unsigned LoopDepthThreshold; @@ -224,6 +228,9 @@ private: // Read only loop marker. bool IsReadOnlyLoop = true; + // OptimizationRemarkEmitter + OptimizationRemarkEmitter *ORE; + bool isLegalForVersioning(); bool legalLoopStructure(); bool legalLoopInstructions(); @@ -235,58 +242,57 @@ private: } // end anonymous namespace -/// \brief Check loop structure and confirms it's good for LoopVersioningLICM. +/// Check loop structure and confirms it's good for LoopVersioningLICM. bool LoopVersioningLICM::legalLoopStructure() { // Loop must be in loop simplify form. if (!CurLoop->isLoopSimplifyForm()) { - DEBUG( - dbgs() << " loop is not in loop-simplify form.\n"); + LLVM_DEBUG(dbgs() << " loop is not in loop-simplify form.\n"); return false; } // Loop should be innermost loop, if not return false. if (!CurLoop->getSubLoops().empty()) { - DEBUG(dbgs() << " loop is not innermost\n"); + LLVM_DEBUG(dbgs() << " loop is not innermost\n"); return false; } // Loop should have a single backedge, if not return false. if (CurLoop->getNumBackEdges() != 1) { - DEBUG(dbgs() << " loop has multiple backedges\n"); + LLVM_DEBUG(dbgs() << " loop has multiple backedges\n"); return false; } // Loop must have a single exiting block, if not return false. if (!CurLoop->getExitingBlock()) { - DEBUG(dbgs() << " loop has multiple exiting block\n"); + LLVM_DEBUG(dbgs() << " loop has multiple exiting block\n"); return false; } // We only handle bottom-tested loop, i.e. loop in which the condition is // checked at the end of each iteration. With that we can assume that all // instructions in the loop are executed the same number of times. if (CurLoop->getExitingBlock() != CurLoop->getLoopLatch()) { - DEBUG(dbgs() << " loop is not bottom tested\n"); + LLVM_DEBUG(dbgs() << " loop is not bottom tested\n"); return false; } // Parallel loops must not have aliasing loop-invariant memory accesses. // Hence we don't need to version anything in this case. if (CurLoop->isAnnotatedParallel()) { - DEBUG(dbgs() << " Parallel loop is not worth versioning\n"); + LLVM_DEBUG(dbgs() << " Parallel loop is not worth versioning\n"); return false; } // Loop depth more then LoopDepthThreshold are not allowed if (CurLoop->getLoopDepth() > LoopDepthThreshold) { - DEBUG(dbgs() << " loop depth is more then threshold\n"); + LLVM_DEBUG(dbgs() << " loop depth is more then threshold\n"); return false; } // We need to be able to compute the loop trip count in order // to generate the bound checks. const SCEV *ExitCount = SE->getBackedgeTakenCount(CurLoop); if (ExitCount == SE->getCouldNotCompute()) { - DEBUG(dbgs() << " loop does not has trip count\n"); + LLVM_DEBUG(dbgs() << " loop does not has trip count\n"); return false; } return true; } -/// \brief Check memory accesses in loop and confirms it's good for +/// Check memory accesses in loop and confirms it's good for /// LoopVersioningLICM. bool LoopVersioningLICM::legalLoopMemoryAccesses() { bool HasMayAlias = false; @@ -328,24 +334,24 @@ bool LoopVersioningLICM::legalLoopMemoryAccesses() { } // Ensure types should be of same type. if (!TypeSafety) { - DEBUG(dbgs() << " Alias tracker type safety failed!\n"); + LLVM_DEBUG(dbgs() << " Alias tracker type safety failed!\n"); return false; } // Ensure loop body shouldn't be read only. if (!HasMod) { - DEBUG(dbgs() << " No memory modified in loop body\n"); + LLVM_DEBUG(dbgs() << " No memory modified in loop body\n"); return false; } // Make sure alias set has may alias case. // If there no alias memory ambiguity, return false. if (!HasMayAlias) { - DEBUG(dbgs() << " No ambiguity in memory access.\n"); + LLVM_DEBUG(dbgs() << " No ambiguity in memory access.\n"); return false; } return true; } -/// \brief Check loop instructions safe for Loop versioning. +/// Check loop instructions safe for Loop versioning. /// It returns true if it's safe else returns false. /// Consider following: /// 1) Check all load store in loop body are non atomic & non volatile. @@ -355,12 +361,12 @@ bool LoopVersioningLICM::instructionSafeForVersioning(Instruction *I) { assert(I != nullptr && "Null instruction found!"); // Check function call safety if (isa<CallInst>(I) && !AA->doesNotAccessMemory(CallSite(I))) { - DEBUG(dbgs() << " Unsafe call site found.\n"); + LLVM_DEBUG(dbgs() << " Unsafe call site found.\n"); return false; } // Avoid loops with possiblity of throw if (I->mayThrow()) { - DEBUG(dbgs() << " May throw instruction found in loop body\n"); + LLVM_DEBUG(dbgs() << " May throw instruction found in loop body\n"); return false; } // If current instruction is load instructions @@ -368,7 +374,7 @@ bool LoopVersioningLICM::instructionSafeForVersioning(Instruction *I) { if (I->mayReadFromMemory()) { LoadInst *Ld = dyn_cast<LoadInst>(I); if (!Ld || !Ld->isSimple()) { - DEBUG(dbgs() << " Found a non-simple load.\n"); + LLVM_DEBUG(dbgs() << " Found a non-simple load.\n"); return false; } LoadAndStoreCounter++; @@ -382,7 +388,7 @@ bool LoopVersioningLICM::instructionSafeForVersioning(Instruction *I) { else if (I->mayWriteToMemory()) { StoreInst *St = dyn_cast<StoreInst>(I); if (!St || !St->isSimple()) { - DEBUG(dbgs() << " Found a non-simple store.\n"); + LLVM_DEBUG(dbgs() << " Found a non-simple store.\n"); return false; } LoadAndStoreCounter++; @@ -396,59 +402,87 @@ bool LoopVersioningLICM::instructionSafeForVersioning(Instruction *I) { return true; } -/// \brief Check loop instructions and confirms it's good for +/// Check loop instructions and confirms it's good for /// LoopVersioningLICM. bool LoopVersioningLICM::legalLoopInstructions() { // Resetting counters. LoadAndStoreCounter = 0; InvariantCounter = 0; IsReadOnlyLoop = true; + using namespace ore; // Iterate over loop blocks and instructions of each block and check // instruction safety. for (auto *Block : CurLoop->getBlocks()) for (auto &Inst : *Block) { // If instruction is unsafe just return false. - if (!instructionSafeForVersioning(&Inst)) + if (!instructionSafeForVersioning(&Inst)) { + ORE->emit([&]() { + return OptimizationRemarkMissed(DEBUG_TYPE, "IllegalLoopInst", &Inst) + << " Unsafe Loop Instruction"; + }); return false; + } } // Get LoopAccessInfo from current loop. LAI = &LAA->getInfo(CurLoop); // Check LoopAccessInfo for need of runtime check. if (LAI->getRuntimePointerChecking()->getChecks().empty()) { - DEBUG(dbgs() << " LAA: Runtime check not found !!\n"); + LLVM_DEBUG(dbgs() << " LAA: Runtime check not found !!\n"); return false; } // Number of runtime-checks should be less then RuntimeMemoryCheckThreshold if (LAI->getNumRuntimePointerChecks() > VectorizerParams::RuntimeMemoryCheckThreshold) { - DEBUG(dbgs() << " LAA: Runtime checks are more than threshold !!\n"); + LLVM_DEBUG( + dbgs() << " LAA: Runtime checks are more than threshold !!\n"); + ORE->emit([&]() { + return OptimizationRemarkMissed(DEBUG_TYPE, "RuntimeCheck", + CurLoop->getStartLoc(), + CurLoop->getHeader()) + << "Number of runtime checks " + << NV("RuntimeChecks", LAI->getNumRuntimePointerChecks()) + << " exceeds threshold " + << NV("Threshold", VectorizerParams::RuntimeMemoryCheckThreshold); + }); return false; } // Loop should have at least one invariant load or store instruction. if (!InvariantCounter) { - DEBUG(dbgs() << " Invariant not found !!\n"); + LLVM_DEBUG(dbgs() << " Invariant not found !!\n"); return false; } // Read only loop not allowed. if (IsReadOnlyLoop) { - DEBUG(dbgs() << " Found a read-only loop!\n"); + LLVM_DEBUG(dbgs() << " Found a read-only loop!\n"); return false; } // Profitablity check: // Check invariant threshold, should be in limit. if (InvariantCounter * 100 < InvariantThreshold * LoadAndStoreCounter) { - DEBUG(dbgs() - << " Invariant load & store are less then defined threshold\n"); - DEBUG(dbgs() << " Invariant loads & stores: " - << ((InvariantCounter * 100) / LoadAndStoreCounter) << "%\n"); - DEBUG(dbgs() << " Invariant loads & store threshold: " - << InvariantThreshold << "%\n"); + LLVM_DEBUG( + dbgs() + << " Invariant load & store are less then defined threshold\n"); + LLVM_DEBUG(dbgs() << " Invariant loads & stores: " + << ((InvariantCounter * 100) / LoadAndStoreCounter) + << "%\n"); + LLVM_DEBUG(dbgs() << " Invariant loads & store threshold: " + << InvariantThreshold << "%\n"); + ORE->emit([&]() { + return OptimizationRemarkMissed(DEBUG_TYPE, "InvariantThreshold", + CurLoop->getStartLoc(), + CurLoop->getHeader()) + << "Invariant load & store " + << NV("LoadAndStoreCounter", + ((InvariantCounter * 100) / LoadAndStoreCounter)) + << " are less then defined threshold " + << NV("Threshold", InvariantThreshold); + }); return false; } return true; } -/// \brief It checks loop is already visited or not. +/// It checks loop is already visited or not. /// check loop meta data, if loop revisited return true /// else false. bool LoopVersioningLICM::isLoopAlreadyVisited() { @@ -459,42 +493,64 @@ bool LoopVersioningLICM::isLoopAlreadyVisited() { return false; } -/// \brief Checks legality for LoopVersioningLICM by considering following: +/// Checks legality for LoopVersioningLICM by considering following: /// a) loop structure legality b) loop instruction legality /// c) loop memory access legality. /// Return true if legal else returns false. bool LoopVersioningLICM::isLegalForVersioning() { - DEBUG(dbgs() << "Loop: " << *CurLoop); + using namespace ore; + LLVM_DEBUG(dbgs() << "Loop: " << *CurLoop); // Make sure not re-visiting same loop again. if (isLoopAlreadyVisited()) { - DEBUG( + LLVM_DEBUG( dbgs() << " Revisiting loop in LoopVersioningLICM not allowed.\n\n"); return false; } // Check loop structure leagality. if (!legalLoopStructure()) { - DEBUG( + LLVM_DEBUG( dbgs() << " Loop structure not suitable for LoopVersioningLICM\n\n"); + ORE->emit([&]() { + return OptimizationRemarkMissed(DEBUG_TYPE, "IllegalLoopStruct", + CurLoop->getStartLoc(), + CurLoop->getHeader()) + << " Unsafe Loop structure"; + }); return false; } // Check loop instruction leagality. if (!legalLoopInstructions()) { - DEBUG(dbgs() - << " Loop instructions not suitable for LoopVersioningLICM\n\n"); + LLVM_DEBUG( + dbgs() + << " Loop instructions not suitable for LoopVersioningLICM\n\n"); return false; } // Check loop memory access leagality. if (!legalLoopMemoryAccesses()) { - DEBUG(dbgs() - << " Loop memory access not suitable for LoopVersioningLICM\n\n"); + LLVM_DEBUG( + dbgs() + << " Loop memory access not suitable for LoopVersioningLICM\n\n"); + ORE->emit([&]() { + return OptimizationRemarkMissed(DEBUG_TYPE, "IllegalLoopMemoryAccess", + CurLoop->getStartLoc(), + CurLoop->getHeader()) + << " Unsafe Loop memory access"; + }); return false; } // Loop versioning is feasible, return true. - DEBUG(dbgs() << " Loop Versioning found to be beneficial\n\n"); + LLVM_DEBUG(dbgs() << " Loop Versioning found to be beneficial\n\n"); + ORE->emit([&]() { + return OptimizationRemark(DEBUG_TYPE, "IsLegalForVersioning", + CurLoop->getStartLoc(), CurLoop->getHeader()) + << " Versioned loop for LICM." + << " Number of runtime checks we had to insert " + << NV("RuntimeChecks", LAI->getNumRuntimePointerChecks()); + }); return true; } -/// \brief Update loop with aggressive aliasing assumptions. +/// Update loop with aggressive aliasing assumptions. /// It marks no-alias to any pairs of memory operations by assuming /// loop should not have any must-alias memory accesses pairs. /// During LoopVersioningLICM legality we ignore loops having must @@ -542,6 +598,7 @@ bool LoopVersioningLICM::runOnLoop(Loop *L, LPPassManager &LPM) { AA = &getAnalysis<AAResultsWrapperPass>().getAAResults(); SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE(); LAA = &getAnalysis<LoopAccessLegacyAnalysis>(); + ORE = &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE(); LAI = nullptr; // Set Current Loop CurLoop = L; @@ -592,6 +649,7 @@ INITIALIZE_PASS_DEPENDENCY(LoopAccessLegacyAnalysis) INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(LoopSimplify) INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) +INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass) INITIALIZE_PASS_END(LoopVersioningLICM, "loop-versioning-licm", "Loop Versioning For LICM", false, false) |
