[EarlyCSE] Make MemorySSA memory dependency check more aggressive.
authorGeoff Berry <gberry@codeaurora.org>
Tue, 25 Oct 2016 16:18:47 +0000 (16:18 +0000)
committerGeoff Berry <gberry@codeaurora.org>
Tue, 25 Oct 2016 16:18:47 +0000 (16:18 +0000)
Now that MemorySSA keeps track of whether MemoryUses are optimized, use
getClobberingMemoryAccess() to check MemoryUse memory dependencies since
it should no longer be so expensive.

This is a follow-up change to https://reviews.llvm.org/D25881

llvm-svn: 285080

llvm/lib/Transforms/Scalar/EarlyCSE.cpp
llvm/test/Transforms/EarlyCSE/memoryssa.ll

index 5f88460..9bf638d 100644 (file)
@@ -496,12 +496,11 @@ private:
   void removeMSSA(Instruction *Inst) {
     if (!MSSA)
       return;
-    // FIXME: Removing a store here can leave MemorySSA in an unoptimized state
-    // by creating MemoryPhis that have identical arguments and by creating
+    // Removing a store here can leave MemorySSA in an unoptimized state by
+    // creating MemoryPhis that have identical arguments and by creating
     // MemoryUses whose defining access is not an actual clobber.  We handle the
-    // phi case here, but the non-optimized MemoryUse case is not handled.  Once
-    // MemorySSA tracks whether uses are optimized this will be taken care of on
-    // the MemorySSA side.
+    // phi case eagerly here.  The non-optimized MemoryUse case is lazily
+    // updated by MemorySSA getClobberingMemoryAccess.
     if (MemoryAccess *MA = MSSA->getMemoryAccess(Inst)) {
       // Optimize MemoryPhi nodes that may become redundant by having all the
       // same input values once MA is removed.
@@ -564,17 +563,8 @@ bool EarlyCSE::isSameMemGeneration(unsigned EarlierGeneration,
   // LaterInst, if LaterDef dominates EarlierInst then it can't occur between
   // EarlierInst and LaterInst and neither can any other write that potentially
   // clobbers LaterInst.
-  // FIXME: Use getClobberingMemoryAccess only for stores since it is currently
-  // fairly expensive to call on MemoryUses since it does an AA check even for
-  // MemoryUses that were already optimized by MemorySSA construction.  Once
-  // MemorySSA optimized use tracking change has been committed we can use
-  // getClobberingMemoryAccess for MemoryUses as well.
-  MemoryAccess *LaterMA = MSSA->getMemoryAccess(LaterInst);
-  MemoryAccess *LaterDef;
-  if (auto *LaterUse = dyn_cast<MemoryUse>(LaterMA))
-    LaterDef = LaterUse->getDefiningAccess();
-  else
-    LaterDef = MSSA->getWalker()->getClobberingMemoryAccess(LaterInst);
+  MemoryAccess *LaterDef =
+      MSSA->getWalker()->getClobberingMemoryAccess(LaterInst);
   return MSSA->dominates(LaterDef, MSSA->getMemoryAccess(EarlierInst));
 }
 
index 9c7f64a..1c10efe 100644 (file)
@@ -5,6 +5,7 @@
 
 @G1 = global i32 zeroinitializer
 @G2 = global i32 zeroinitializer
+@G3 = global i32 zeroinitializer
 
 ;; Simple load value numbering across non-clobbering store.
 ; CHECK-LABEL: @test1(
@@ -67,3 +68,41 @@ end:
   store i32 %sum, i32* @G2
   ret void
 }
+
+
+;; Check that MemoryPhi optimization and MemoryUse re-optimization
+;; happens during EarlyCSE, enabling more load CSE opportunities.
+; CHECK-LABEL: @test_memphiopt2(
+; CHECK-NOMEMSSA-LABEL: @test_memphiopt2(
+define void @test_memphiopt2(i1 %c, i32* %p) {
+; CHECK-LABEL: entry:
+; CHECK-NOMEMSSA-LABEL: entry:
+entry:
+; CHECK: load
+; CHECK-NOMEMSSA: load
+  %v1 = load i32, i32* @G1
+; CHECK: store
+; CHECK-NOMEMSSA: store
+  store i32 %v1, i32* @G2
+  br i1 %c, label %then, label %end
+
+; CHECK-LABEL: then:
+; CHECK-NOMEMSSA-LABEL: then:
+then:
+; CHECK: load
+; CHECK-NOMEMSSA: load
+  %pv = load i32, i32* %p
+; CHECK-NOT: store
+; CHECK-NOMEMSSA-NOT: store
+  store i32 %pv, i32* %p
+  br label %end
+
+; CHECK-LABEL: end:
+; CHECK-NOMEMSSA-LABEL: end:
+end:
+; CHECK-NOT: load
+; CHECK-NOMEMSSA: load
+  %v2 = load i32, i32* @G1
+  store i32 %v2, i32* @G3
+  ret void
+}