X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FBasicAliasAnalysis.cpp;h=944d0e0d375669b205f0d67fc56b24bda1ef9fe8;hb=20d6f0982ad33818cfa141f80157ac13e36d5550;hp=8f7fcbf67a8ec2a22fcc17b9ef2730f6bd23f886;hpb=e7275794d399615e8bde0dfb69b02934549e4fb6;p=oota-llvm.git diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index 8f7fcbf67a8..944d0e0d375 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -18,7 +18,6 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" -#include "llvm/ParameterAttributes.h" #include "llvm/GlobalVariable.h" #include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" @@ -32,6 +31,165 @@ #include using namespace llvm; +//===----------------------------------------------------------------------===// +// Useful predicates +//===----------------------------------------------------------------------===// + +// Determine if an AllocationInst instruction escapes from the function it is +// contained in. If it does not escape, there is no way for another function to +// mod/ref it. We do this by looking at its uses and determining if the uses +// can escape (recursively). +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(*UI); + switch (I->getOpcode()) { + case Instruction::Load: + break; //next use. + case Instruction::Store: + if (I->getOperand(0) == V) + return true; // Escapes if the pointer is stored. + break; // next use. + case Instruction::GetElementPtr: + if (AddressMightEscape(I)) + return true; + break; // next use. + case Instruction::BitCast: + if (AddressMightEscape(I)) + return true; + break; // next use + case Instruction::Ret: + // If returned, the address will escape to calling functions, but no + // callees could modify it. + break; // next use + case Instruction::Call: + // If the call is to a few known safe intrinsics, we know that it does + // not escape. + // TODO: Eventually just check the 'nocapture' attribute. + if (!isa(I)) + return true; + break; // next use + default: + return true; + } + } + return false; +} + +static const User *isGEP(const Value *V) { + if (isa(V) || + (isa(V) && + cast(V)->getOpcode() == Instruction::GetElementPtr)) + return cast(V); + return 0; +} + +static const Value *GetGEPOperands(const Value *V, + SmallVector &GEPOps){ + assert(GEPOps.empty() && "Expect empty list to populate!"); + GEPOps.insert(GEPOps.end(), cast(V)->op_begin()+1, + cast(V)->op_end()); + + // Accumulate all of the chained indexes into the operand array + V = cast(V)->getOperand(0); + + while (const User *G = isGEP(V)) { + if (!isa(GEPOps[0]) || isa(GEPOps[0]) || + !cast(GEPOps[0])->isNullValue()) + break; // Don't handle folding arbitrary pointer offsets yet... + GEPOps.erase(GEPOps.begin()); // Drop the zero index + GEPOps.insert(GEPOps.begin(), G->op_begin()+1, G->op_end()); + V = G->getOperand(0); + } + return V; +} + +/// isNoAliasCall - Return true if this pointer is returned by a noalias +/// function. +static bool isNoAliasCall(const Value *V) { + if (isa(V) || isa(V)) + return CallSite(const_cast(cast(V))) + .paramHasAttr(0, Attribute::NoAlias); + return false; +} + +/// isIdentifiedObject - Return true if this pointer refers to a distinct and +/// identifiable object. This returns true for: +/// Global Variables and Functions +/// Allocas and Mallocs +/// ByVal and NoAlias Arguments +/// NoAlias returns +/// +static bool isIdentifiedObject(const Value *V) { + if (isa(V) || isa(V) || isNoAliasCall(V)) + return true; + if (const Argument *A = dyn_cast(V)) + return A->hasNoAliasAttr() || A->hasByValAttr(); + return false; +} + +/// isKnownNonNull - Return true if we know that the specified value is never +/// null. +static bool isKnownNonNull(const Value *V) { + // Alloca never returns null, malloc might. + if (isa(V)) return true; + + // A byval argument is never null. + if (const Argument *A = dyn_cast(V)) + return A->hasByValAttr(); + + // Global values are not null unless extern weak. + if (const GlobalValue *GV = dyn_cast(V)) + return !GV->hasExternalWeakLinkage(); + return false; +} + +/// isNonEscapingLocalObject - Return true if the pointer is to a function-local +/// object that never escapes from the function. +static bool isNonEscapingLocalObject(const Value *V) { + // If this is a local allocation, check to see if it escapes. + if (isa(V) || isNoAliasCall(V)) + return !AddressMightEscape(V); + + // If this is an argument that corresponds to a byval or noalias argument, + // it can't escape either. + if (const Argument *A = dyn_cast(V)) + if (A->hasByValAttr() || A->hasNoAliasAttr()) + return !AddressMightEscape(V); + return false; +} + + +/// isObjectSmallerThan - Return true if we can prove that the object specified +/// by V is smaller than Size. +static bool isObjectSmallerThan(const Value *V, unsigned Size, + const TargetData &TD) { + const Type *AccessTy; + if (const GlobalVariable *GV = dyn_cast(V)) { + AccessTy = GV->getType()->getElementType(); + } else if (const AllocationInst *AI = dyn_cast(V)) { + if (!AI->isArrayAllocation()) + AccessTy = AI->getType()->getElementType(); + else + return false; + } else if (const Argument *A = dyn_cast(V)) { + if (A->hasByValAttr()) + AccessTy = cast(A->getType())->getElementType(); + else + return false; + } else { + return false; + } + + if (AccessTy->isSized()) + return TD.getABITypeSize(AccessTy) < Size; + return false; +} + +//===----------------------------------------------------------------------===// +// NoAA Pass +//===----------------------------------------------------------------------===// + namespace { /// NoAA - This class implements the -no-aa pass, which always returns "I /// don't know" for alias queries. NoAA is unlike other alias analysis @@ -40,8 +198,8 @@ namespace { /// struct VISIBILITY_HIDDEN NoAA : public ImmutablePass, public AliasAnalysis { static char ID; // Class identification, replacement for typeinfo - NoAA() : ImmutablePass((intptr_t)&ID) {} - explicit NoAA(intptr_t PID) : ImmutablePass(PID) { } + NoAA() : ImmutablePass(&ID) {} + explicit NoAA(void *PID) : ImmutablePass(PID) { } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); @@ -91,21 +249,23 @@ static RegisterAnalysisGroup V(U); ImmutablePass *llvm::createNoAAPass() { return new NoAA(); } +//===----------------------------------------------------------------------===// +// BasicAA Pass +//===----------------------------------------------------------------------===// + namespace { /// BasicAliasAnalysis - This is the default alias analysis implementation. /// Because it doesn't chain to a previous alias analysis (like -no-aa), it /// derives from the NoAA class. struct VISIBILITY_HIDDEN BasicAliasAnalysis : public NoAA { static char ID; // Class identification, replacement for typeinfo - BasicAliasAnalysis() : NoAA((intptr_t)&ID) { } + BasicAliasAnalysis() : NoAA(&ID) {} AliasResult alias(const Value *V1, unsigned V1Size, const Value *V2, unsigned V2Size); ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size); - ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) { - return NoAA::getModRefInfo(CS1,CS2); - } - + ModRefResult getModRefInfo(CallSite CS1, CallSite CS2); + /// hasNoModRefInfoForCalls - We can provide mod/ref information against /// non-escaping allocations. virtual bool hasNoModRefInfoForCalls() const { return false; } @@ -138,107 +298,16 @@ ImmutablePass *llvm::createBasicAliasAnalysisPass() { return new BasicAliasAnalysis(); } -/// getUnderlyingObject - This traverses the use chain to figure out what object -/// the specified value points to. If the value points to, or is derived from, -/// a unique object or an argument, return it. This returns: -/// Arguments, GlobalVariables, Functions, Allocas, Mallocs. -static const Value *getUnderlyingObject(const Value *V) { - if (!isa(V->getType())) return V; - - // If we are at some type of object, return it. GlobalValues and Allocations - // have unique addresses. - if (isa(V) || isa(V) || isa(V)) - return V; - - // Traverse through different addressing mechanisms... - if (const Instruction *I = dyn_cast(V)) { - if (isa(I) || isa(I)) - return getUnderlyingObject(I->getOperand(0)); - } else if (const ConstantExpr *CE = dyn_cast(V)) { - if (CE->getOpcode() == Instruction::BitCast || - CE->getOpcode() == Instruction::GetElementPtr) - return getUnderlyingObject(CE->getOperand(0)); - } - return V; -} - -static const User *isGEP(const Value *V) { - if (isa(V) || - (isa(V) && - cast(V)->getOpcode() == Instruction::GetElementPtr)) - return cast(V); - return 0; -} - -static const Value *GetGEPOperands(const Value *V, - SmallVector &GEPOps){ - assert(GEPOps.empty() && "Expect empty list to populate!"); - GEPOps.insert(GEPOps.end(), cast(V)->op_begin()+1, - cast(V)->op_end()); - - // Accumulate all of the chained indexes into the operand array - V = cast(V)->getOperand(0); - - while (const User *G = isGEP(V)) { - if (!isa(GEPOps[0]) || isa(GEPOps[0]) || - !cast(GEPOps[0])->isNullValue()) - break; // Don't handle folding arbitrary pointer offsets yet... - GEPOps.erase(GEPOps.begin()); // Drop the zero index - GEPOps.insert(GEPOps.begin(), G->op_begin()+1, G->op_end()); - V = G->getOperand(0); - } - return V; -} /// pointsToConstantMemory - Chase pointers until we find a (constant /// global) or not. bool BasicAliasAnalysis::pointsToConstantMemory(const Value *P) { if (const GlobalVariable *GV = - dyn_cast(getUnderlyingObject(P))) + dyn_cast(P->getUnderlyingObject())) return GV->isConstant(); return false; } -// Determine if an AllocationInst instruction escapes from the function it is -// contained in. If it does not escape, there is no way for another function to -// mod/ref it. We do this by looking at its uses and determining if the uses -// can escape (recursively). -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(*UI); - switch (I->getOpcode()) { - case Instruction::Load: - break; //next use. - case Instruction::Store: - if (I->getOperand(0) == V) - return true; // Escapes if the pointer is stored. - break; // next use. - case Instruction::GetElementPtr: - if (AddressMightEscape(I)) - return true; - break; // next use. - case Instruction::BitCast: - if (AddressMightEscape(I)) - return true; - break; // next use - case Instruction::Ret: - // If returned, the address will escape to calling functions, but no - // callees could modify it. - break; // next use - case Instruction::Call: - // If the call is to a few known safe intrinsics, we know that it does - // not escape - if (!isa(I)) - return true; - break; // next use - 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 @@ -247,7 +316,7 @@ static bool AddressMightEscape(const Value *V) { AliasAnalysis::ModRefResult BasicAliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) { if (!isa(P)) { - const Value *Object = getUnderlyingObject(P); + const Value *Object = P->getUnderlyingObject(); // If this is a tail call and P points to a stack location, we know that // the tail call cannot access or modify the local stack. @@ -259,27 +328,20 @@ BasicAliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) { if (CI->isTailCall()) return NoModRef; - // Allocations and byval arguments are "new" objects. - if (isa(Object) || isa(Object)) { - // Okay, the pointer is to a stack allocated (or effectively so, for - // for noalias parameters) object. If the address of this object doesn't - // escape from this function body to a callee, then we know that no - // callees can mod/ref it unless they are actually passed it. - if (isa(Object) || - cast(Object)->hasByValAttr() || - cast(Object)->hasNoAliasAttr()) - if (!AddressMightEscape(Object)) { - bool passedAsArg = false; - for (CallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end(); - CI != CE; ++CI) - if (isa((*CI)->getType()) && - (getUnderlyingObject(*CI) == P || - alias(cast(CI), ~0U, P, ~0U) != NoAlias)) - passedAsArg = true; - - if (!passedAsArg) - return NoModRef; - } + // If the pointer is to a locally allocated object that does not escape, + // then the call can not mod/ref the pointer unless the call takes the + // argument without capturing it. + if (isNonEscapingLocalObject(Object)) { + bool passedAsArg = false; + // TODO: Eventually only check 'nocapture' arguments. + for (CallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end(); + CI != CE; ++CI) + if (isa((*CI)->getType()) && + alias(cast(CI), ~0U, P, ~0U) != NoAlias) + passedAsArg = true; + + if (!passedAsArg) + return NoModRef; } } @@ -287,73 +349,25 @@ BasicAliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) { return AliasAnalysis::getModRefInfo(CS, P, Size); } -/// isIdentifiedObject - Return true if this pointer refers to a distinct and -/// identifiable object. This returns true for: -/// Global Variables and Functions -/// Allocas and Mallocs -/// ByVal and NoAlias Arguments -/// -static bool isIdentifiedObject(const Value *V) { - if (isa(V) || isa(V)) - return true; - if (const Argument *A = dyn_cast(V)) - return A->hasNoAliasAttr() || A->hasByValAttr(); - return false; -} -/// isKnownNonNull - Return true if we know that the specified value is never -/// null. -static bool isKnownNonNull(const Value *V) { - // Alloca never returns null, malloc might. - if (isa(V)) return true; +AliasAnalysis::ModRefResult +BasicAliasAnalysis::getModRefInfo(CallSite CS1, CallSite CS2) { + // If CS1 or CS2 are readnone, they don't interact. + ModRefBehavior CS1B = AliasAnalysis::getModRefBehavior(CS1); + if (CS1B == DoesNotAccessMemory) return NoModRef; - // A byval argument is never null. - if (const Argument *A = dyn_cast(V)) - return A->hasByValAttr(); - - // Global values are not null unless extern weak. - if (const GlobalValue *GV = dyn_cast(V)) - return !GV->hasExternalWeakLinkage(); - return false; -} - -/// isNonEscapingLocalObject - Return true if the pointer is to a function-local -/// object that never escapes from the function. -static bool isNonEscapingLocalObject(const Value *V) { - // If this is a local allocation, check to see if it escapes. - if (isa(V)) - return !AddressMightEscape(V); - - // If this is an argument that corresponds to a byval or noalias argument, - // it can't escape either. - if (const Argument *A = dyn_cast(V)) - if (A->hasByValAttr() || A->hasNoAliasAttr()) - return !AddressMightEscape(V); - return false; -} - - -/// isObjectSmallerThan - Return true if we can prove that the object specified -/// by V is smaller than Size. -static bool isObjectSmallerThan(const Value *V, unsigned Size, - const TargetData &TD) { - const Type *AccessTy = 0; - if (const GlobalVariable *GV = dyn_cast(V)) - AccessTy = GV->getType()->getElementType(); + ModRefBehavior CS2B = AliasAnalysis::getModRefBehavior(CS2); + if (CS2B == DoesNotAccessMemory) return NoModRef; - if (const AllocationInst *AI = dyn_cast(V)) - if (!AI->isArrayAllocation()) - AccessTy = AI->getType()->getElementType(); - - if (const Argument *A = dyn_cast(V)) - if (A->hasByValAttr()) - AccessTy = cast(A->getType())->getElementType(); + // If they both only read from memory, just return ref. + if (CS1B == OnlyReadsMemory && CS2B == OnlyReadsMemory) + return Ref; - if (AccessTy && AccessTy->isSized()) - return TD.getABITypeSize(AccessTy) < Size; - return false; + // Otherwise, fall back to NoAA (mod+ref). + return NoAA::getModRefInfo(CS1, CS2); } + // 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. :) @@ -372,8 +386,7 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size, // Are we checking for alias of the same value? if (V1 == V2) return MustAlias; - if ((!isa(V1->getType()) || !isa(V2->getType())) && - V1->getType() != Type::Int64Ty && V2->getType() != Type::Int64Ty) + if (!isa(V1->getType()) || !isa(V2->getType())) return NoAlias; // Scalars cannot alias each other // Strip off cast instructions... @@ -383,19 +396,19 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size, return alias(V1, V1Size, I->getOperand(0), V2Size); // Figure out what objects these things are pointing to if we can... - const Value *O1 = getUnderlyingObject(V1); - const Value *O2 = getUnderlyingObject(V2); + const Value *O1 = V1->getUnderlyingObject(); + const Value *O2 = V2->getUnderlyingObject(); if (O1 != O2) { // If V1/V2 point to two different objects we know that we have no alias. if (isIdentifiedObject(O1) && isIdentifiedObject(O2)) return NoAlias; - // Incoming argument cannot alias locally allocated object! - if ((isa(O1) && isa(O2)) || - (isa(O2) && isa(O1))) + // Arguments can't alias with local allocations or noalias calls. + if ((isa(O1) && (isa(O2) || isNoAliasCall(O2))) || + (isa(O2) && (isa(O1) || isNoAliasCall(O1)))) return NoAlias; - + // Most objects can't alias null. if ((isa(V2) && isKnownNonNull(O1)) || (isa(V1) && isKnownNonNull(O2))) @@ -533,7 +546,7 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size, return MayAlias; } -// This function is used to determin if the indices of two GEP instructions are +// This function is used to determine if the indices of two GEP instructions are // equal. V1 and V2 are the indices. static bool IndexOperandsEqual(Value *V1, Value *V2) { if (V1->getType() == V2->getType())