aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 6bb84d4..11cba99 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 e97bc3b..e003d64 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 953eaa8..f655913 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()