Make GVN able to remove unnecessary calls to read-only functions again.
authorOwen Anderson <resistor@mac.com>
Thu, 17 Apr 2008 05:36:50 +0000 (05:36 +0000)
committerOwen Anderson <resistor@mac.com>
Thu, 17 Apr 2008 05:36:50 +0000 (05:36 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49842 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/MemoryDependenceAnalysis.cpp
lib/Transforms/Scalar/GVN.cpp
test/Analysis/BasicAA/const-dce.ll [deleted file]
test/Analysis/BasicAA/pure-const-dce.ll [new file with mode: 0644]

index 314d6e4b3a7e0e995a731ac76c14e2f7dd3384d9..161c2fed1c7112658c13715a9355be3746fea86d 100644 (file)
@@ -134,8 +134,7 @@ Instruction* MemoryDependenceAnalysis::getCallSiteDependency(CallSite C,
     } else if (isa<CallInst>(QI)) {
       AliasAnalysis::ModRefBehavior result =
                    AA.getModRefBehavior(CallSite::get(QI));
-      if (result != AliasAnalysis::DoesNotAccessMemory &&
-          result != AliasAnalysis::OnlyReadsMemory) {
+      if (result != AliasAnalysis::DoesNotAccessMemory) {
         if (!start && !block) {
           cachedResult.first = QI;
           cachedResult.second = true;
index b33d3af31fca242fcb760b82d2f3de532a894405..bd360520a701d119e56bbad2acbeaf4981352120 100644 (file)
@@ -135,6 +135,7 @@ namespace {
       DenseMap<Value*, uint32_t> valueNumbering;
       DenseMap<Expression, uint32_t> expressionNumbering;
       AliasAnalysis* AA;
+      MemoryDependenceAnalysis* MD;
   
       uint32_t nextValueNumber;
     
@@ -159,6 +160,7 @@ namespace {
       void erase(Value* v);
       unsigned size();
       void setAliasAnalysis(AliasAnalysis* A) { AA = A; }
+      void setMemDep(MemoryDependenceAnalysis* M) { MD = M; }
   };
 }
 
@@ -432,6 +434,33 @@ uint32_t ValueTable::lookup_or_add(Value* V) {
       
         return nextValueNumber++;
       }
+    } else if (AA->onlyReadsMemory(C)) {
+      Expression e = create_expression(C);
+      
+      Instruction* dep = MD->getDependency(C);
+      
+      if (dep == MemoryDependenceAnalysis::NonLocal ||
+          !isa<CallInst>(dep)) {
+        expressionNumbering.insert(std::make_pair(e, nextValueNumber));
+        valueNumbering.insert(std::make_pair(V, nextValueNumber));
+      
+        return nextValueNumber++;
+      }
+      
+      CallInst* cdep = cast<CallInst>(dep);
+      Expression d_exp = create_expression(cdep);
+      
+      if (e != d_exp) {
+        expressionNumbering.insert(std::make_pair(e, nextValueNumber));
+        valueNumbering.insert(std::make_pair(V, nextValueNumber));
+      
+        return nextValueNumber++;
+      } else {
+        uint32_t v = expressionNumbering[d_exp];
+        valueNumbering.insert(std::make_pair(V, v));
+        return v;
+      }
+      
     } else {
       valueNumbering.insert(std::make_pair(V, nextValueNumber));
       return nextValueNumber++;
@@ -993,22 +1022,6 @@ bool GVN::processInstruction(Instruction *I, ValueNumberedSet &currAvail,
   } else if (currAvail.test(num)) {
     Value* repl = find_leader(currAvail, num);
     
-    if (CallInst* CI = dyn_cast<CallInst>(I)) {
-      AliasAnalysis& AA = getAnalysis<AliasAnalysis>();
-      if (!AA.doesNotAccessMemory(CI)) {
-        MemoryDependenceAnalysis& MD = getAnalysis<MemoryDependenceAnalysis>();
-        if (cast<Instruction>(repl)->getParent() != CI->getParent() ||
-            MD.getDependency(CI) != MD.getDependency(cast<CallInst>(repl))) {
-          // There must be an intervening may-alias store, so nothing from
-          // this point on will be able to be replaced with the preceding call
-          currAvail.erase(repl);
-          currAvail.insert(I);
-          
-          return false;
-        }
-      }
-    }
-    
     // Remove it!
     MemoryDependenceAnalysis& MD = getAnalysis<MemoryDependenceAnalysis>();
     MD.removeInstruction(I);
@@ -1030,6 +1043,7 @@ bool GVN::processInstruction(Instruction *I, ValueNumberedSet &currAvail,
 //
 bool GVN::runOnFunction(Function& F) {
   VN.setAliasAnalysis(&getAnalysis<AliasAnalysis>());
+  VN.setMemDep(&getAnalysis<MemoryDependenceAnalysis>());
   
   bool changed = false;
   bool shouldContinue = true;
diff --git a/test/Analysis/BasicAA/const-dce.ll b/test/Analysis/BasicAA/const-dce.ll
deleted file mode 100644 (file)
index dcde914..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestConst | count 2
-; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestPure  | count 4
-; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestNone  | count 4
-@g = global i32 0              ; <i32*> [#uses=1]
-
-define i32 @test() {
-entry:
-       %tmp0 = call i32 @TestConst( i32 5 ) readnone           ; <i32> [#uses=1]
-       %tmp1 = call i32 @TestPure( i32 6 ) readonly            ; <i32> [#uses=1]
-       %tmp2 = call i32 @TestNone( i32 7 )             ; <i32> [#uses=1]
-       store i32 1, i32* @g
-       %tmp3 = call i32 @TestConst( i32 5 ) readnone           ; <i32> [#uses=1]
-       %tmp4 = call i32 @TestConst( i32 5 ) readnone           ; <i32> [#uses=1]
-       %tmp5 = call i32 @TestPure( i32 6 ) readonly            ; <i32> [#uses=1]
-       %tmp6 = call i32 @TestPure( i32 6 ) readonly            ; <i32> [#uses=1]
-       %tmp7 = call i32 @TestNone( i32 7 )             ; <i32> [#uses=1]
-       %tmp8 = call i32 @TestNone( i32 7 )             ; <i32> [#uses=1]
-       %sum0 = add i32 %tmp0, %tmp1            ; <i32> [#uses=1]
-       %sum1 = add i32 %sum0, %tmp2            ; <i32> [#uses=1]
-       %sum2 = add i32 %sum1, %tmp3            ; <i32> [#uses=1]
-       %sum3 = add i32 %sum2, %tmp4            ; <i32> [#uses=1]
-       %sum4 = add i32 %sum3, %tmp5            ; <i32> [#uses=1]
-       %sum5 = add i32 %sum4, %tmp6            ; <i32> [#uses=1]
-       %sum6 = add i32 %sum5, %tmp7            ; <i32> [#uses=1]
-       %sum7 = add i32 %sum6, %tmp8            ; <i32> [#uses=1]
-       ret i32 %sum7
-}
-
-declare i32 @TestConst(i32) readnone
-
-declare i32 @TestPure(i32) readonly
-
-declare i32 @TestNone(i32)
diff --git a/test/Analysis/BasicAA/pure-const-dce.ll b/test/Analysis/BasicAA/pure-const-dce.ll
new file mode 100644 (file)
index 0000000..b01b5c5
--- /dev/null
@@ -0,0 +1,33 @@
+; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestConst | count 2
+; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestPure  | count 3
+; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestNone  | count 4
+@g = global i32 0              ; <i32*> [#uses=1]
+
+define i32 @test() {
+entry:
+       %tmp0 = call i32 @TestConst( i32 5 ) readnone           ; <i32> [#uses=1]
+       %tmp1 = call i32 @TestPure( i32 6 ) readonly            ; <i32> [#uses=1]
+       %tmp2 = call i32 @TestNone( i32 7 )             ; <i32> [#uses=1]
+       store i32 1, i32* @g
+       %tmp3 = call i32 @TestConst( i32 5 ) readnone           ; <i32> [#uses=1]
+       %tmp4 = call i32 @TestConst( i32 5 ) readnone           ; <i32> [#uses=1]
+       %tmp5 = call i32 @TestPure( i32 6 ) readonly            ; <i32> [#uses=1]
+       %tmp6 = call i32 @TestPure( i32 6 ) readonly            ; <i32> [#uses=1]
+       %tmp7 = call i32 @TestNone( i32 7 )             ; <i32> [#uses=1]
+       %tmp8 = call i32 @TestNone( i32 7 )             ; <i32> [#uses=1]
+       %sum0 = add i32 %tmp0, %tmp1            ; <i32> [#uses=1]
+       %sum1 = add i32 %sum0, %tmp2            ; <i32> [#uses=1]
+       %sum2 = add i32 %sum1, %tmp3            ; <i32> [#uses=1]
+       %sum3 = add i32 %sum2, %tmp4            ; <i32> [#uses=1]
+       %sum4 = add i32 %sum3, %tmp5            ; <i32> [#uses=1]
+       %sum5 = add i32 %sum4, %tmp6            ; <i32> [#uses=1]
+       %sum6 = add i32 %sum5, %tmp7            ; <i32> [#uses=1]
+       %sum7 = add i32 %sum6, %tmp8            ; <i32> [#uses=1]
+       ret i32 %sum7
+}
+
+declare i32 @TestConst(i32) readnone
+
+declare i32 @TestPure(i32) readonly
+
+declare i32 @TestNone(i32)