[LoopAccesses] Cache the result of canVectorizeMemory
authorAdam Nemet <anemet@apple.com>
Thu, 19 Feb 2015 19:15:00 +0000 (19:15 +0000)
committerAdam Nemet <anemet@apple.com>
Thu, 19 Feb 2015 19:15:00 +0000 (19:15 +0000)
LAA will be an on-demand analysis pass, so we need to cache the result
of the analysis.  canVectorizeMemory is renamed to analyzeLoop which
computes the result.  canVectorizeMemory becomes the query function for
the cached result.

This is part of the patchset that converts LoopAccessAnalysis into an
actual analysis pass.

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

include/llvm/Analysis/LoopAccessAnalysis.h
lib/Analysis/LoopAccessAnalysis.cpp
lib/Transforms/Vectorize/LoopVectorize.cpp

index 98e9c91f64f917bb197d0a18f330b7b0486602d9..3867b896504b2e835e8cbf688bf994488b7d3425 100644 (file)
@@ -140,11 +140,14 @@ public:
                  const TargetLibraryInfo *TLI, AliasAnalysis *AA,
                  DominatorTree *DT) :
       TheLoop(L), SE(SE), DL(DL), TLI(TLI), AA(AA), DT(DT), NumLoads(0),
-      NumStores(0), MaxSafeDepDistBytes(-1U) {}
+      NumStores(0), MaxSafeDepDistBytes(-1U), CanVecMem(false) {}
+
+  /// \brief Analyze the loop.  Replaces symbolic strides using Strides.
+  void analyzeLoop(ValueToValueMap &Strides);
 
   /// Return true we can analyze the memory accesses in the loop and there are
-  /// no memory dependence cycles.  Replaces symbolic strides using Strides.
-  bool canVectorizeMemory(ValueToValueMap &Strides);
+  /// no memory dependence cycles.
+  bool canVectorizeMemory() { return CanVecMem; }
 
   RuntimePointerCheck *getRuntimePointerCheck() { return &PtrRtCheck; }
 
@@ -189,6 +192,9 @@ private:
 
   unsigned MaxSafeDepDistBytes;
 
+  /// \brief Cache the result of analyzeLoop.
+  bool CanVecMem;
+
   /// \brief The diagnostics report generated for the analysis.  E.g. why we
   /// couldn't analyze the loop.
   Optional<VectorizationReport> Report;
index 8d64553d1deaee5c365355e8aa0a3e2671f784bb..5001b5fa3f1f798312b6404212918fe00e5885eb 100644 (file)
@@ -854,7 +854,7 @@ bool MemoryDepChecker::areDepsSafe(AccessAnalysis::DepCandidates &AccessSets,
   return true;
 }
 
-bool LoopAccessInfo::canVectorizeMemory(ValueToValueMap &Strides) {
+void LoopAccessInfo::analyzeLoop(ValueToValueMap &Strides) {
 
   typedef SmallVector<Value*, 16> ValueVector;
   typedef SmallPtrSet<Value*, 16> ValueSet;
@@ -897,7 +897,8 @@ bool LoopAccessInfo::canVectorizeMemory(ValueToValueMap &Strides) {
           emitAnalysis(VectorizationReport(Ld)
                        << "read with atomic ordering or volatile read");
           DEBUG(dbgs() << "LV: Found a non-simple load.\n");
-          return false;
+          CanVecMem = false;
+          return;
         }
         NumLoads++;
         Loads.push_back(Ld);
@@ -911,13 +912,15 @@ bool LoopAccessInfo::canVectorizeMemory(ValueToValueMap &Strides) {
         if (!St) {
           emitAnalysis(VectorizationReport(it) <<
                        "instruction cannot be vectorized");
-          return false;
+          CanVecMem = false;
+          return;
         }
         if (!St->isSimple() && !IsAnnotatedParallel) {
           emitAnalysis(VectorizationReport(St)
                        << "write with atomic ordering or volatile write");
           DEBUG(dbgs() << "LV: Found a non-simple store.\n");
-          return false;
+          CanVecMem = false;
+          return;
         }
         NumStores++;
         Stores.push_back(St);
@@ -933,7 +936,8 @@ bool LoopAccessInfo::canVectorizeMemory(ValueToValueMap &Strides) {
   // care if the pointers are *restrict*.
   if (!Stores.size()) {
     DEBUG(dbgs() << "LV: Found a read-only loop!\n");
-    return true;
+    CanVecMem = true;
+    return;
   }
 
   AccessAnalysis::DepCandidates DependentAccesses;
@@ -956,7 +960,8 @@ bool LoopAccessInfo::canVectorizeMemory(ValueToValueMap &Strides) {
           VectorizationReport(ST)
           << "write to a loop invariant address could not be vectorized");
       DEBUG(dbgs() << "LV: We don't allow storing to uniform addresses\n");
-      return false;
+      CanVecMem = false;
+      return;
     }
 
     // If we did *not* see this pointer before, insert it to  the read-write
@@ -979,7 +984,8 @@ bool LoopAccessInfo::canVectorizeMemory(ValueToValueMap &Strides) {
     DEBUG(dbgs()
           << "LV: A loop annotated parallel, ignore memory dependency "
           << "checks.\n");
-    return true;
+    CanVecMem = true;
+    return;
   }
 
   for (I = Loads.begin(), IE = Loads.end(); I != IE; ++I) {
@@ -1014,7 +1020,8 @@ bool LoopAccessInfo::canVectorizeMemory(ValueToValueMap &Strides) {
   // other reads in this loop then is it safe to vectorize.
   if (NumReadWrites == 1 && NumReads == 0) {
     DEBUG(dbgs() << "LV: Found a write-only loop!\n");
-    return true;
+    CanVecMem = true;
+    return;
   }
 
   // Build dependence sets and check whether we need a runtime pointer bounds
@@ -1055,12 +1062,13 @@ bool LoopAccessInfo::canVectorizeMemory(ValueToValueMap &Strides) {
     DEBUG(dbgs() << "LV: We can't vectorize because we can't find " <<
           "the array bounds.\n");
     PtrRtCheck.reset();
-    return false;
+    CanVecMem = false;
+    return;
   }
 
   PtrRtCheck.Need = NeedRTCheck;
 
-  bool CanVecMem = true;
+  CanVecMem = true;
   if (Accesses.isDependencyCheckNeeded()) {
     DEBUG(dbgs() << "LV: Checking memory dependencies\n");
     CanVecMem = DepChecker.areDepsSafe(
@@ -1093,7 +1101,8 @@ bool LoopAccessInfo::canVectorizeMemory(ValueToValueMap &Strides) {
                        << " dependent memory operations checked at runtime");
         DEBUG(dbgs() << "LV: Can't vectorize with memory checks\n");
         PtrRtCheck.reset();
-        return false;
+        CanVecMem = false;
+        return;
       }
 
       CanVecMem = true;
@@ -1106,8 +1115,6 @@ bool LoopAccessInfo::canVectorizeMemory(ValueToValueMap &Strides) {
 
   DEBUG(dbgs() << "LV: We" << (NeedRTCheck ? "" : " don't") <<
         " need a runtime memory check.\n");
-
-  return CanVecMem;
 }
 
 bool LoopAccessInfo::blockNeedsPredication(BasicBlock *BB, Loop *TheLoop,
index 8b671355ebd9d8b949d6d4154f8eeb0da2d04101..2ba7913119fd46c0e4410d152b058d90cc39a72d 100644 (file)
@@ -3807,11 +3807,11 @@ void LoopVectorizationLegality::collectLoopUniforms() {
 }
 
 bool LoopVectorizationLegality::canVectorizeMemory() {
-  bool Success = LAI.canVectorizeMemory(Strides);
+  LAI.analyzeLoop(Strides);
   auto &OptionalReport = LAI.getReport();
   if (OptionalReport)
     emitAnalysis(*OptionalReport);
-  return Success;
+  return LAI.canVectorizeMemory();
 }
 
 static bool hasMultipleUsesOf(Instruction *I,