X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FAliasAnalysis.cpp;h=588d68da33bfb9a207e2b5cb92e20c5851d54659;hb=12bf43bc4f86602a5677d5e1662cb4e40562351b;hp=cfe6f5e68afaf92d3c30a2cb4ec4a7259cea4652;hpb=f9355f636b6a7d59993081766dd0481bd08f545d;p=oota-llvm.git diff --git a/lib/Analysis/AliasAnalysis.cpp b/lib/Analysis/AliasAnalysis.cpp index cfe6f5e68af..588d68da33b 100644 --- a/lib/Analysis/AliasAnalysis.cpp +++ b/lib/Analysis/AliasAnalysis.cpp @@ -1,5 +1,12 @@ //===- AliasAnalysis.cpp - Generic Alias Analysis Interface Implementation -==// // +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// // This file implements the generic AliasAnalysis interface which is used as the // common interface used by all clients and implementations of alias analysis. // @@ -17,42 +24,266 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Analysis/BasicAliasAnalysis.h" -#include "llvm/BasicBlock.h" -#include "llvm/Support/InstVisitor.h" -#include "llvm/iMemory.h" -#include "llvm/Constants.h" -#include "llvm/GlobalValue.h" -#include "llvm/DerivedTypes.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Pass.h" +#include "llvm/BasicBlock.h" +#include "llvm/Function.h" +#include "llvm/IntrinsicInst.h" +#include "llvm/Instructions.h" +#include "llvm/LLVMContext.h" +#include "llvm/Type.h" +#include "llvm/Target/TargetData.h" +using namespace llvm; // Register the AliasAnalysis interface, providing a nice name to refer to. -static RegisterAnalysisGroup X("Alias Analysis"); +INITIALIZE_ANALYSIS_GROUP(AliasAnalysis, "Alias Analysis", NoAA) +char AliasAnalysis::ID = 0; -// CanModify - Define a little visitor class that is used to check to see if -// arbitrary chunks of code can modify a specified pointer. -// -namespace { - struct CanModify : public InstVisitor { - const AliasAnalysis &AA; - const Value *Ptr; +//===----------------------------------------------------------------------===// +// Default chaining methods +//===----------------------------------------------------------------------===// + +AliasAnalysis::AliasResult +AliasAnalysis::alias(const Location &LocA, const Location &LocB) { + assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); + return AA->alias(LocA, LocB); +} + +bool AliasAnalysis::pointsToConstantMemory(const Location &Loc, + bool OrLocal) { + assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); + return AA->pointsToConstantMemory(Loc, OrLocal); +} + +void AliasAnalysis::deleteValue(Value *V) { + assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); + AA->deleteValue(V); +} + +void AliasAnalysis::copyValue(Value *From, Value *To) { + assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); + AA->copyValue(From, To); +} + +AliasAnalysis::ModRefResult +AliasAnalysis::getModRefInfo(ImmutableCallSite CS, + const Location &Loc) { + assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); + + ModRefBehavior MRB = getModRefBehavior(CS); + if (MRB == DoesNotAccessMemory) + return NoModRef; + + ModRefResult Mask = ModRef; + if (onlyReadsMemory(MRB)) + Mask = Ref; + + if (onlyAccessesArgPointees(MRB)) { + bool doesAlias = false; + if (doesAccessArgPointees(MRB)) + for (ImmutableCallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end(); + AI != AE; ++AI) + if (!isNoAlias(Location(*AI), Loc)) { + doesAlias = true; + break; + } + + if (!doesAlias) + return NoModRef; + } + + // If Loc is a constant memory location, the call definitely could not + // modify the memory location. + if ((Mask & Mod) && pointsToConstantMemory(Loc)) + Mask = ModRefResult(Mask & ~Mod); + + // If this is the end of the chain, don't forward. + if (!AA) return Mask; + + // Otherwise, fall back to the next AA in the chain. But we can merge + // in any mask we've managed to compute. + return ModRefResult(AA->getModRefInfo(CS, Loc) & Mask); +} + +AliasAnalysis::ModRefResult +AliasAnalysis::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) { + assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); + + // If CS1 or CS2 are readnone, they don't interact. + ModRefBehavior CS1B = getModRefBehavior(CS1); + if (CS1B == DoesNotAccessMemory) return NoModRef; + + ModRefBehavior CS2B = getModRefBehavior(CS2); + if (CS2B == DoesNotAccessMemory) return NoModRef; + + // If they both only read from memory, there is no dependence. + if (onlyReadsMemory(CS1B) && onlyReadsMemory(CS2B)) + return NoModRef; + + AliasAnalysis::ModRefResult Mask = ModRef; + + // If CS1 only reads memory, the only dependence on CS2 can be + // from CS1 reading memory written by CS2. + if (onlyReadsMemory(CS1B)) + Mask = ModRefResult(Mask & Ref); + + // If CS2 only access memory through arguments, accumulate the mod/ref + // information from CS1's references to the memory referenced by + // CS2's arguments. + if (onlyAccessesArgPointees(CS2B)) { + AliasAnalysis::ModRefResult R = NoModRef; + if (doesAccessArgPointees(CS2B)) + for (ImmutableCallSite::arg_iterator + I = CS2.arg_begin(), E = CS2.arg_end(); I != E; ++I) { + R = ModRefResult((R | getModRefInfo(CS1, *I, UnknownSize)) & Mask); + if (R == Mask) + break; + } + return R; + } + + // If CS1 only accesses memory through arguments, check if CS2 references + // any of the memory referenced by CS1's arguments. If not, return NoModRef. + if (onlyAccessesArgPointees(CS1B)) { + AliasAnalysis::ModRefResult R = NoModRef; + if (doesAccessArgPointees(CS1B)) + for (ImmutableCallSite::arg_iterator + I = CS1.arg_begin(), E = CS1.arg_end(); I != E; ++I) + if (getModRefInfo(CS2, *I, UnknownSize) != NoModRef) { + R = Mask; + break; + } + if (R == NoModRef) + return R; + } + + // If this is the end of the chain, don't forward. + if (!AA) return Mask; + + // Otherwise, fall back to the next AA in the chain. But we can merge + // in any mask we've managed to compute. + return ModRefResult(AA->getModRefInfo(CS1, CS2) & Mask); +} + +AliasAnalysis::ModRefBehavior +AliasAnalysis::getModRefBehavior(ImmutableCallSite CS) { + assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); + + ModRefBehavior Min = UnknownModRefBehavior; + + // Call back into the alias analysis with the other form of getModRefBehavior + // to see if it can give a better response. + if (const Function *F = CS.getCalledFunction()) + Min = getModRefBehavior(F); + + // If this is the end of the chain, don't forward. + if (!AA) return Min; + + // Otherwise, fall back to the next AA in the chain. But we can merge + // in any result we've managed to compute. + return ModRefBehavior(AA->getModRefBehavior(CS) & Min); +} + +AliasAnalysis::ModRefBehavior +AliasAnalysis::getModRefBehavior(const Function *F) { + assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); + return AA->getModRefBehavior(F); +} + +//===----------------------------------------------------------------------===// +// AliasAnalysis non-virtual helper method implementation +//===----------------------------------------------------------------------===// + +AliasAnalysis::Location AliasAnalysis::getLocation(const LoadInst *LI) { + return Location(LI->getPointerOperand(), + getTypeStoreSize(LI->getType()), + LI->getMetadata(LLVMContext::MD_tbaa)); +} + +AliasAnalysis::Location AliasAnalysis::getLocation(const StoreInst *SI) { + return Location(SI->getPointerOperand(), + getTypeStoreSize(SI->getValueOperand()->getType()), + SI->getMetadata(LLVMContext::MD_tbaa)); +} + +AliasAnalysis::Location AliasAnalysis::getLocation(const VAArgInst *VI) { + return Location(VI->getPointerOperand(), + UnknownSize, + VI->getMetadata(LLVMContext::MD_tbaa)); +} + + +AliasAnalysis::Location +AliasAnalysis::getLocationForSource(const MemTransferInst *MTI) { + uint64_t Size = UnknownSize; + if (ConstantInt *C = dyn_cast(MTI->getLength())) + Size = C->getValue().getZExtValue(); + + // FIXME: Can memcpy/memmove have TBAA tags? + return Location(MTI->getRawSource(), Size, 0); +} + +AliasAnalysis::Location +AliasAnalysis::getLocationForDest(const MemIntrinsic *MTI) { + uint64_t Size = UnknownSize; + if (ConstantInt *C = dyn_cast(MTI->getLength())) + Size = C->getValue().getZExtValue(); + + // FIXME: Can memcpy/memmove have TBAA tags? + return Location(MTI->getRawDest(), Size, 0); +} + + + +AliasAnalysis::ModRefResult +AliasAnalysis::getModRefInfo(const LoadInst *L, const Location &Loc) { + // Be conservative in the face of volatile. + if (L->isVolatile()) + return ModRef; + + // If the load address doesn't alias the given address, it doesn't read + // or write the specified memory. + if (!alias(getLocation(L), Loc)) + return NoModRef; - CanModify(const AliasAnalysis *aa, const Value *ptr) - : AA(*aa), Ptr(ptr) {} + // Otherwise, a load just reads. + return Ref; +} + +AliasAnalysis::ModRefResult +AliasAnalysis::getModRefInfo(const StoreInst *S, const Location &Loc) { + // Be conservative in the face of volatile. + if (S->isVolatile()) + return ModRef; + + // If the store address cannot alias the pointer in question, then the + // specified memory cannot be modified by the store. + if (!alias(getLocation(S), Loc)) + return NoModRef; + + // If the pointer is a pointer to constant memory, then it could not have been + // modified by this store. + if (pointsToConstantMemory(Loc)) + return NoModRef; + + // Otherwise, a store just writes. + return Mod; +} + +AliasAnalysis::ModRefResult +AliasAnalysis::getModRefInfo(const VAArgInst *V, const Location &Loc) { + // If the va_arg address cannot alias the pointer in question, then the + // specified memory cannot be accessed by the va_arg. + if (!alias(getLocation(V), Loc)) + return NoModRef; - bool visitInvokeInst(InvokeInst &II) { - return AA.canInvokeModify(II, Ptr); - } - bool visitCallInst(CallInst &CI) { - return AA.canCallModify(CI, Ptr); - } - bool visitStoreInst(StoreInst &SI) { - return AA.alias(Ptr, SI.getOperand(1)); - } + // If the pointer is a pointer to constant memory, then it could not have been + // modified by this va_arg. + if (pointsToConstantMemory(Loc)) + return NoModRef; - // Other instructions do not alias anything. - bool visitInstruction(Instruction &I) { return false; } - }; + // Otherwise, a va_arg reads and writes. + return ModRef; } // AliasAnalysis destructor: DO NOT move this to the header file for @@ -62,19 +293,33 @@ namespace { // AliasAnalysis::~AliasAnalysis() {} -/// canBasicBlockModify - Return true if it is possible for execution of the -/// specified basic block to modify the value pointed to by Ptr. +/// InitializeAliasAnalysis - Subclasses must call this method to initialize the +/// AliasAnalysis interface before any other methods are called. /// -bool AliasAnalysis::canBasicBlockModify(const BasicBlock &bb, - const Value *Ptr) const { - CanModify CM(this, Ptr); - BasicBlock &BB = const_cast(bb); +void AliasAnalysis::InitializeAliasAnalysis(Pass *P) { + TD = P->getAnalysisIfAvailable(); + AA = &P->getAnalysis(); +} - for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) - if (CM.visit(I)) // Check every instruction in the basic block... - return true; +// getAnalysisUsage - All alias analysis implementations should invoke this +// directly (using AliasAnalysis::getAnalysisUsage(AU)). +void AliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); // All AA's chain +} - return false; +/// getTypeStoreSize - Return the TargetData store size for the given type, +/// if known, or a conservative value otherwise. +/// +uint64_t AliasAnalysis::getTypeStoreSize(const Type *Ty) { + return TD ? TD->getTypeStoreSize(Ty) : UnknownSize; +} + +/// canBasicBlockModify - Return true if it is possible for execution of the +/// specified basic block to modify the value pointed to by Ptr. +/// +bool AliasAnalysis::canBasicBlockModify(const BasicBlock &BB, + const Location &Loc) { + return canInstructionRangeModify(BB.front(), BB.back(), Loc); } /// canInstructionRangeModify - Return true if it is possible for the execution @@ -84,72 +329,43 @@ bool AliasAnalysis::canBasicBlockModify(const BasicBlock &bb, /// bool AliasAnalysis::canInstructionRangeModify(const Instruction &I1, const Instruction &I2, - const Value *Ptr) const { + const Location &Loc) { assert(I1.getParent() == I2.getParent() && "Instructions not in same basic block!"); - CanModify CM(this, Ptr); - BasicBlock::iterator I = const_cast(&I1); - BasicBlock::iterator E = const_cast(&I2); + BasicBlock::const_iterator I = &I1; + BasicBlock::const_iterator E = &I2; ++E; // Convert from inclusive to exclusive range. - for (; I != E; ++I) - if (CM.visit(I)) // Check every instruction in the basic block... + for (; I != E; ++I) // Check every instruction in range + if (getModRefInfo(I, Loc) & Mod) return true; - return false; } -//===----------------------------------------------------------------------===// -// BasicAliasAnalysis Pass Implementation -//===----------------------------------------------------------------------===// -// -// Because of the way .a files work, the implementation of the -// BasicAliasAnalysis class MUST be in the AliasAnalysis file itself, or else we -// run the risk of AliasAnalysis being used, but the default implementation not -// being linked into the tool that uses it. As such, we register and implement -// the class here. -// -namespace { - // Register this pass... - RegisterOpt - X("basicaa", "Basic Alias Analysis (default AA impl)"); - - // Declare that we implement the AliasAnalysis interface - RegisterAnalysisGroup Y; -} // End of anonymous namespace - - - -// hasUniqueAddress - Return true if the -static inline bool hasUniqueAddress(const Value *V) { - return isa(V) || isa(V) || isa(V); +/// isNoAliasCall - Return true if this pointer is returned by a noalias +/// function. +bool llvm::isNoAliasCall(const Value *V) { + if (isa(V) || isa(V)) + return ImmutableCallSite(cast(V)) + .paramHasAttr(0, Attribute::NoAlias); + return false; } -AliasAnalysis::Result BasicAliasAnalysis::alias(const Value *V1, - const Value *V2) const { - // Strip off constant pointer refs if they exist - if (const ConstantPointerRef *CPR = dyn_cast(V1)) - V1 = CPR->getValue(); - if (const ConstantPointerRef *CPR = dyn_cast(V2)) - V2 = CPR->getValue(); - - // Are we checking for alias of the same value? - if (V1 == V2) return MustAlias; - - if (!isa(V1->getType()) || !isa(V2->getType())) - return NoAlias; // Scalars cannot alias each other - - bool V1Unique = hasUniqueAddress(V1); - bool V2Unique = hasUniqueAddress(V2); - - if (V1Unique && V2Unique) - return NoAlias; // Can't alias if they are different unique values - - if ((V1Unique && isa(V2)) || - (V2Unique && isa(V1))) - return NoAlias; // Unique values don't alias null - - // TODO: Handle getelementptr with nonzero offset - - return MayAlias; +/// isIdentifiedObject - Return true if this pointer refers to a distinct and +/// identifiable object. This returns true for: +/// Global Variables and Functions (but not Global Aliases) +/// Allocas and Mallocs +/// ByVal and NoAlias Arguments +/// NoAlias returns +/// +bool llvm::isIdentifiedObject(const Value *V) { + if (isa(V)) + return true; + if (isa(V) && !isa(V)) + return true; + if (isNoAliasCall(V)) + return true; + if (const Argument *A = dyn_cast(V)) + return A->hasNoAliasAttr() || A->hasByValAttr(); + return false; }