Add optimization remarks to the loop unroller and vectorizer.
authorDiego Novillo <dnovillo@google.com>
Tue, 29 Apr 2014 14:27:31 +0000 (14:27 +0000)
committerDiego Novillo <dnovillo@google.com>
Tue, 29 Apr 2014 14:27:31 +0000 (14:27 +0000)
Summary:
This calls emitOptimizationRemark from the loop unroller and vectorizer
at the point where they make a positive transformation. For the
vectorizer, it reports vectorization and interleave factors. For the
loop unroller, it reports all the different supported types of
unrolling.

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D3456

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207528 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/LoopInfo.h
lib/Transforms/Utils/LoopUnroll.cpp
lib/Transforms/Vectorize/LoopVectorize.cpp

index 045d4dc565e7bb2e0fa6aba28e70dde6c0249be6..bef03e91bbbdcabd14bfddb3d3767a3e8a09536d 100644 (file)
@@ -453,6 +453,31 @@ public:
 
   void dump() const;
 
+  /// \brief Return the debug location of the start of this loop.
+  /// This looks for a BB terminating instruction with a known debug
+  /// location by looking at the preheader and header blocks. If it
+  /// cannot find a terminating instruction with location information,
+  /// it returns an unknown location.
+  DebugLoc getStartLoc() const {
+    DebugLoc StartLoc;
+    BasicBlock *HeadBB;
+
+    // Try the pre-header first.
+    if ((HeadBB = getLoopPreheader()) != nullptr) {
+      StartLoc = HeadBB->getTerminator()->getDebugLoc();
+      if (!StartLoc.isUnknown())
+        return StartLoc;
+    }
+
+    // If we have no pre-header or there are no instructions with debug
+    // info in it, try the header.
+    HeadBB = getHeader();
+    if (HeadBB)
+      StartLoc = HeadBB->getTerminator()->getDebugLoc();
+
+    return StartLoc;
+  }
+
 private:
   friend class LoopInfoBase<BasicBlock, Loop>;
   explicit Loop(BasicBlock *BB) : LoopBase<BasicBlock, Loop>(BB) {}
index 668324881e3d8cf2a293120a367db6be7c99e5ef..faaab5c12e4cfb1807e6c552935d04f8eba63531 100644 (file)
@@ -24,6 +24,7 @@
 #include "llvm/Analysis/ScalarEvolution.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/Dominators.h"
+#include "llvm/IR/LLVMContext.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
@@ -228,20 +229,33 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount,
       (unsigned)GreatestCommonDivisor64(Count, TripMultiple);
   }
 
+  // Report the unrolling decision.
+  DebugLoc LoopLoc = L->getStartLoc();
+  Function *F = Header->getParent();
+  LLVMContext &Ctx = F->getContext();
+
   if (CompletelyUnroll) {
     DEBUG(dbgs() << "COMPLETELY UNROLLING loop %" << Header->getName()
           << " with trip count " << TripCount << "!\n");
+    Ctx.emitOptimizationRemark(DEBUG_TYPE, *F, LoopLoc,
+                               Twine("completely unrolled loop with ") +
+                                   Twine(TripCount) + " iterations");
   } else {
     DEBUG(dbgs() << "UNROLLING loop %" << Header->getName()
           << " by " << Count);
+    Twine DiagMsg("unrolled loop by a factor of " + Twine(Count));
     if (TripMultiple == 0 || BreakoutTrip != TripMultiple) {
       DEBUG(dbgs() << " with a breakout at trip " << BreakoutTrip);
+      DiagMsg.concat(" with a breakout at trip " + Twine(BreakoutTrip));
     } else if (TripMultiple != 1) {
       DEBUG(dbgs() << " with " << TripMultiple << " trips per branch");
+      DiagMsg.concat(" with " + Twine(TripMultiple) + " trips per branch");
     } else if (RuntimeTripCount) {
       DEBUG(dbgs() << " with run-time trip count");
+      DiagMsg.concat(" with run-time trip count");
     }
     DEBUG(dbgs() << "!\n");
+    Ctx.emitOptimizationRemark(DEBUG_TYPE, *F, LoopLoc, DiagMsg);
   }
 
   bool ContinueOnTrue = L->contains(BI->getSuccessor(0));
index cf210d679d810749cd185e1f3f24ec7954c20b8f..586c220162fb5e9d7cd3d5ecc9777667a9d03689 100644 (file)
@@ -1222,6 +1222,12 @@ struct LoopVectorize : public FunctionPass {
     // Mark the loop as already vectorized to avoid vectorizing again.
     Hints.setAlreadyVectorized(L);
 
+    // Report the vectorization decision.
+    F->getContext().emitOptimizationRemark(
+        DEBUG_TYPE, *F, L->getStartLoc(),
+        Twine("vectorized loop (vectorization factor: ") + Twine(VF.Width) +
+            ", unroll factor: " + Twine(UF) + ")");
+
     DEBUG(verifyFunction(*L->getHeader()->getParent()));
     return true;
   }