[PATCH] D87778: [MemorySSA] Be more conservative when traversing MemoryPhis.

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 16 11:00:08 PDT 2020


fhahn created this revision.
fhahn added reviewers: asbirlea, efriedma, george.burgess.iv.
Herald added a subscriber: Prazek.
Herald added a project: LLVM.
fhahn requested review of this revision.

I think we need to be even more conservative when traversing memory
phis, to make sure we catch any loop carried dependences.

This approach updates fillInCurrentPair to use unknown sizes for
locations when we walk over a phi, unless the location is guaranteed to
be loop-invariant for any possible loop. Using an unknown size for
locations should ensure we catch all memory accesses to locations after
the given memory location, which includes loop-carried dependences.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D87778

Files:
  llvm/include/llvm/Analysis/MemorySSA.h
  llvm/test/Analysis/MemorySSA/phi-translation.ll


Index: llvm/test/Analysis/MemorySSA/phi-translation.ll
===================================================================
--- llvm/test/Analysis/MemorySSA/phi-translation.ll
+++ llvm/test/Analysis/MemorySSA/phi-translation.ll
@@ -481,8 +481,7 @@
 ; CHECK-NEXT:  ; 4 = MemoryPhi({entry,1},{cond.read,3})
 
 ; CHECK-LABEL: cond.read:
-; NOLIMIT:     ; MemoryUse(liveOnEntry)
-; LIMIT:       ; MemoryUse(4)
+; CHECK:       ; MemoryUse(4)
 ; CHECK-NEXT:  %use = load i32, i32* %ptr.1, align 4
 ; CHECK-NEXT:  ; 2 = MemoryDef(4)
 ; CHECK-NEXT:  %c.2 = call i1 @cond(i32 %use)
Index: llvm/include/llvm/Analysis/MemorySSA.h
===================================================================
--- llvm/include/llvm/Analysis/MemorySSA.h
+++ llvm/include/llvm/Analysis/MemorySSA.h
@@ -88,9 +88,9 @@
 #include "llvm/IR/DerivedUser.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/Operator.h"
 #include "llvm/IR/Type.h"
 #include "llvm/IR/Use.h"
-#include "llvm/IR/User.h"
 #include "llvm/IR/Value.h"
 #include "llvm/IR/ValueHandle.h"
 #include "llvm/Pass.h"
@@ -1217,9 +1217,40 @@
   BasicBlock *getPhiArgBlock() const { return DefIterator.getPhiArgBlock(); }
 
 private:
+  /// Returns true if \p Ptr is guaranteed to be loop invariant for any possible
+  /// loop. In particular, this guarantees that it only references a single
+  /// MemoryLocation during execution of the containing function.
+  bool IsGuaranteedLoopInvariant(Value *Ptr) const {
+    auto IsGuaranteedLoopInvariantBase = [](Value *Ptr) {
+      Ptr = Ptr->stripPointerCasts();
+      if (auto *I = dyn_cast<Instruction>(Ptr)) {
+        if (isa<AllocaInst>(Ptr))
+          return true;
+        return false;
+      }
+      return true;
+    };
+
+    Ptr = Ptr->stripPointerCasts();
+    if (auto *GEP = dyn_cast<GEPOperator>(Ptr)) {
+      return IsGuaranteedLoopInvariantBase(GEP->getPointerOperand()) &&
+             GEP->hasAllConstantIndices();
+    }
+    return IsGuaranteedLoopInvariantBase(Ptr);
+  }
+
   void fillInCurrentPair() {
     CurrentPair.first = *DefIterator;
+    CurrentPair.second = Location;
     if (WalkingPhi && Location.Ptr) {
+      // Mark size as unknown, if the location is not guaranteed to be
+      // loop-invariant for any possible loop in the function. Setting the size
+      // to unknown guarantees that any memory accesses that access locations
+      // after the pointer are considered as clobbers, which is important to
+      // catch loop carried dependences.
+      if (Location.Ptr &&
+          !IsGuaranteedLoopInvariant(const_cast<Value *>(Location.Ptr)))
+        CurrentPair.second = Location.getWithNewSize(LocationSize::unknown());
       PHITransAddr Translator(
           const_cast<Value *>(Location.Ptr),
           OriginalAccess->getBlock()->getModule()->getDataLayout(), nullptr);
@@ -1227,17 +1258,13 @@
                                         DefIterator.getPhiArgBlock(), DT,
                                         true)) {
         if (Translator.getAddr() != Location.Ptr) {
-          CurrentPair.second = Location.getWithNewPtr(Translator.getAddr());
+          CurrentPair.second = Location.getWithNewPtr(Translator.getAddr())
+                                   .getWithNewSize(LocationSize::unknown());
           if (PerformedPhiTranslation)
             *PerformedPhiTranslation = true;
-          return;
         }
-      } else {
-        CurrentPair.second = Location.getWithNewSize(LocationSize::unknown());
-        return;
       }
     }
-    CurrentPair.second = Location;
   }
 
   MemoryAccessPair CurrentPair;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D87778.292276.patch
Type: text/x-patch
Size: 3604 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200916/ff6a4b1d/attachment.bin>


More information about the llvm-commits mailing list