diff options
-rw-r--r-- | lib/Analysis/BasicAliasAnalysis.cpp | 7 | ||||
-rw-r--r-- | lib/Analysis/MemoryDependenceAnalysis.cpp | 27 | ||||
-rw-r--r-- | test/Analysis/BasicAA/getmodrefinfo-cs-cs.ll | 1 |
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() |