aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-03-12 22:39:00 +0000
committerChris Lattner <sabre@nondot.org>2004-03-12 22:39:00 +0000
commit04b75935462642641469fb264aab9f1110ce2666 (patch)
tree8692e009af5c1e5acad9d2e790ef1434c15ef10e /lib/Analysis
parent130608905527299186c424c86cb385ec1b1a3335 (diff)
downloadexternal_llvm-04b75935462642641469fb264aab9f1110ce2666.zip
external_llvm-04b75935462642641469fb264aab9f1110ce2666.tar.gz
external_llvm-04b75935462642641469fb264aab9f1110ce2666.tar.bz2
Implement mod/ref analysis for a trivial case where locals don't escape.
This comes up when you have a local array on the stack and you never pass the address of elements around. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12349 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/BasicAliasAnalysis.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp
index 16bb53f..617ae55 100644
--- a/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/lib/Analysis/BasicAliasAnalysis.cpp
@@ -47,6 +47,8 @@ namespace {
AliasResult alias(const Value *V1, unsigned V1Size,
const Value *V2, unsigned V2Size);
+ ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
+
/// pointsToConstantMemory - Chase pointers until we find a (constant
/// global) or not.
bool pointsToConstantMemory(const Value *P);
@@ -139,6 +141,56 @@ bool BasicAliasAnalysis::pointsToConstantMemory(const Value *P) {
return false;
}
+static bool AddressMightEscape(const Value *V) {
+ for (Value::use_const_iterator UI = V->use_begin(), E = V->use_end();
+ UI != E; ++UI) {
+ const Instruction *I = cast<Instruction>(*UI);
+ switch (I->getOpcode()) {
+ case Instruction::Load: break;
+ case Instruction::Store:
+ if (I->getOperand(0) == V)
+ return true; // Escapes if the pointer is stored.
+ break;
+ case Instruction::GetElementPtr:
+ if (AddressMightEscape(I)) return true;
+ break;
+ case Instruction::Cast:
+ if (!isa<PointerType>(I->getType()))
+ return true;
+ if (AddressMightEscape(I)) return true;
+ break;
+ case Instruction::PHI:
+ if (AddressMightEscape(I)) return true;
+ break;
+ default:
+ return true;
+ }
+ }
+ return false;
+}
+
+// getModRefInfo - Check to see if the specified callsite can clobber the
+// specified memory object. Since we only look at local properties of this
+// function, we really can't say much about this query. We do, however, use
+// simple "address taken" analysis on local objects.
+//
+AliasAnalysis::ModRefResult
+BasicAliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
+ if (!isa<Constant>(P) && !isa<GlobalValue>(P))
+ if (const AllocationInst *AI =
+ dyn_cast<AllocationInst>(getUnderlyingObject(P))) {
+ // Okay, the pointer is to a stack allocated object. If we can prove that
+ // the pointer never "escapes", then we know the call cannot clobber it,
+ // because it simply can't get its address.
+ if (!AddressMightEscape(AI))
+ return NoModRef;
+ }
+
+ // If P points to a constant memory location, the call definitely could not
+ // modify the memory location.
+ return pointsToConstantMemory(P) ? Ref : ModRef;
+}
+
// alias - Provide a bunch of ad-hoc rules to disambiguate in common cases, such
// as array references. Note that this function is heavily tail recursive.
// Hopefully we have a smart C++ compiler. :)