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" @@ -206,9 +207,9 @@ unsigned InvariantCounter; // Counter to track num of invariant bool IsReadOnlyLoop; // Read only loop marker. - bool isLegalForVersioning(); + bool isLegalForVersioning(OptimizationRemarkEmitter *ORE); bool legalLoopStructure(); - bool legalLoopInstructions(); + bool legalLoopInstructions(OptimizationRemarkEmitter *ORE); bool legalLoopMemoryAccesses(); bool isLoopAlreadyVisited(); void setNoAliasToLoop(Loop *); @@ -379,18 +380,26 @@ /// \brief Check loop instructions and confirms it's good for /// LoopVersioningLICM. -bool LoopVersioningLICM::legalLoopInstructions() { +bool LoopVersioningLICM::legalLoopInstructions(OptimizationRemarkEmitter *ORE) { // 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) + << " Illegal Loop Instruction"; + }); return false; + } } // Get LoopAccessInfo from current loop. LAI = &LAA->getInfo(CurLoop); @@ -403,6 +412,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 +441,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", static_cast(InvariantThreshold)); + }); return false; } return true; @@ -444,7 +470,7 @@ /// a) loop structure legality b) loop instruction legality /// c) loop memory access legality. /// Return true if legal else returns false. -bool LoopVersioningLICM::isLegalForVersioning() { +bool LoopVersioningLICM::isLegalForVersioning(OptimizationRemarkEmitter *ORE) { DEBUG(dbgs() << "Loop: " << *CurLoop); // Make sure not re-visiting same loop again. if (isLoopAlreadyVisited()) { @@ -456,22 +482,42 @@ if (!legalLoopStructure()) { DEBUG( dbgs() << " Loop structure not suitable for LoopVersioningLICM\n\n"); + ORE->emit([&]() { + return OptimizationRemarkMissed(DEBUG_TYPE, "IllegalLoopStruct", + CurLoop->getStartLoc(), CurLoop->getHeader()) + << " Illegal Loop structure"; + }); return false; } // Check loop instruction leagality. - if (!legalLoopInstructions()) { - DEBUG(dbgs() + if (!legalLoopInstructions(ORE)) { + DEBUG(dbgs() << " Loop instructions not suitable for LoopVersioningLICM\n\n"); + ORE->emit([&]() { + return OptimizationRemarkMissed(DEBUG_TYPE, "IllegalLoopInst", + CurLoop->getStartLoc(), CurLoop->getHeader()) + << " Loop instructions not suitable for LoopVersioningLICM"; + }); 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()) + << " Illegal 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"; + }); return true; } @@ -536,11 +582,12 @@ } bool Changed = false; + OptimizationRemarkEmitter ORE(CurLoop->getHeader()->getParent()); // Check feasiblity of LoopVersioningLICM. // If versioning found to be feasible and beneficial then proceed // else simply return, by cleaning up memory. - if (isLegalForVersioning()) { + if (isLegalForVersioning(&ORE)) { // Do loop versioning. // Create memcheck for memory accessed inside loop. // Clone original loop, and set blocks properly.