SLPVectorizer: Improve the compile time of isConsecutive by adding a simple constant...
authorNadav Rotem <nrotem@apple.com>
Tue, 16 Jul 2013 22:51:07 +0000 (22:51 +0000)
committerNadav Rotem <nrotem@apple.com>
Tue, 16 Jul 2013 22:51:07 +0000 (22:51 +0000)
This check does not always work because not all of the GEPs use a constant offset, but it happens often enough to reduce the number of times we use SCEV.

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

lib/Transforms/Vectorize/SLPVectorizer.cpp

index 50ca69776e84e5325f4f0f95fab3e0d562e61dba..c1e811126d6c78e9b53345fa84eecf81a3bd7967 100644 (file)
@@ -983,6 +983,24 @@ bool BoUpSLP::isConsecutiveAccess(Value *A, Value *B) {
   if (PtrA->getType() != PtrB->getType())
     return false;
 
+  // Calculate a constant offset from the base pointer without using SCEV
+  // in the supported cases. 
+  // TODO: Add support for the case where one of the pointers is a GEP that
+  // uses the other pointer.
+  GetElementPtrInst *GepA = dyn_cast<GetElementPtrInst>(PtrA);
+  GetElementPtrInst *GepB = dyn_cast<GetElementPtrInst>(PtrB);
+  if (GepA && GepB && GepA->getPointerOperand() == GepB->getPointerOperand()) {
+    unsigned BW = DL->getPointerSizeInBits(ASA);
+    APInt OffsetA(BW, 0) ,OffsetB(BW, 0);
+
+    if (GepA->accumulateConstantOffset(*DL, OffsetA) &&
+        GepB->accumulateConstantOffset(*DL, OffsetB)) {
+      Type *Ty = cast<PointerType>(PtrA->getType())->getElementType();
+      int64_t Sz = DL->getTypeStoreSize(Ty);
+      return ((OffsetB.getSExtValue() - OffsetA.getSExtValue()) == Sz);
+    }
+  }
+
   // Calculate the distance.
   const SCEV *PtrSCEVA = SE->getSCEV(PtrA);
   const SCEV *PtrSCEVB = SE->getSCEV(PtrB);