diff options
author | Chris Lattner <sabre@nondot.org> | 2004-03-12 22:39:00 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-03-12 22:39:00 +0000 |
commit | 04b75935462642641469fb264aab9f1110ce2666 (patch) | |
tree | 8692e009af5c1e5acad9d2e790ef1434c15ef10e /lib/Analysis | |
parent | 130608905527299186c424c86cb385ec1b1a3335 (diff) | |
download | external_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.cpp | 52 |
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. :) |