summaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/LoopVersioningLICM.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/Scalar/LoopVersioningLICM.cpp')
-rw-r--r--lib/Transforms/Scalar/LoopVersioningLICM.cpp148
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)