summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/BasicAliasAnalysis.cpp
diff options
context:
space:
mode:
authorIgor Laevsky <igmyrj@gmail.com>2017-03-01 13:19:51 +0000
committerIgor Laevsky <igmyrj@gmail.com>2017-03-01 13:19:51 +0000
commit37cba4360491e73492b686ee4ded55abf90b7282 (patch)
tree14d181b9bc9ac349a7d2acceb06dce8942816692 /llvm/lib/Analysis/BasicAliasAnalysis.cpp
parent9e745b729280d9d5f2a5e2871a0cdb40ed74cddd (diff)
downloadbcm5719-llvm-37cba4360491e73492b686ee4ded55abf90b7282.tar.gz
bcm5719-llvm-37cba4360491e73492b686ee4ded55abf90b7282.zip
[BasicAA] Take attributes into account when requesting modref info for a call site
Differential Revision: https://reviews.llvm.org/D29989 llvm-svn: 296617
Diffstat (limited to 'llvm/lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/BasicAliasAnalysis.cpp40
1 files changed, 31 insertions, 9 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 55f40a34839..d3898aad8a7 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -749,7 +749,11 @@ ModRefInfo BasicAAResult::getModRefInfo(ImmutableCallSite CS,
// as an argument, and itself doesn't capture it.
if (!isa<Constant>(Object) && CS.getInstruction() != Object &&
isNonEscapingLocalObject(Object)) {
- bool PassedAsArg = false;
+
+ // Optimistically assume that call doesn't touch Object and check this
+ // assumption in the following loop.
+ ModRefInfo Result = MRI_NoModRef;
+
unsigned OperandNo = 0;
for (auto CI = CS.data_operands_begin(), CE = CS.data_operands_end();
CI != CE; ++CI, ++OperandNo) {
@@ -761,20 +765,38 @@ ModRefInfo BasicAAResult::getModRefInfo(ImmutableCallSite CS,
OperandNo < CS.getNumArgOperands() && !CS.isByValArgument(OperandNo)))
continue;
+ // Call doesn't access memory through this operand, so we don't care
+ // if it aliases with Object.
+ if (CS.doesNotAccessMemory(OperandNo))
+ continue;
+
// If this is a no-capture pointer argument, see if we can tell that it
- // is impossible to alias the pointer we're checking. If not, we have to
- // assume that the call could touch the pointer, even though it doesn't
- // escape.
+ // is impossible to alias the pointer we're checking.
AliasResult AR =
getBestAAResults().alias(MemoryLocation(*CI), MemoryLocation(Object));
- if (AR) {
- PassedAsArg = true;
- break;
+
+ // Operand doesnt alias 'Object', continue looking for other aliases
+ if (AR == NoAlias)
+ continue;
+ // Operand aliases 'Object', but call doesn't modify it. Strengthen
+ // initial assumption and keep looking in case if there are more aliases.
+ if (CS.onlyReadsMemory(OperandNo)) {
+ Result = static_cast<ModRefInfo>(Result | MRI_Ref);
+ continue;
+ }
+ // Operand aliases 'Object' but call only writes into it.
+ if (CS.doesNotReadMemory(OperandNo)) {
+ Result = static_cast<ModRefInfo>(Result | MRI_Mod);
+ continue;
}
+ // This operand aliases 'Object' and call reads and writes into it.
+ Result = MRI_ModRef;
+ break;
}
- if (!PassedAsArg)
- return MRI_NoModRef;
+ // Early return if we improved mod ref information
+ if (Result != MRI_ModRef)
+ return Result;
}
// If the CallSite is to malloc or calloc, we can assume that it doesn't
OpenPOWER on IntegriCloud