[llvm] r357319 - [MemorySSA] Limit clobber walks.

Alina Sbirlea via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 29 14:56:09 PDT 2019


Author: asbirlea
Date: Fri Mar 29 14:56:09 2019
New Revision: 357319

URL: http://llvm.org/viewvc/llvm-project?rev=357319&view=rev
Log:
[MemorySSA] Limit clobber walks.

Summary: This patch limits all getClobberingMemoryAccess() walks to MaxCheckLimit.

Reviewers: george.burgess.iv

Subscribers: sanjoy, jlebar, Prazek, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D59569

Modified:
    llvm/trunk/lib/Analysis/MemorySSA.cpp
    llvm/trunk/test/Analysis/MemorySSA/optimize-use.ll
    llvm/trunk/test/Analysis/MemorySSA/phi-translation.ll

Modified: llvm/trunk/lib/Analysis/MemorySSA.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemorySSA.cpp?rev=357319&r1=357318&r2=357319&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/MemorySSA.cpp (original)
+++ llvm/trunk/lib/Analysis/MemorySSA.cpp Fri Mar 29 14:56:09 2019
@@ -504,6 +504,7 @@ template <class AliasAnalysisType> class
   AliasAnalysisType &AA;
   DominatorTree &DT;
   UpwardsMemoryQuery *Query;
+  unsigned *UpwardWalkLimit;
 
   // Phi optimization bookkeeping
   SmallVector<DefPath, 32> Paths;
@@ -542,6 +543,8 @@ template <class AliasAnalysisType> class
   walkToPhiOrClobber(DefPath &Desc, const MemoryAccess *StopAt = nullptr,
                      const MemoryAccess *SkipStopAt = nullptr) const {
     assert(!isa<MemoryUse>(Desc.Last) && "Uses don't exist in my world");
+    assert(UpwardWalkLimit && *UpwardWalkLimit > 0 &&
+           "Need a positive walk limit");
 
     for (MemoryAccess *Current : def_chain(Desc.Last)) {
       Desc.Last = Current;
@@ -551,6 +554,10 @@ template <class AliasAnalysisType> class
       if (auto *MD = dyn_cast<MemoryDef>(Current)) {
         if (MSSA.isLiveOnEntryDef(MD))
           return {MD, true, MustAlias};
+
+        if (!--*UpwardWalkLimit)
+          return {Current, true, MayAlias};
+
         ClobberAlias CA =
             instructionClobbersQuery(MD, Desc.Loc, Query->Inst, AA);
         if (CA.IsClobber)
@@ -629,10 +636,12 @@ template <class AliasAnalysisType> class
         SkipStopWhere = Query->OriginalAccess;
       }
 
-      UpwardsWalkResult Res = walkToPhiOrClobber(Node, /*StopAt=*/StopWhere,
+      UpwardsWalkResult Res = walkToPhiOrClobber(Node,
+                                                 /*StopAt=*/StopWhere,
                                                  /*SkipStopAt=*/SkipStopWhere);
       if (Res.IsKnownClobber) {
         assert(Res.Result != StopWhere && Res.Result != SkipStopWhere);
+
         // If this wasn't a cache hit, we hit a clobber when walking. That's a
         // failure.
         TerminatedPath Term{Res.Result, PathIndex};
@@ -896,8 +905,13 @@ public:
   AliasAnalysisType *getAA() { return &AA; }
   /// Finds the nearest clobber for the given query, optimizing phis if
   /// possible.
-  MemoryAccess *findClobber(MemoryAccess *Start, UpwardsMemoryQuery &Q) {
+  MemoryAccess *findClobber(MemoryAccess *Start, UpwardsMemoryQuery &Q,
+                            unsigned &UpWalkLimit) {
     Query = &Q;
+    UpwardWalkLimit = &UpWalkLimit;
+    // Starting limit must be > 0.
+    if (!UpWalkLimit)
+      UpWalkLimit++;
 
     MemoryAccess *Current = Start;
     // This walker pretends uses don't exist. If we're handed one, silently grab
@@ -922,7 +936,7 @@ public:
     }
 
 #ifdef EXPENSIVE_CHECKS
-    if (!Q.SkipSelfAccess)
+    if (!Q.SkipSelfAccess && *UpwardWalkLimit > 0)
       checkClobberSanity(Current, Result, Q.StartingLoc, MSSA, Q, AA);
 #endif
     return Result;
@@ -958,14 +972,15 @@ public:
       : Walker(*M, *A, *D), MSSA(M) {}
 
   MemoryAccess *getClobberingMemoryAccessBase(MemoryAccess *,
-                                              const MemoryLocation &);
-  // Second argument (bool), defines whether the clobber search should skip the
+                                              const MemoryLocation &,
+                                              unsigned &);
+  // Third argument (bool), defines whether the clobber search should skip the
   // original queried access. If true, there will be a follow-up query searching
   // for a clobber access past "self". Note that the Optimized access is not
   // updated if a new clobber is found by this SkipSelf search. If this
   // additional query becomes heavily used we may decide to cache the result.
   // Walker instantiations will decide how to set the SkipSelf bool.
-  MemoryAccess *getClobberingMemoryAccessBase(MemoryAccess *, bool);
+  MemoryAccess *getClobberingMemoryAccessBase(MemoryAccess *, unsigned &, bool);
 };
 
 /// A MemorySSAWalker that does AA walks to disambiguate accesses. It no
@@ -982,12 +997,23 @@ public:
 
   using MemorySSAWalker::getClobberingMemoryAccess;
 
+  MemoryAccess *getClobberingMemoryAccess(MemoryAccess *MA, unsigned &UWL) {
+    return Walker->getClobberingMemoryAccessBase(MA, UWL, false);
+  }
+  MemoryAccess *getClobberingMemoryAccess(MemoryAccess *MA,
+                                          const MemoryLocation &Loc,
+                                          unsigned &UWL) {
+    return Walker->getClobberingMemoryAccessBase(MA, Loc, UWL);
+  }
+
   MemoryAccess *getClobberingMemoryAccess(MemoryAccess *MA) override {
-    return Walker->getClobberingMemoryAccessBase(MA, false);
+    unsigned UpwardWalkLimit = MaxCheckLimit;
+    return getClobberingMemoryAccess(MA, UpwardWalkLimit);
   }
   MemoryAccess *getClobberingMemoryAccess(MemoryAccess *MA,
                                           const MemoryLocation &Loc) override {
-    return Walker->getClobberingMemoryAccessBase(MA, Loc);
+    unsigned UpwardWalkLimit = MaxCheckLimit;
+    return getClobberingMemoryAccess(MA, Loc, UpwardWalkLimit);
   }
 
   void invalidateInfo(MemoryAccess *MA) override {
@@ -1007,12 +1033,23 @@ public:
 
   using MemorySSAWalker::getClobberingMemoryAccess;
 
+  MemoryAccess *getClobberingMemoryAccess(MemoryAccess *MA, unsigned &UWL) {
+    return Walker->getClobberingMemoryAccessBase(MA, UWL, true);
+  }
+  MemoryAccess *getClobberingMemoryAccess(MemoryAccess *MA,
+                                          const MemoryLocation &Loc,
+                                          unsigned &UWL) {
+    return Walker->getClobberingMemoryAccessBase(MA, Loc, UWL);
+  }
+
   MemoryAccess *getClobberingMemoryAccess(MemoryAccess *MA) override {
-    return Walker->getClobberingMemoryAccessBase(MA, true);
+    unsigned UpwardWalkLimit = MaxCheckLimit;
+    return getClobberingMemoryAccess(MA, UpwardWalkLimit);
   }
   MemoryAccess *getClobberingMemoryAccess(MemoryAccess *MA,
                                           const MemoryLocation &Loc) override {
-    return Walker->getClobberingMemoryAccessBase(MA, Loc);
+    unsigned UpwardWalkLimit = MaxCheckLimit;
+    return getClobberingMemoryAccess(MA, Loc, UpwardWalkLimit);
   }
 
   void invalidateInfo(MemoryAccess *MA) override {
@@ -1205,8 +1242,8 @@ namespace llvm {
 /// which is walking bottom-up.
 class MemorySSA::OptimizeUses {
 public:
-  OptimizeUses(MemorySSA *MSSA, MemorySSAWalker *Walker, BatchAAResults *BAA,
-               DominatorTree *DT)
+  OptimizeUses(MemorySSA *MSSA, CachingWalker<BatchAAResults> *Walker,
+               BatchAAResults *BAA, DominatorTree *DT)
       : MSSA(MSSA), Walker(Walker), AA(BAA), DT(DT) {}
 
   void optimizeUses();
@@ -1235,7 +1272,7 @@ private:
                            DenseMap<MemoryLocOrCall, MemlocStackInfo> &);
 
   MemorySSA *MSSA;
-  MemorySSAWalker *Walker;
+  CachingWalker<BatchAAResults> *Walker;
   BatchAAResults *AA;
   DominatorTree *DT;
 };
@@ -1353,11 +1390,12 @@ void MemorySSA::OptimizeUses::optimizeUs
       continue;
     }
     bool FoundClobberResult = false;
+    unsigned UpwardWalkLimit = MaxCheckLimit;
     while (UpperBound > LocInfo.LowerBound) {
       if (isa<MemoryPhi>(VersionStack[UpperBound])) {
         // For phis, use the walker, see where we ended up, go there
-        Instruction *UseInst = MU->getMemoryInst();
-        MemoryAccess *Result = Walker->getClobberingMemoryAccess(UseInst);
+        MemoryAccess *Result =
+            Walker->getClobberingMemoryAccess(MU, UpwardWalkLimit);
         // We are guaranteed to find it or something is wrong
         while (VersionStack[UpperBound] != Result) {
           assert(UpperBound != 0);
@@ -2210,7 +2248,8 @@ MemorySSAWalker::MemorySSAWalker(MemoryS
 template <typename AliasAnalysisType>
 MemoryAccess *
 MemorySSA::ClobberWalkerBase<AliasAnalysisType>::getClobberingMemoryAccessBase(
-    MemoryAccess *StartingAccess, const MemoryLocation &Loc) {
+    MemoryAccess *StartingAccess, const MemoryLocation &Loc,
+    unsigned &UpwardWalkLimit) {
   if (isa<MemoryPhi>(StartingAccess))
     return StartingAccess;
 
@@ -2238,7 +2277,8 @@ MemorySSA::ClobberWalkerBase<AliasAnalys
                                      ? StartingUseOrDef->getDefiningAccess()
                                      : StartingUseOrDef;
 
-  MemoryAccess *Clobber = Walker.findClobber(DefiningAccess, Q);
+  MemoryAccess *Clobber =
+      Walker.findClobber(DefiningAccess, Q, UpwardWalkLimit);
   LLVM_DEBUG(dbgs() << "Starting Memory SSA clobber for " << *I << " is ");
   LLVM_DEBUG(dbgs() << *StartingUseOrDef << "\n");
   LLVM_DEBUG(dbgs() << "Final Memory SSA clobber for " << *I << " is ");
@@ -2249,7 +2289,7 @@ MemorySSA::ClobberWalkerBase<AliasAnalys
 template <typename AliasAnalysisType>
 MemoryAccess *
 MemorySSA::ClobberWalkerBase<AliasAnalysisType>::getClobberingMemoryAccessBase(
-    MemoryAccess *MA, bool SkipSelf) {
+    MemoryAccess *MA, unsigned &UpwardWalkLimit, bool SkipSelf) {
   auto *StartingAccess = dyn_cast<MemoryUseOrDef>(MA);
   // If this is a MemoryPhi, we can't do anything.
   if (!StartingAccess)
@@ -2295,7 +2335,7 @@ MemorySSA::ClobberWalkerBase<AliasAnalys
       return DefiningAccess;
     }
 
-    OptimizedAccess = Walker.findClobber(DefiningAccess, Q);
+    OptimizedAccess = Walker.findClobber(DefiningAccess, Q, UpwardWalkLimit);
     StartingAccess->setOptimized(OptimizedAccess);
     if (MSSA->isLiveOnEntryDef(OptimizedAccess))
       StartingAccess->setOptimizedAccessType(None);
@@ -2311,10 +2351,10 @@ MemorySSA::ClobberWalkerBase<AliasAnalys
 
   MemoryAccess *Result;
   if (SkipSelf && isa<MemoryPhi>(OptimizedAccess) &&
-      isa<MemoryDef>(StartingAccess)) {
+      isa<MemoryDef>(StartingAccess) && UpwardWalkLimit) {
     assert(isa<MemoryDef>(Q.OriginalAccess));
     Q.SkipSelfAccess = true;
-    Result = Walker.findClobber(OptimizedAccess, Q);
+    Result = Walker.findClobber(OptimizedAccess, Q, UpwardWalkLimit);
   } else
     Result = OptimizedAccess;
 

Modified: llvm/trunk/test/Analysis/MemorySSA/optimize-use.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/MemorySSA/optimize-use.ll?rev=357319&r1=357318&r2=357319&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/MemorySSA/optimize-use.ll (original)
+++ llvm/trunk/test/Analysis/MemorySSA/optimize-use.ll Fri Mar 29 14:56:09 2019
@@ -1,5 +1,7 @@
-; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s
-; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>,verify<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s
+; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,NOLIMIT
+; RUN: opt -memssa-check-limit=0 -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,LIMIT
+; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>,verify<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,NOLIMIT
+; RUN: opt -memssa-check-limit=0 -aa-pipeline=basic-aa -passes='print<memoryssa>,verify<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,LIMIT
 
 ; Function Attrs: ssp uwtable
 define i32 @main() {
@@ -18,20 +20,29 @@ entry:
 ; CHECK: 4 = MemoryDef(3)
 ; CHECK-NEXT:   store i32 7, i32* %1, align 4
   store i32 7, i32* %1, align 4
-; CHECK: MemoryUse(3) MustAlias
-; CHECK-NEXT:   %2 = load i32, i32* %0, align 4
+; NOLIMIT: MemoryUse(3) MustAlias
+; NOLIMIT-NEXT:   %2 = load i32, i32* %0, align 4
+; LIMIT: MemoryUse(4) MayAlias
+; LIMIT-NEXT:   %2 = load i32, i32* %0, align 4
   %2 = load i32, i32* %0, align 4
-; CHECK: MemoryUse(4) MustAlias
-; CHECK-NEXT:   %3 = load i32, i32* %1, align 4
+; NOLIMIT: MemoryUse(4) MustAlias
+; NOLIMIT-NEXT:   %3 = load i32, i32* %1, align 4
+; LIMIT: MemoryUse(4) MayAlias
+; LIMIT-NEXT:   %3 = load i32, i32* %1, align 4
   %3 = load i32, i32* %1, align 4
-; CHECK: MemoryUse(3) MustAlias
-; CHECK-NEXT:   %4 = load i32, i32* %0, align 4
+; NOLIMIT: MemoryUse(3) MustAlias
+; NOLIMIT-NEXT:   %4 = load i32, i32* %0, align 4
+; LIMIT: MemoryUse(4) MayAlias
+; LIMIT-NEXT:   %4 = load i32, i32* %0, align 4
   %4 = load i32, i32* %0, align 4
-; CHECK: MemoryUse(4) MustAlias
-; CHECK-NEXT:   %5 = load i32, i32* %1, align 4
+; NOLIMIT: MemoryUse(4) MustAlias
+; NOLIMIT-NEXT:   %5 = load i32, i32* %1, align 4
+; LIMIT: MemoryUse(4) MayAlias
+; LIMIT-NEXT:   %5 = load i32, i32* %1, align 4
   %5 = load i32, i32* %1, align 4
   %add = add nsw i32 %3, %5
   ret i32 %add
 }
 
+
 declare noalias i8* @_Znwm(i64)

Modified: llvm/trunk/test/Analysis/MemorySSA/phi-translation.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/MemorySSA/phi-translation.ll?rev=357319&r1=357318&r2=357319&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/MemorySSA/phi-translation.ll (original)
+++ llvm/trunk/test/Analysis/MemorySSA/phi-translation.ll Fri Mar 29 14:56:09 2019
@@ -1,5 +1,7 @@
-; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s
-; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>,verify<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s
+; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,NOLIMIT
+; RUN: opt -memssa-check-limit=0 -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,LIMIT
+; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>,verify<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,NOLIMIT
+; RUN: opt -memssa-check-limit=0 -aa-pipeline=basic-aa -passes='print<memoryssa>,verify<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,LIMIT
 
 ; %ptr can't alias %local, so we should be able to optimize the use of %local to
 ; point to the store to %local.
@@ -21,8 +23,10 @@ if.then:
 
 if.end:
 ; CHECK: 3 = MemoryPhi({entry,1},{if.then,2})
-; CHECK: MemoryUse(1)
-; CHECK-NEXT: load i8, i8* %local, align 1
+; NOLIMIT: MemoryUse(1) MayAlias
+; NOLIMIT-NEXT: load i8, i8* %local, align 1
+; LIMIT: MemoryUse(3) MayAlias
+; LIMIT-NEXT: load i8, i8* %local, align 1
   load i8, i8* %local, align 1
   ret void
 }
@@ -62,8 +66,10 @@ phi.1:
 ; Order matters here; phi.2 needs to come before phi.3, because that's the order
 ; they're visited in.
 ; CHECK: 6 = MemoryPhi({phi.2,4},{phi.3,3})
-; CHECK: MemoryUse(1)
-; CHECK-NEXT: load i8, i8* %local
+; NOLIMIT: MemoryUse(1) MayAlias
+; NOLIMIT-NEXT: load i8, i8* %local
+; LIMIT: MemoryUse(6) MayAlias
+; LIMIT-NEXT: load i8, i8* %local
   load i8, i8* %local
   ret void
 }
@@ -73,8 +79,10 @@ define void @cross_phi(i8* noalias %p1,
 ; CHECK: 1 = MemoryDef(liveOnEntry)
 ; CHECK-NEXT: store i8 0, i8* %p1
   store i8 0, i8* %p1
-; CHECK: MemoryUse(1)
-; CHECK-NEXT: load i8, i8* %p1
+; NOLIMIT: MemoryUse(1) MustAlias
+; NOLIMIT-NEXT: load i8, i8* %p1
+; LIMIT: MemoryUse(1) MayAlias
+; LIMIT-NEXT: load i8, i8* %p1
   load i8, i8* %p1
   br i1 undef, label %a, label %b
 
@@ -106,8 +114,10 @@ d:
 
 e:
 ; 8 = MemoryPhi({c,4},{d,5})
-; CHECK: MemoryUse(1)
-; CHECK-NEXT: load i8, i8* %p1
+; NOLIMIT: MemoryUse(1) MustAlias
+; NOLIMIT-NEXT: load i8, i8* %p1
+; LIMIT: MemoryUse(8) MayAlias
+; LIMIT-NEXT: load i8, i8* %p1
   load i8, i8* %p1
   ret void
 }
@@ -138,8 +148,10 @@ loop.3:
 ; CHECK: 4 = MemoryDef(7)
 ; CHECK-NEXT: store i8 2, i8* %p2
   store i8 2, i8* %p2
-; CHECK: MemoryUse(1)
-; CHECK-NEXT: load i8, i8* %p1
+; NOLIMIT: MemoryUse(1) MayAlias
+; NOLIMIT-NEXT: load i8, i8* %p1
+; LIMIT: MemoryUse(4) MayAlias
+; LIMIT-NEXT: load i8, i8* %p1
   load i8, i8* %p1
   br i1 undef, label %loop.2, label %loop.1
 }
@@ -167,14 +179,16 @@ if.then2:
 
 if.end:
 ; CHECK: 4 = MemoryPhi({while.cond,5},{if.then,1},{if.then2,2})
-; CHECK: MemoryUse(4)
+; CHECK: MemoryUse(4) MayAlias
 ; CHECK-NEXT: load i8, i8* %p1
   load i8, i8* %p1
 ; CHECK: 3 = MemoryDef(4)
 ; CHECK-NEXT: store i8 2, i8* %p2
   store i8 2, i8* %p2
-; CHECK: MemoryUse(4)
-; CHECK-NEXT: load i8, i8* %p1
+; NOLIMIT: MemoryUse(4) MayAlias
+; NOLIMIT-NEXT: load i8, i8* %p1
+; LIMIT: MemoryUse(3) MayAlias
+; LIMIT-NEXT: load i8, i8* %p1
   load i8, i8* %p1
   br label %while.cond
 }




More information about the llvm-commits mailing list