Index: lib/Transforms/Scalar/LoopInterchange.cpp =================================================================== --- lib/Transforms/Scalar/LoopInterchange.cpp +++ lib/Transforms/Scalar/LoopInterchange.cpp @@ -22,6 +22,7 @@ #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopIterator.h" #include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/OptimizationDiagnosticInfo.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionExpander.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" @@ -323,9 +324,10 @@ class LoopInterchangeLegality { public: LoopInterchangeLegality(Loop *Outer, Loop *Inner, ScalarEvolution *SE, - LoopInfo *LI, DominatorTree *DT, bool PreserveLCSSA) + LoopInfo *LI, DominatorTree *DT, bool PreserveLCSSA, + OptimizationRemarkEmitter *ORE) : OuterLoop(Outer), InnerLoop(Inner), SE(SE), LI(LI), DT(DT), - PreserveLCSSA(PreserveLCSSA), InnerLoopHasReduction(false) {} + PreserveLCSSA(PreserveLCSSA), ORE(ORE), InnerLoopHasReduction(false) {} /// Check if the loops can be interchanged. bool canInterchangeLoops(unsigned InnerLoopId, unsigned OuterLoopId, @@ -353,6 +355,8 @@ LoopInfo *LI; DominatorTree *DT; bool PreserveLCSSA; + /// Interface to emit optimization remarks. + OptimizationRemarkEmitter *ORE; bool InnerLoopHasReduction; }; @@ -422,6 +426,9 @@ DependenceInfo *DI; DominatorTree *DT; bool PreserveLCSSA; + /// Interface to emit optimization remarks. + OptimizationRemarkEmitter *ORE; + LoopInterchange() : FunctionPass(ID), SE(nullptr), LI(nullptr), DI(nullptr), DT(nullptr) { initializeLoopInterchangePass(*PassRegistry::getPassRegistry()); @@ -435,6 +442,7 @@ AU.addRequired(); AU.addRequiredID(LoopSimplifyID); AU.addRequiredID(LCSSAID); + AU.addRequired(); } bool runOnFunction(Function &F) override { @@ -446,6 +454,7 @@ DI = &getAnalysis().getDI(); auto *DTWP = getAnalysisIfAvailable(); DT = DTWP ? &DTWP->getDomTree() : nullptr; + ORE = &getAnalysis().getORE(); PreserveLCSSA = mustPreserveAnalysisID(LCSSAID); // Build up a worklist of loop pairs to analyze. @@ -575,7 +584,7 @@ Loop *OuterLoop = LoopList[OuterLoopId]; LoopInterchangeLegality LIL(OuterLoop, InnerLoop, SE, LI, DT, - PreserveLCSSA); + PreserveLCSSA, ORE); if (!LIL.canInterchangeLoops(InnerLoopId, OuterLoopId, DependencyMatrix)) { DEBUG(dbgs() << "Not interchanging Loops. Cannot prove legality\n"); return false; @@ -584,9 +593,21 @@ LoopInterchangeProfitability LIP(OuterLoop, InnerLoop, SE); if (!LIP.isProfitable(InnerLoopId, OuterLoopId, DependencyMatrix)) { DEBUG(dbgs() << "Interchanging loops not profitable\n"); + ORE->emit(OptimizationRemarkMissed("loop-interchange", + "InterchangeNotProfitable", + InnerLoop->getStartLoc(), + InnerLoop->getHeader()) + << "Interchanging loops is not profitable."); + + return false; } + ORE->emit(OptimizationRemark("loop-interchange", "Interchanged", + InnerLoop->getStartLoc(), + InnerLoop->getHeader()) + << "Loop interchanged with enclosing loop."); + LoopInterchangeTransform LIT(OuterLoop, InnerLoop, SE, LI, DT, LoopNestExit, LIL.hasInnerLoopReduction()); LIT.transform(); @@ -875,6 +896,11 @@ DEBUG(dbgs() << "Failed interchange InnerLoopId = " << InnerLoopId << " and OuterLoopId = " << OuterLoopId << " due to dependence\n"); + ORE->emit(OptimizationRemarkMissed("loop-interchange", + "InterchangeDependence", + InnerLoop->getStartLoc(), + InnerLoop->getHeader()) + << "Cannot interchange loops due to dependences."); return false; } @@ -904,12 +930,23 @@ // transform module. if (currentLimitations()) { DEBUG(dbgs() << "Not legal because of current transform limitation\n"); + ORE->emit(OptimizationRemarkMissed("loop-interchange", + "InterchangeLimitations", + InnerLoop->getStartLoc(), + InnerLoop->getHeader()) + << "Cannot interchange loops due to current limitations."); return false; } // Check if the loops are tightly nested. if (!tightlyNested(OuterLoop, InnerLoop)) { DEBUG(dbgs() << "Loops not tightly nested\n"); + ORE->emit(OptimizationRemarkMissed("loop-interchange", + "InterchangeTightlyNested", + InnerLoop->getStartLoc(), + InnerLoop->getHeader()) + << "Cannot interchange loops because they are not tightly " + << "nested."); return false; } Index: test/Transforms/LoopInterchange/loop-interchange-optimization-remarks.ll =================================================================== --- /dev/null +++ test/Transforms/LoopInterchange/loop-interchange-optimization-remarks.ll @@ -0,0 +1,195 @@ +; Test optimization remarks generated by the LoopInterchange pass. +; +; RUN: opt < %s -basicaa -loop-interchange -pass-remarks-missed='loop-interchange' -S 2>&1 \ +; RUN: | FileCheck --check-prefix MISSED %s +; RUN: opt < %s -basicaa -loop-interchange -pass-remarks='loop-interchange' -S 2>&1 \ +; RUN: | FileCheck --check-prefix OPT %s +; RUN: opt < %s -basicaa -loop-interchange -pass-remarks-missed='loop-interchange' \ +; RUN: -pass-remarks='loop-interchange' -S 2>&1 | FileCheck --check-prefix MISSED --check-prefix OPT %s + +@A = common global [100 x [100 x i32]] zeroinitializer +@B = common global [100 x [100 x i32]] zeroinitializer +@C = common global [100 x i32] zeroinitializer + +;;---------------------------------------Test case 01--------------------------------- +;; Loops interchange is not profitable. +;; for(int i=1;i