aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2010-08-05 22:09:15 +0000
committerDan Gohman <gohman@apple.com>2010-08-05 22:09:15 +0000
commit5fa417c7904f7394d4e6dcb86e366c86867bcb5a (patch)
tree68a0821883973c55b5f4f210abc85726e4ec50c1
parent3ecf355c7a6f6f559f3c85b46d041ffda5163a8c (diff)
Fix memdep's code for reasoning about dependences between two calls. A Ref
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
-rw-r--r--lib/Analysis/BasicAliasAnalysis.cpp7
-rw-r--r--lib/Analysis/MemoryDependenceAnalysis.cpp27
-rw-r--r--test/Analysis/BasicAA/getmodrefinfo-cs-cs.ll1
3 files changed, 14 insertions, 21 deletions
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp
index 6bb84d4e45..11cba991a9 100644
--- a/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/lib/Analysis/BasicAliasAnalysis.cpp
@@ -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).
diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp
index e97bc3b672..e003d64369 100644
--- a/lib/Analysis/MemoryDependenceAnalysis.cpp
+++ b/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -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);
}
diff --git a/test/Analysis/BasicAA/getmodrefinfo-cs-cs.ll b/test/Analysis/BasicAA/getmodrefinfo-cs-cs.ll
index 953eaa847d..f655913f3d 100644
--- a/test/Analysis/BasicAA/getmodrefinfo-cs-cs.ll
+++ b/test/Analysis/BasicAA/getmodrefinfo-cs-cs.ll
@@ -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()