]> granicus.if.org Git - llvm/commitdiff
[SLP] Make sortMemAccesses explicitly return an error. NFC.
authorMichael Kuperstein <mkuper@google.com>
Fri, 3 Feb 2017 19:32:50 +0000 (19:32 +0000)
committerMichael Kuperstein <mkuper@google.com>
Fri, 3 Feb 2017 19:32:50 +0000 (19:32 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294029 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 1d9ade4468c28b5aaf7ebb6e3c734ff7d2b1def0..1cc679afa2ca6e1bbfbb274a462d747c2b1a6490 100644 (file)
@@ -692,13 +692,12 @@ int64_t getPtrStride(PredicatedScalarEvolution &PSE, Value *Ptr, const Loop *Lp,
 
 /// \brief Try to sort an array of loads / stores.
 ///
-/// If all pointers refer to the same object, and the differences between all
-/// pointer operands are known to be constant, the array is sorted by offset,
-/// and returned in \p Sorted.
-/// 
-/// If those conditions do not hold, the output array is an arbitrary
-/// permutation of the input.
-void sortMemAccesses(ArrayRef<Value *> VL, const DataLayout &DL,
+/// An array of loads / stores can only be sorted if all pointer operands
+/// refer to the same object, and the differences between these pointers 
+/// are known to be constant. If that is the case, this returns true, and the
+/// sorted array is returned in \p Sorted. Otherwise, this returns false, and
+/// \p Sorted is invalid.
+bool sortMemAccesses(ArrayRef<Value *> VL, const DataLayout &DL,
                      ScalarEvolution &SE, SmallVectorImpl<Value *> &Sorted);
 
 /// \brief Returns true if the memory operations \p A and \p B are consecutive.
index 4e076f5f004781e5c579548672e38ef1e61d46a2..f035ccda6f5be02e2a4fcbe8528135dbfbb36bb9 100644 (file)
@@ -1058,9 +1058,9 @@ static unsigned getAddressSpaceOperand(Value *I) {
   return -1;
 }
 
-void llvm::sortMemAccesses(ArrayRef<Value *> VL, const DataLayout &DL,
-                         ScalarEvolution &SE,
-                         SmallVectorImpl<Value *> &Sorted) {
+bool llvm::sortMemAccesses(ArrayRef<Value *> VL, const DataLayout &DL,
+                           ScalarEvolution &SE,
+                           SmallVectorImpl<Value *> &Sorted) {
   SmallVector<std::pair<int64_t, Value *>, 4> OffValPairs;
   OffValPairs.reserve(VL.size());
   Sorted.reserve(VL.size());
@@ -1077,10 +1077,8 @@ void llvm::sortMemAccesses(ArrayRef<Value *> VL, const DataLayout &DL,
     // If a pointer refers to a different underlying object, bail - the
     // pointers are by definition incomparable.
     Value *CurrObj = GetUnderlyingObject(Ptr, DL);
-    if (CurrObj != Obj0) {
-      Sorted.append(VL.begin(), VL.end());
-      return;
-    }
+    if (CurrObj != Obj0)
+      return false;
 
     const SCEVConstant *Diff =
         dyn_cast<SCEVConstant>(SE.getMinusSCEV(SE.getSCEV(Ptr), Scev0));
@@ -1088,10 +1086,8 @@ void llvm::sortMemAccesses(ArrayRef<Value *> VL, const DataLayout &DL,
     // The pointers may not have a constant offset from each other, or SCEV
     // may just not be smart enough to figure out they do. Regardless,
     // there's nothing we can do.
-    if (!Diff) {
-      Sorted.append(VL.begin(), VL.end());
-      return;
-    }
+    if (!Diff)
+      return false;
 
     OffValPairs.emplace_back(Diff->getAPInt().getSExtValue(), Val);
   }
@@ -1102,8 +1098,10 @@ void llvm::sortMemAccesses(ArrayRef<Value *> VL, const DataLayout &DL,
               return Left.first < Right.first;
             });
 
-  for (autoit : OffValPairs)
+  for (auto &it : OffValPairs)
     Sorted.push_back(it.second);
+
+  return true;
 }
 
 /// Returns true if the memory operations \p A and \p B are consecutive.
index 8a608ad71ec173539f9b5741db6899a54ce48d1c..dc64c39d38507918b6fd9702ccf9833d7a5c1e3f 100644 (file)
@@ -467,7 +467,9 @@ private:
                         ScalarEvolution &SE) const {
       assert(VL.size() == Scalars.size() && "Invalid size");
       SmallVector<Value *, 8> List;
-      sortMemAccesses(VL, DL, SE, List);
+      if (!sortMemAccesses(VL, DL, SE, List))
+        return false;
+
       return std::equal(List.begin(), List.end(), Scalars.begin());
     }
 
@@ -1223,18 +1225,19 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth) {
 
       if (VL.size() > 2 && !ReverseConsecutive) {
         bool ShuffledLoads = true;
-        SmallVector<Value *, 8> List;
-        sortMemAccesses(VL, *DL, *SE, List);
-        auto NewVL = makeArrayRef(List.begin(), List.end());
-        for (unsigned i = 0, e = NewVL.size() - 1; i < e; ++i) {
-          if (!isConsecutiveAccess(NewVL[i], NewVL[i + 1], *DL, *SE)) {
-            ShuffledLoads = false;
-            break;
+        SmallVector<Value *, 8> Sorted;
+        if (sortMemAccesses(VL, *DL, *SE, Sorted)) {
+          auto NewVL = makeArrayRef(Sorted.begin(), Sorted.end());
+          for (unsigned i = 0, e = NewVL.size() - 1; i < e; ++i) {
+            if (!isConsecutiveAccess(NewVL[i], NewVL[i + 1], *DL, *SE)) {
+              ShuffledLoads = false;
+              break;
+            }
+          }
+          if (ShuffledLoads) {
+            newTreeEntry(NewVL, true, true);
+            return;
           }
-        }
-        if (ShuffledLoads) {
-          newTreeEntry(NewVL, true, true);
-          return;
         }
       }