Print vectorization analysis when loop hint is specified.
authorTyler Nowicki <tyler.nowicki@gmail.com>
Tue, 11 Aug 2015 01:09:15 +0000 (01:09 +0000)
committerTyler Nowicki <tyler.nowicki@gmail.com>
Tue, 11 Aug 2015 01:09:15 +0000 (01:09 +0000)
This patch and a relatec clang patch solve the problem of having to explicitly enable analysis when specifying a loop hint pragma to get the diagnostics. Passing AlwasyPrint as the pass name (see below) causes the front-end to print the diagnostic if the user has specified '-Rpass-analysis' without an '=<target-pass>’. Users of loop hints can pass that compiler option without having to specify the pass and they will get diagnostics for only those loops with loop hints.

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

include/llvm/IR/DiagnosticInfo.h
lib/IR/DiagnosticInfo.cpp
lib/Transforms/Vectorize/LoopVectorize.cpp
test/Transforms/LoopVectorize/control-flow.ll
test/Transforms/LoopVectorize/no_outside_user.ll
test/Transforms/LoopVectorize/no_switch.ll

index abd69ff9708c81274019f11d420d00d851e85f30..8ed65c0dd39f685aa6d401882e46013e9e9a0ac5 100644 (file)
@@ -101,6 +101,8 @@ public:
   /// The printed message must not end with '.' nor start with a severity
   /// keyword.
   virtual void print(DiagnosticPrinter &DP) const = 0;
+
+  static const char *AlwaysPrint;
 };
 
 typedef std::function<void(const DiagnosticInfo &)> DiagnosticHandlerFunction;
index 3acef9048cc250bcf8c7fc6ce84083d6e5d095e8..eab14e69eaa7ee81a1370c1a80b2ff1d831fc199 100644 (file)
@@ -91,6 +91,8 @@ int llvm::getNextAvailablePluginDiagnosticKind() {
   return ++PluginKindID;
 }
 
+const char *DiagnosticInfo::AlwaysPrint = "";
+
 DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
                                                  const Twine &MsgStr,
                                                  DiagnosticSeverity Severity)
@@ -166,8 +168,9 @@ bool DiagnosticInfoOptimizationRemarkMissed::isEnabled() const {
 }
 
 bool DiagnosticInfoOptimizationRemarkAnalysis::isEnabled() const {
-  return PassRemarksAnalysisOptLoc.Pattern &&
-         PassRemarksAnalysisOptLoc.Pattern->match(getPassName());
+  return getPassName() == DiagnosticInfo::AlwaysPrint ||
+         (PassRemarksAnalysisOptLoc.Pattern &&
+          PassRemarksAnalysisOptLoc.Pattern->match(getPassName()));
 }
 
 void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
index 2502d21c3b535cc55b75a7a3ca0aeb51fd585cef..f940d6daca1c7d1f403e54e4200643568acfec5e 100644 (file)
@@ -914,6 +914,10 @@ public:
   unsigned getWidth() const { return Width.Value; }
   unsigned getInterleave() const { return Interleave.Value; }
   enum ForceKind getForce() const { return (ForceKind)Force.Value; }
+  bool isForced() const {
+    return getForce() == LoopVectorizeHints::FK_Enabled || getWidth() > 1 ||
+           getInterleave() > 1;
+  }
 
 private:
   /// Find hints specified in the loop metadata and update local values.
@@ -1031,6 +1035,14 @@ private:
   const Loop *TheLoop;
 };
 
+static void emitAnalysisDiag(const Function *TheFunction, const Loop *TheLoop,
+                             const LoopVectorizeHints &Hints,
+                             const LoopAccessReport &Message) {
+  // If a loop hint is provided the diagnostic is always produced.
+  const char *Name = Hints.isForced() ? DiagnosticInfo::AlwaysPrint : LV_NAME;
+  LoopAccessReport::emitAnalysis(Message, TheFunction, TheLoop, Name);
+}
+
 static void emitMissedWarning(Function *F, Loop *L,
                               const LoopVectorizeHints &LH) {
   emitOptimizationRemarkMissed(F->getContext(), DEBUG_TYPE, *F,
@@ -1067,11 +1079,12 @@ public:
                             TargetLibraryInfo *TLI, AliasAnalysis *AA,
                             Function *F, const TargetTransformInfo *TTI,
                             LoopAccessAnalysis *LAA,
-                            LoopVectorizationRequirements *R)
+                            LoopVectorizationRequirements *R,
+                            const LoopVectorizeHints *H)
       : NumPredStores(0), TheLoop(L), SE(SE), TLI(TLI), TheFunction(F),
         TTI(TTI), DT(DT), LAA(LAA), LAI(nullptr), InterleaveInfo(SE, L, DT),
         Induction(nullptr), WidestIndTy(nullptr), HasFunNoNaNAttr(false),
-        Requirements(R) {}
+        Requirements(R), Hints(H) {}
 
   /// This enum represents the kinds of inductions that we support.
   enum InductionKind {
@@ -1285,8 +1298,8 @@ private:
   /// not vectorized.  These are handled as LoopAccessReport rather than
   /// VectorizationReport because the << operator of VectorizationReport returns
   /// LoopAccessReport.
-  void emitAnalysis(const LoopAccessReport &Message) {
-    LoopAccessReport::emitAnalysis(Message, TheFunction, TheLoop, LV_NAME);
+  void emitAnalysis(const LoopAccessReport &Message) const {
+    emitAnalysisDiag(TheFunction, TheLoop, *Hints, Message);
   }
 
   unsigned NumPredStores;
@@ -1340,6 +1353,9 @@ private:
   /// Vectorization requirements that will go through late-evaluation.
   LoopVectorizationRequirements *Requirements;
 
+  /// Used to emit an analysis of any legality issues.
+  const LoopVectorizeHints *Hints;
+
   ValueToValueMap Strides;
   SmallPtrSet<Value *, 8> StrideSet;
 
@@ -1430,8 +1446,8 @@ private:
   /// not vectorized.  These are handled as LoopAccessReport rather than
   /// VectorizationReport because the << operator of VectorizationReport returns
   /// LoopAccessReport.
-  void emitAnalysis(const LoopAccessReport &Message) {
-    LoopAccessReport::emitAnalysis(Message, TheFunction, TheLoop, LV_NAME);
+  void emitAnalysis(const LoopAccessReport &Message) const {
+    emitAnalysisDiag(TheFunction, TheLoop, *Hints, Message);
   }
 
   /// Values used only by @llvm.assume calls.
@@ -1480,13 +1496,14 @@ public:
   void addRuntimePointerChecks(unsigned Num) { NumRuntimePointerChecks = Num; }
 
   bool doesNotMeet(Function *F, Loop *L, const LoopVectorizeHints &Hints) {
+    // If a loop hint is provided the diagnostic is always produced.
+    const char *Name = Hints.isForced() ? DiagnosticInfo::AlwaysPrint : LV_NAME;
     bool failed = false;
-
     if (UnsafeAlgebraInst &&
         Hints.getForce() == LoopVectorizeHints::FK_Undefined &&
         Hints.getWidth() == 0) {
       emitOptimizationRemarkAnalysisFPCommute(
-          F->getContext(), DEBUG_TYPE, *F, UnsafeAlgebraInst->getDebugLoc(),
+          F->getContext(), Name, *F, UnsafeAlgebraInst->getDebugLoc(),
           VectorizationReport() << "vectorization requires changes in the "
                                    "order of operations, however IEEE 754 "
                                    "floating-point operations are not "
@@ -1497,7 +1514,7 @@ public:
     if (NumRuntimePointerChecks >
         VectorizerParams::RuntimeMemoryCheckThreshold) {
       emitOptimizationRemarkAnalysisAliasing(
-          F->getContext(), DEBUG_TYPE, *F, L->getStartLoc(),
+          F->getContext(), Name, *F, L->getStartLoc(),
           VectorizationReport()
               << "cannot prove pointers refer to independent arrays in memory. "
                  "The loop requires "
@@ -1679,9 +1696,9 @@ struct LoopVectorize : public FunctionPass {
         DEBUG(dbgs() << " But vectorizing was explicitly forced.\n");
       else {
         DEBUG(dbgs() << "\n");
-        emitOptimizationRemarkAnalysis(
-            F->getContext(), DEBUG_TYPE, *F, L->getStartLoc(),
-            "vectorization is not beneficial and is not explicitly forced");
+        emitAnalysisDiag(F, L, Hints, VectorizationReport()
+                                          << "vectorization is not beneficial "
+                                             "and is not explicitly forced");
         return false;
       }
     }
@@ -1689,7 +1706,7 @@ struct LoopVectorize : public FunctionPass {
     // Check if it is legal to vectorize the loop.
     LoopVectorizationRequirements Requirements;
     LoopVectorizationLegality LVL(L, SE, DT, TLI, AA, F, TTI, LAA,
-                                  &Requirements);
+                                  &Requirements, &Hints);
     if (!LVL.canVectorize()) {
       DEBUG(dbgs() << "LV: Not vectorizing: Cannot prove legality.\n");
       emitMissedWarning(F, L, Hints);
@@ -1724,9 +1741,10 @@ struct LoopVectorize : public FunctionPass {
     if (F->hasFnAttribute(Attribute::NoImplicitFloat)) {
       DEBUG(dbgs() << "LV: Can't vectorize when the NoImplicitFloat"
             "attribute is used.\n");
-      emitOptimizationRemarkAnalysis(
-          F->getContext(), DEBUG_TYPE, *F, L->getStartLoc(),
-          "loop not vectorized due to NoImplicitFloat attribute");
+      emitAnalysisDiag(
+          F, L, Hints,
+          VectorizationReport()
+              << "loop not vectorized due to NoImplicitFloat attribute");
       emitMissedWarning(F, L, Hints);
       return false;
     }
index 888640786932e2158223f1bbcaea5d1bff6fa647..83bf98fe7a1be98eabaa977af9bb032968b48978 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: opt < %s -loop-vectorize -force-vector-width=4 -S -pass-remarks-missed='loop-vectorize' -pass-remarks-analysis='loop-vectorize' 2>&1 | FileCheck %s
+; RUN: opt < %s -loop-vectorize -force-vector-width=4 -S -pass-remarks-missed='loop-vectorize' 2>&1 | FileCheck %s
 
 ; C/C++ code for control flow test
 ; int test(int *A, int Length) {
index 7030b6b4df2d47485c95c94c99d5f0e304564146..2683b42dc7172b138b7d1bda9e06ec0c33ffabfb 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: opt -S -loop-vectorize -force-vector-interleave=1 -force-vector-width=2 -pass-remarks-analysis=loop-vectorize < %s 2>&1 | FileCheck %s
+; RUN: opt -S -loop-vectorize -force-vector-interleave=1 -force-vector-width=2 < %s 2>&1 | FileCheck %s
 
 ; CHECK: remark: {{.*}}: loop not vectorized: value could not be identified as an induction or reduction variable
 ; CHECK: remark: {{.*}}: loop not vectorized: use of induction value outside of the loop is not handled by vectorizer
index 5dc71df0cf9fac493ccc01d800586ff87f8968d1..904a96fa5b62998f3d1071de8af1a0410869d1c2 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: opt < %s -loop-vectorize -force-vector-width=4 -S -pass-remarks-missed='loop-vectorize' -pass-remarks-analysis='loop-vectorize' 2>&1 | FileCheck %s
+; RUN: opt < %s -loop-vectorize -force-vector-width=4 -S -pass-remarks-missed='loop-vectorize' 2>&1 | FileCheck %s
 
 ; CHECK: remark: source.cpp:4:5: loop not vectorized: loop contains a switch statement
 ; CHECK: remark: source.cpp:4:5: loop not vectorized: use -Rpass-analysis=loop-vectorize for more info (Force=true, Vector Width=4)