Index: include/llvm/IR/DiagnosticInfo.h =================================================================== --- include/llvm/IR/DiagnosticInfo.h +++ include/llvm/IR/DiagnosticInfo.h @@ -415,6 +415,7 @@ Argument(StringRef Key, const Type *T); Argument(StringRef Key, StringRef S); Argument(StringRef Key, int N); + Argument(StringRef Key, float N); Argument(StringRef Key, long N); Argument(StringRef Key, long long N); Argument(StringRef Key, unsigned N); Index: lib/IR/DiagnosticInfo.cpp =================================================================== --- lib/IR/DiagnosticInfo.cpp +++ lib/IR/DiagnosticInfo.cpp @@ -35,6 +35,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Regex.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/ScopedPrinter.h" #include #include #include @@ -166,6 +167,9 @@ DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N) : Key(Key), Val(itostr(N)) {} + +DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, float N) + : Key(Key), Val(llvm::to_string(N)) {} DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long N) : Key(Key), Val(itostr(N)) {} Index: lib/Transforms/Scalar/LoopVersioningLICM.cpp =================================================================== --- lib/Transforms/Scalar/LoopVersioningLICM.cpp +++ lib/Transforms/Scalar/LoopVersioningLICM.cpp @@ -71,6 +71,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/Analysis/ScalarEvolutionExpander.h" #include "llvm/Analysis/TargetLibraryInfo.h" @@ -159,13 +160,14 @@ AU.addRequired(); AU.addPreserved(); AU.addPreserved(); + AU.addRequired(); } LoopVersioningLICM() : LoopPass(ID), AA(nullptr), SE(nullptr), LAA(nullptr), LAI(nullptr), CurLoop(nullptr), LoopDepthThreshold(LVLoopDepthThreshold), InvariantThreshold(LVInvarThreshold), LoadAndStoreCounter(0), - InvariantCounter(0), IsReadOnlyLoop(true) { + InvariantCounter(0), IsReadOnlyLoop(true), ORE(nullptr) { initializeLoopVersioningLICMPass(*PassRegistry::getPassRegistry()); } StringRef getPassName() const override { return "Loop Versioning for LICM"; } @@ -178,6 +180,7 @@ LoadAndStoreCounter = 0; InvariantCounter = 0; IsReadOnlyLoop = true; + ORE = nullptr; CurAST.reset(); } @@ -205,6 +208,7 @@ unsigned LoadAndStoreCounter; // Counter to track num of load & store unsigned InvariantCounter; // Counter to track num of invariant bool IsReadOnlyLoop; // Read only loop marker. + OptimizationRemarkEmitter *ORE; bool isLegalForVersioning(); bool legalLoopStructure(); @@ -384,13 +388,21 @@ 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); @@ -403,6 +415,14 @@ if (LAI->getNumRuntimePointerChecks() > VectorizerParams::RuntimeMemoryCheckThreshold) { 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. @@ -424,6 +444,15 @@ << ((InvariantCounter * 100) / LoadAndStoreCounter) << "%\n"); 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; @@ -445,6 +474,8 @@ /// c) loop memory access legality. /// Return true if legal else returns false. bool LoopVersioningLICM::isLegalForVersioning() { + using namespace ore; + DEBUG(dbgs() << "Loop: " << *CurLoop); // Make sure not re-visiting same loop again. if (isLoopAlreadyVisited()) { @@ -456,22 +487,39 @@ if (!legalLoopStructure()) { 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() + 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"); + 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"); + 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; } @@ -524,6 +572,7 @@ SE = &getAnalysis().getSE(); LAA = &getAnalysis(); LAI = nullptr; + ORE = &getAnalysis().getORE(); // Set Current Loop CurLoop = L; CurAST.reset(new AliasSetTracker(*AA)); @@ -572,6 +621,7 @@ 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)