Fix memdep's code for reasoning about dependences between two calls. A Ref
authorDan Gohman <gohman@apple.com>
Thu, 5 Aug 2010 22:09:15 +0000 (22:09 +0000)
committerDan Gohman <gohman@apple.com>
Thu, 5 Aug 2010 22:09:15 +0000 (22:09 +0000)
response from getModRefInfo is not useful here. Instead, check for identical
calls only in the NoModRef case.

Reapply r110270, and strengthen it to compensate for the memdep changes.
When both calls are readonly, there is no dependence between them.

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

lib/Analysis/BasicAliasAnalysis.cpp
lib/Analysis/MemoryDependenceAnalysis.cpp
test/Analysis/BasicAA/getmodrefinfo-cs-cs.ll

index 6bb84d4e458b6a2d2efedee37c206ebc4675c379..11cba991a951b4790a0c9ac4bbfca39153173d6c 100644 (file)
@@ -425,8 +425,13 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
   ModRefBehavior CS2B = AliasAnalysis::getModRefBehavior(CS2);
   if (CS2B == DoesNotAccessMemory) return NoModRef;
   
-  // If they both only read from memory, just return ref.
+  // If they both only read from memory, there is no dependence.
   if (CS1B == OnlyReadsMemory && CS2B == OnlyReadsMemory)
+    return NoModRef;
+
+  // If CS1 only reads memory, the only dependence on CS2 can be
+  // from CS1 reading memory written by CS2.
+  if (CS1B == OnlyReadsMemory)
     return Ref;
   
   // Otherwise, fall back to NoAA (mod+ref).
index e97bc3b6727c6e8de3ca0b98a1a053cf9ca0cb3a..e003d643691231cce97f760b468cda724b96f0c4 100644 (file)
@@ -126,26 +126,15 @@ getCallSiteDependencyFrom(CallSite CS, bool isReadOnlyCall,
       // If these two calls do not interfere, look past it.
       switch (AA->getModRefInfo(CS, InstCS)) {
       case AliasAnalysis::NoModRef:
-        // If the two calls don't interact (e.g. InstCS is readnone) keep
-        // scanning.
+        // If the two calls are the same, return InstCS as a Def, so that
+        // CS can be found redundant and eliminated.
+        if (isReadOnlyCall && InstCS.onlyReadsMemory() &&
+            CS.getInstruction()->isIdenticalToWhenDefined(Inst))
+          return MemDepResult::getDef(Inst);
+
+        // Otherwise if the two calls don't interact (e.g. InstCS is readnone)
+        // keep scanning.
         continue;
-      case AliasAnalysis::Ref:
-        // If the two calls read the same memory locations and CS is a readonly
-        // function, then we have two cases: 1) the calls may not interfere with
-        // each other at all.  2) the calls may produce the same value.  In case
-        // #1 we want to ignore the values, in case #2, we want to return Inst
-        // as a Def dependence.  This allows us to CSE in cases like:
-        //   X = strlen(P);
-        //    memchr(...);
-        //   Y = strlen(P);  // Y = X
-        if (isReadOnlyCall) {
-          if (CS.getCalledFunction() != 0 &&
-              CS.getCalledFunction() == InstCS.getCalledFunction())
-            return MemDepResult::getDef(Inst);
-          // Ignore unrelated read/read call dependences.
-          continue;
-        }
-        // FALL THROUGH
       default:
         return MemDepResult::getClobber(Inst);
       }
index 953eaa847d1e45fc81dbc1d1207dcde691042f1d..f655913f3d129c7a5c4b60d81b60410b9178923d 100644 (file)
@@ -1,5 +1,4 @@
 ; RUN: opt < %s -aa-eval -print-all-alias-modref-info -disable-output |& FileCheck %s
-; XFAIL: *
 
 ; CHECK: Just Ref: call void @ro() <-> call void @f0()