From ebbc4df924a1c3ee344e758bda33dda9e7b57a00 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 14 Sep 2010 21:25:10 +0000 Subject: [PATCH] Remove the experimental AliasAnalysis::getDependency interface, which isn't a good level of abstraction for memdep. Instead, generalize AliasAnalysis::alias and related interfaces with a new Location class for describing a memory location. For now, this is the same Pointer and Size as before, plus an additional field for a TBAA tag. Also, introduce a fixed MD_tbaa metadata tag kind. llvm-svn: 113858 --- include/llvm/Analysis/AliasAnalysis.h | 239 +++++++-------- include/llvm/Analysis/LibCallAliasAnalysis.h | 4 +- include/llvm/Analysis/LibCallSemantics.h | 2 +- include/llvm/LLVMContext.h | 3 +- lib/Analysis/AliasAnalysis.cpp | 285 ++---------------- lib/Analysis/AliasAnalysisCounter.cpp | 30 +- lib/Analysis/AliasDebugger.cpp | 23 +- lib/Analysis/BasicAliasAnalysis.cpp | 89 +++--- lib/Analysis/IPA/GlobalsModRef.cpp | 22 +- lib/Analysis/LibCallAliasAnalysis.cpp | 18 +- lib/Analysis/ScalarEvolutionAliasAnalysis.cpp | 29 +- lib/Analysis/TypeBasedAliasAnalysis.cpp | 17 +- lib/VMCore/LLVMContext.cpp | 9 +- 13 files changed, 258 insertions(+), 512 deletions(-) diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index a03e0c88068..cae7addd3b0 100644 --- a/include/llvm/Analysis/AliasAnalysis.h +++ b/include/llvm/Analysis/AliasAnalysis.h @@ -83,6 +83,22 @@ public: /// Alias Queries... /// + /// Location - A description of a memory location. + struct Location { + /// Ptr - The address of the start of the location. + const Value *Ptr; + /// Size - The size of the location. + unsigned Size; + /// TBAATag - The metadata node which describes the TBAA type of + /// the location, or null if there is no (unique) tag. + const MDNode *TBAATag; + + explicit Location(const Value *P = 0, + unsigned S = UnknownSize, + const MDNode *N = 0) + : Ptr(P), Size(S), TBAATag(N) {} + }; + /// Alias analysis result - Either we know for sure that it does not alias, we /// know for sure it must alias, or we don't know anything: The two pointers /// _might_ alias. This enum is designed so you can do things like: @@ -98,27 +114,41 @@ public: /// Returns a Result indicating whether the two pointers are aliased to each /// other. This is the interface that must be implemented by specific alias /// analysis implementations. - /// - virtual AliasResult alias(const Value *V1, unsigned V1Size, - const Value *V2, unsigned V2Size); + virtual AliasResult alias(const Location &LocA, const Location &LocB); - /// alias - A convenience wrapper for the case where the sizes are unknown. + /// alias - A convenience wrapper. + AliasResult alias(const Value *V1, unsigned V1Size, + const Value *V2, unsigned V2Size) { + return alias(Location(V1, V1Size), Location(V2, V2Size)); + } + + /// alias - A convenience wrapper. AliasResult alias(const Value *V1, const Value *V2) { return alias(V1, UnknownSize, V2, UnknownSize); } /// isNoAlias - A trivial helper function to check to see if the specified /// pointers are no-alias. - bool isNoAlias(const Value *V1, unsigned V1Size, - const Value *V2, unsigned V2Size) { - return alias(V1, V1Size, V2, V2Size) == NoAlias; + bool isNoAlias(const Location &LocA, const Location &LocB) { + return alias(LocA, LocB) == NoAlias; } - /// pointsToConstantMemory - If the specified pointer is known to point into - /// constant global memory, return true. This allows disambiguation of store + /// isNoAlias - A convenience wrapper. + bool isNoAlias(const Value *V1, unsigned V1Size, + const Value *V2, unsigned V2Size) { + return isNoAlias(Location(V1, V1Size), Location(V2, V2Size)); + } + + /// pointsToConstantMemory - If the specified memory location is known to be + /// constant, return true. This allows disambiguation of store /// instructions from constant pointers. /// - virtual bool pointsToConstantMemory(const Value *P); + virtual bool pointsToConstantMemory(const Location &Loc); + + /// pointsToConstantMemory - A convenient wrapper. + bool pointsToConstantMemory(const Value *P) { + return pointsToConstantMemory(Location(P)); + } //===--------------------------------------------------------------------===// /// Simple mod/ref information... @@ -220,55 +250,87 @@ public: /// getModRefInfo - Return information about whether or not an instruction may - /// read or write memory specified by the pointer operand. An instruction + /// read or write the specified memory location. An instruction /// that doesn't read or write memory may be trivially LICM'd for example. ModRefResult getModRefInfo(const Instruction *I, - const Value *P, unsigned Size) { + const Location &Loc) { switch (I->getOpcode()) { - case Instruction::VAArg: return getModRefInfo((const VAArgInst*)I, P,Size); - case Instruction::Load: return getModRefInfo((const LoadInst*)I, P, Size); - case Instruction::Store: return getModRefInfo((const StoreInst*)I, P,Size); - case Instruction::Call: return getModRefInfo((const CallInst*)I, P, Size); - case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,P,Size); + case Instruction::VAArg: return getModRefInfo((const VAArgInst*)I, Loc); + case Instruction::Load: return getModRefInfo((const LoadInst*)I, Loc); + case Instruction::Store: return getModRefInfo((const StoreInst*)I, Loc); + case Instruction::Call: return getModRefInfo((const CallInst*)I, Loc); + case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,Loc); default: return NoModRef; } } + /// getModRefInfo - A convenience wrapper. + ModRefResult getModRefInfo(const Instruction *I, + const Value *P, unsigned Size) { + return getModRefInfo(I, Location(P, Size)); + } + /// getModRefInfo (for call sites) - Return whether information about whether - /// a particular call site modifies or reads the memory specified by the - /// pointer. + /// a particular call site modifies or reads the specified memory location. virtual ModRefResult getModRefInfo(ImmutableCallSite CS, - const Value *P, unsigned Size); + const Location &Loc); + + /// getModRefInfo (for call sites) - A convenience wrapper. + ModRefResult getModRefInfo(ImmutableCallSite CS, + const Value *P, unsigned Size) { + return getModRefInfo(CS, Location(P, Size)); + } /// getModRefInfo (for calls) - Return whether information about whether - /// a particular call modifies or reads the memory specified by the - /// pointer. + /// a particular call modifies or reads the specified memory location. + ModRefResult getModRefInfo(const CallInst *C, const Location &Loc) { + return getModRefInfo(ImmutableCallSite(C), Loc); + } + + /// getModRefInfo (for calls) - A convenience wrapper. ModRefResult getModRefInfo(const CallInst *C, const Value *P, unsigned Size) { - return getModRefInfo(ImmutableCallSite(C), P, Size); + return getModRefInfo(C, Location(P, Size)); } /// getModRefInfo (for invokes) - Return whether information about whether - /// a particular invoke modifies or reads the memory specified by the - /// pointer. + /// a particular invoke modifies or reads the specified memory location. + ModRefResult getModRefInfo(const InvokeInst *I, + const Location &Loc) { + return getModRefInfo(ImmutableCallSite(I), Loc); + } + + /// getModRefInfo (for invokes) - A convenience wrapper. ModRefResult getModRefInfo(const InvokeInst *I, const Value *P, unsigned Size) { - return getModRefInfo(ImmutableCallSite(I), P, Size); + return getModRefInfo(I, Location(P, Size)); } /// getModRefInfo (for loads) - Return whether information about whether - /// a particular load modifies or reads the memory specified by the - /// pointer. - ModRefResult getModRefInfo(const LoadInst *L, const Value *P, unsigned Size); + /// a particular load modifies or reads the specified memory location. + ModRefResult getModRefInfo(const LoadInst *L, const Location &Loc); + + /// getModRefInfo (for loads) - A convenience wrapper. + ModRefResult getModRefInfo(const LoadInst *L, const Value *P, unsigned Size) { + return getModRefInfo(L, Location(P, Size)); + } /// getModRefInfo (for stores) - Return whether information about whether - /// a particular store modifies or reads the memory specified by the - /// pointer. - ModRefResult getModRefInfo(const StoreInst *S, const Value *P, unsigned Size); + /// a particular store modifies or reads the specified memory location. + ModRefResult getModRefInfo(const StoreInst *S, const Location &Loc); + + /// getModRefInfo (for stores) - A convenience wrapper. + ModRefResult getModRefInfo(const StoreInst *S, const Value *P, unsigned Size) { + return getModRefInfo(S, Location(P, Size)); + } /// getModRefInfo (for va_args) - Return whether information about whether - /// a particular va_arg modifies or reads the memory specified by the - /// pointer. - ModRefResult getModRefInfo(const VAArgInst* I, const Value* P, unsigned Size); + /// a particular va_arg modifies or reads the specified memory location. + ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc); + + /// getModRefInfo (for va_args) - A convenience wrapper. + ModRefResult getModRefInfo(const VAArgInst* I, const Value* P, unsigned Size) { + return getModRefInfo(I, Location(P, Size)); + } /// getModRefInfo - Return information about whether two call sites may refer /// to the same set of memory locations. See @@ -277,101 +339,31 @@ public: virtual ModRefResult getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2); - //===--------------------------------------------------------------------===// - /// Dependence queries. - /// - - /// DependenceResult - These are the return values for getDependence queries. - /// They are defined in terms of "memory", but they are also used to model - /// other side effects, such as I/O and volatility. - enum DependenceResult { - /// ReadThenRead - The instructions are ReadThenReadSome and the second - /// instruction reads from exactly the same memory read from by the first. - ReadThenRead, - - /// ReadThenReadSome - The instructions are Independent, both are read-only, - /// and the second instruction reads from a subset of the memory read from - /// by the first. - ReadThenReadSome, - - /// Independent - Neither instruction reads from or writes to memory written - /// to by the other. All enum values lower than this one are special cases - /// of Indepenent. - Independent, - - /// WriteThenRead - The instructions are WriteThenReadSome and the second - /// instruction reads from exactly the same memory written by the first. - WriteThenRead, - - /// WriteThenReadSome - The first instruction is write-only, the second - /// instruction is read-only, and the second only reads from memory - /// written to by the first. - WriteThenReadSome, - - /// ReadThenWrite - The first instruction is read-only, the second - /// instruction is write-only, and the second wrotes to exactly the - /// same memory read from by the first. - ReadThenWrite, - - /// WriteThenWrite - The instructions are WriteThenWriteSome, and the - /// second instruction writes to exactly the same memory written to by - /// the first. - WriteThenWrite, - - /// WriteSomeThenWrite - Both instructions are write-only, and the second - /// instruction writes to a superset of the memory written to by the first. - WriteSomeThenWrite, - - /// Unknown - The relationship between the instructions cannot be - /// determined or does not fit into any of the cases defined here. - Unknown - }; - - /// DependenceQueryFlags - Flags for refining dependence queries. - enum DependenceQueryFlags { - Default = 0, - IgnoreLoads = 1, - IgnoreStores = 2 - }; - - /// getDependence - Determine the dependence relationship between the - /// instructions. This does not include "register" dependencies; it just - /// considers memory references and other side effects. - /// WARNING: This is an experimental interface. - DependenceResult getDependence(const Instruction *First, - const Instruction *Second) { - return getDependence(First, 0, Default, Second, 0, Default); - } - - /// getDependence - Determine the dependence relationship between the - /// instructions. This does not include "register" dependencies; it just - /// considers memory references and other side effects. This overload - /// has additional parameters to allow phi-translated addresses to be - /// specified, and additional flags to refine the query. - /// WARNING: This is an experimental interface. - virtual DependenceResult getDependence(const Instruction *First, - const Value *FirstPHITranslatedAddr, - DependenceQueryFlags FirstFlags, - const Instruction *Second, - const Value *SecondPHITranslatedAddr, - DependenceQueryFlags SecondFlags); - //===--------------------------------------------------------------------===// /// Higher level methods for querying mod/ref information. /// /// canBasicBlockModify - Return true if it is possible for execution of the /// specified basic block to modify the value pointed to by Ptr. - /// - bool canBasicBlockModify(const BasicBlock &BB, const Value *P, unsigned Size); + bool canBasicBlockModify(const BasicBlock &BB, const Location &Loc); + + /// canBasicBlockModify - A convenience wrapper. + bool canBasicBlockModify(const BasicBlock &BB, const Value *P, unsigned Size){ + return canBasicBlockModify(BB, Location(P, Size)); + } /// canInstructionRangeModify - Return true if it is possible for the /// execution of the specified instructions to modify the value pointed to by /// Ptr. The instructions to consider are all of the instructions in the /// range of [I1,I2] INCLUSIVE. I1 and I2 must be in the same basic block. - /// bool canInstructionRangeModify(const Instruction &I1, const Instruction &I2, - const Value *Ptr, unsigned Size); + const Location &Loc); + + /// canInstructionRangeModify - A convenience wrapper. + bool canInstructionRangeModify(const Instruction &I1, const Instruction &I2, + const Value *Ptr, unsigned Size) { + return canInstructionRangeModify(I1, I2, Location(Ptr, Size)); + } //===--------------------------------------------------------------------===// /// Methods that clients should call when they transform the program to allow @@ -401,17 +393,6 @@ public: copyValue(Old, New); deleteValue(Old); } - -protected: - /// getDependenceViaModRefInfo - Helper function for implementing getDependence - /// in implementations which already have getModRefInfo implementations. - DependenceResult getDependenceViaModRefInfo(const Instruction *First, - const Value *FirstPHITranslatedAddr, - DependenceQueryFlags FirstFlags, - const Instruction *Second, - const Value *SecondPHITranslatedAddr, - DependenceQueryFlags SecondFlags); - }; /// isNoAliasCall - Return true if this pointer is returned by a noalias diff --git a/include/llvm/Analysis/LibCallAliasAnalysis.h b/include/llvm/Analysis/LibCallAliasAnalysis.h index c9adf3f36ad..7d7782ab7c8 100644 --- a/include/llvm/Analysis/LibCallAliasAnalysis.h +++ b/include/llvm/Analysis/LibCallAliasAnalysis.h @@ -36,7 +36,7 @@ namespace llvm { ~LibCallAliasAnalysis(); ModRefResult getModRefInfo(ImmutableCallSite CS, - const Value *P, unsigned Size); + const Location &Loc); ModRefResult getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) { @@ -64,7 +64,7 @@ namespace llvm { private: ModRefResult AnalyzeLibCallDetails(const LibCallFunctionInfo *FI, ImmutableCallSite CS, - const Value *P, unsigned Size); + const Location &Loc); }; } // End of llvm namespace diff --git a/include/llvm/Analysis/LibCallSemantics.h b/include/llvm/Analysis/LibCallSemantics.h index 31d7cc56ce5..f5a9e96cbdd 100644 --- a/include/llvm/Analysis/LibCallSemantics.h +++ b/include/llvm/Analysis/LibCallSemantics.h @@ -48,7 +48,7 @@ namespace llvm { Yes, No, Unknown }; LocResult (*isLocation)(ImmutableCallSite CS, - const Value *Ptr, unsigned Size); + const AliasAnalysis::Location &Loc); }; /// LibCallFunctionInfo - Each record in the array of FunctionInfo structs diff --git a/include/llvm/LLVMContext.h b/include/llvm/LLVMContext.h index 8abf277772f..e5b77777d9f 100644 --- a/include/llvm/LLVMContext.h +++ b/include/llvm/LLVMContext.h @@ -37,7 +37,8 @@ public: // Pinned metadata names, which always have the same value. This is a // compile-time performance optimization, not a correctness optimization. enum { - MD_dbg = 0 // "dbg" + MD_dbg = 0, // "dbg" + MD_tbaa = 1 // "tbaa" }; /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. diff --git a/lib/Analysis/AliasAnalysis.cpp b/lib/Analysis/AliasAnalysis.cpp index 93597cab226..b9cd5a69203 100644 --- a/lib/Analysis/AliasAnalysis.cpp +++ b/lib/Analysis/AliasAnalysis.cpp @@ -30,6 +30,7 @@ #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; @@ -43,15 +44,14 @@ char AliasAnalysis::ID = 0; //===----------------------------------------------------------------------===// AliasAnalysis::AliasResult -AliasAnalysis::alias(const Value *V1, unsigned V1Size, - const Value *V2, unsigned V2Size) { +AliasAnalysis::alias(const Location &LocA, const Location &LocB) { assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); - return AA->alias(V1, V1Size, V2, V2Size); + return AA->alias(LocA, LocB); } -bool AliasAnalysis::pointsToConstantMemory(const Value *P) { +bool AliasAnalysis::pointsToConstantMemory(const Location &Loc) { assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!"); - return AA->pointsToConstantMemory(P); + return AA->pointsToConstantMemory(Loc); } void AliasAnalysis::deleteValue(Value *V) { @@ -66,7 +66,7 @@ void AliasAnalysis::copyValue(Value *From, Value *To) { AliasAnalysis::ModRefResult AliasAnalysis::getModRefInfo(ImmutableCallSite CS, - const Value *P, unsigned Size) { + const Location &Loc) { // Don't assert AA because BasicAA calls us in order to make use of the // logic here. @@ -81,7 +81,7 @@ AliasAnalysis::getModRefInfo(ImmutableCallSite CS, bool doesAlias = false; for (ImmutableCallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end(); AI != AE; ++AI) - if (!isNoAlias(*AI, ~0U, P, Size)) { + if (!isNoAlias(Location(*AI), Loc)) { doesAlias = true; break; } @@ -90,9 +90,9 @@ AliasAnalysis::getModRefInfo(ImmutableCallSite CS, return NoModRef; } - // If P points to a constant memory location, the call definitely could not + // If Loc is a constant memory location, the call definitely could not // modify the memory location. - if ((Mask & Mod) && pointsToConstantMemory(P)) + if ((Mask & Mod) && pointsToConstantMemory(Loc)) Mask = ModRefResult(Mask & ~Mod); // If this is BasicAA, don't forward. @@ -100,7 +100,7 @@ AliasAnalysis::getModRefInfo(ImmutableCallSite CS, // 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, P, Size) & Mask); + return ModRefResult(AA->getModRefInfo(CS, Loc) & Mask); } AliasAnalysis::ModRefResult @@ -188,31 +188,22 @@ AliasAnalysis::getModRefBehavior(const Function *F) { return AA->getModRefBehavior(F); } -AliasAnalysis::DependenceResult -AliasAnalysis::getDependence(const Instruction *First, - const Value *FirstPHITranslatedAddr, - DependenceQueryFlags FirstFlags, - const Instruction *Second, - const Value *SecondPHITranslatedAddr, - DependenceQueryFlags SecondFlags) { - assert(AA && "AA didn't call InitializeAliasAnalyais in its run method!"); - return AA->getDependence(First, FirstPHITranslatedAddr, FirstFlags, - Second, SecondPHITranslatedAddr, SecondFlags); -} - //===----------------------------------------------------------------------===// // AliasAnalysis non-virtual helper method implementation //===----------------------------------------------------------------------===// AliasAnalysis::ModRefResult -AliasAnalysis::getModRefInfo(const LoadInst *L, const Value *P, unsigned Size) { +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(L->getOperand(0), getTypeStoreSize(L->getType()), P, Size)) + if (!alias(Location(L->getOperand(0), + getTypeStoreSize(L->getType()), + L->getMetadata(LLVMContext::MD_tbaa)), + Loc)) return NoModRef; // Otherwise, a load just reads. @@ -220,20 +211,22 @@ AliasAnalysis::getModRefInfo(const LoadInst *L, const Value *P, unsigned Size) { } AliasAnalysis::ModRefResult -AliasAnalysis::getModRefInfo(const StoreInst *S, const Value *P, unsigned Size) { +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(S->getOperand(1), - getTypeStoreSize(S->getOperand(0)->getType()), P, Size)) + if (!alias(Location(S->getOperand(1), + getTypeStoreSize(S->getOperand(0)->getType()), + S->getMetadata(LLVMContext::MD_tbaa)), + Loc)) return NoModRef; // If the pointer is a pointer to constant memory, then it could not have been // modified by this store. - if (pointsToConstantMemory(P)) + if (pointsToConstantMemory(Loc)) return NoModRef; // Otherwise, a store just writes. @@ -241,240 +234,24 @@ AliasAnalysis::getModRefInfo(const StoreInst *S, const Value *P, unsigned Size) } AliasAnalysis::ModRefResult -AliasAnalysis::getModRefInfo(const VAArgInst *V, const Value *P, unsigned Size) { +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(V->getOperand(0), UnknownSize, P, Size)) + if (!alias(Location(V->getOperand(0), + UnknownSize, + V->getMetadata(LLVMContext::MD_tbaa)), + Loc)) return NoModRef; // If the pointer is a pointer to constant memory, then it could not have been // modified by this va_arg. - if (pointsToConstantMemory(P)) + if (pointsToConstantMemory(Loc)) return NoModRef; // Otherwise, a va_arg reads and writes. return ModRef; } -AliasAnalysis::DependenceResult -AliasAnalysis::getDependenceViaModRefInfo(const Instruction *First, - const Value *FirstPHITranslatedAddr, - DependenceQueryFlags FirstFlags, - const Instruction *Second, - const Value *SecondPHITranslatedAddr, - DependenceQueryFlags SecondFlags) { - if (const LoadInst *L = dyn_cast(First)) { - // Be over-conservative with volatile for now. - if (L->isVolatile()) - return Unknown; - - // If we don't have a phi-translated address, use the actual one. - if (!FirstPHITranslatedAddr) - FirstPHITranslatedAddr = L->getPointerOperand(); - - // Forward this query to getModRefInfo. - switch (getModRefInfo(Second, - FirstPHITranslatedAddr, - getTypeStoreSize(L->getType()))) { - case NoModRef: - // Second doesn't reference First's memory, so they're independent. - return Independent; - - case Ref: - // Second only reads from the memory read from by First. If it - // also writes to any other memory, be conservative. - if (Second->mayWriteToMemory()) - return Unknown; - - // If it's loading the same size from the same address, we can - // give a more precise result. - if (const LoadInst *SecondL = dyn_cast(Second)) { - // If we don't have a phi-translated address, use the actual one. - if (!SecondPHITranslatedAddr) - SecondPHITranslatedAddr = SecondL->getPointerOperand(); - - unsigned LSize = getTypeStoreSize(L->getType()); - unsigned SecondLSize = getTypeStoreSize(SecondL->getType()); - if (alias(FirstPHITranslatedAddr, LSize, - SecondPHITranslatedAddr, SecondLSize) == - MustAlias) { - // If the loads are the same size, it's ReadThenRead. - if (LSize == SecondLSize) - return ReadThenRead; - - // If the second load is smaller, it's only ReadThenReadSome. - if (LSize > SecondLSize) - return ReadThenReadSome; - } - } - - // Otherwise it's just two loads. - return Independent; - - case Mod: - // Second only writes to the memory read from by First. If it - // also reads from any other memory, be conservative. - if (Second->mayReadFromMemory()) - return Unknown; - - // If it's storing the same size to the same address, we can - // give a more precise result. - if (const StoreInst *SecondS = dyn_cast(Second)) { - // If we don't have a phi-translated address, use the actual one. - if (!SecondPHITranslatedAddr) - SecondPHITranslatedAddr = SecondS->getPointerOperand(); - - unsigned LSize = getTypeStoreSize(L->getType()); - unsigned SecondSSize = getTypeStoreSize(SecondS->getType()); - if (alias(FirstPHITranslatedAddr, LSize, - SecondPHITranslatedAddr, SecondSSize) == - MustAlias) { - // If the load and the store are the same size, it's ReadThenWrite. - if (LSize == SecondSSize) - return ReadThenWrite; - } - } - - // Otherwise we don't know if it could be writing to other memory. - return Unknown; - - case ModRef: - // Second reads and writes to the memory read from by First. - // We don't have a way to express that. - return Unknown; - } - - } else if (const StoreInst *S = dyn_cast(First)) { - // Be over-conservative with volatile for now. - if (S->isVolatile()) - return Unknown; - - // If we don't have a phi-translated address, use the actual one. - if (!FirstPHITranslatedAddr) - FirstPHITranslatedAddr = S->getPointerOperand(); - - // Forward this query to getModRefInfo. - switch (getModRefInfo(Second, - FirstPHITranslatedAddr, - getTypeStoreSize(S->getValueOperand()->getType()))) { - case NoModRef: - // Second doesn't reference First's memory, so they're independent. - return Independent; - - case Ref: - // Second only reads from the memory written to by First. If it - // also writes to any other memory, be conservative. - if (Second->mayWriteToMemory()) - return Unknown; - - // If it's loading the same size from the same address, we can - // give a more precise result. - if (const LoadInst *SecondL = dyn_cast(Second)) { - // If we don't have a phi-translated address, use the actual one. - if (!SecondPHITranslatedAddr) - SecondPHITranslatedAddr = SecondL->getPointerOperand(); - - unsigned SSize = getTypeStoreSize(S->getValueOperand()->getType()); - unsigned SecondLSize = getTypeStoreSize(SecondL->getType()); - if (alias(FirstPHITranslatedAddr, SSize, - SecondPHITranslatedAddr, SecondLSize) == - MustAlias) { - // If the store and the load are the same size, it's WriteThenRead. - if (SSize == SecondLSize) - return WriteThenRead; - - // If the load is smaller, it's only WriteThenReadSome. - if (SSize > SecondLSize) - return WriteThenReadSome; - } - } - - // Otherwise we don't know if it could be reading from other memory. - return Unknown; - - case Mod: - // Second only writes to the memory written to by First. If it - // also reads from any other memory, be conservative. - if (Second->mayReadFromMemory()) - return Unknown; - - // If it's storing the same size to the same address, we can - // give a more precise result. - if (const StoreInst *SecondS = dyn_cast(Second)) { - // If we don't have a phi-translated address, use the actual one. - if (!SecondPHITranslatedAddr) - SecondPHITranslatedAddr = SecondS->getPointerOperand(); - - unsigned SSize = getTypeStoreSize(S->getValueOperand()->getType()); - unsigned SecondSSize = getTypeStoreSize(SecondS->getType()); - if (alias(FirstPHITranslatedAddr, SSize, - SecondPHITranslatedAddr, SecondSSize) == - MustAlias) { - // If the stores are the same size, it's WriteThenWrite. - if (SSize == SecondSSize) - return WriteThenWrite; - - // If the second store is larger, it's only WriteSomeThenWrite. - if (SSize < SecondSSize) - return WriteSomeThenWrite; - } - } - - // Otherwise we don't know if it could be writing to other memory. - return Unknown; - - case ModRef: - // Second reads and writes to the memory written to by First. - // We don't have a way to express that. - return Unknown; - } - - } else if (const VAArgInst *V = dyn_cast(First)) { - // If we don't have a phi-translated address, use the actual one. - if (!FirstPHITranslatedAddr) - FirstPHITranslatedAddr = V->getPointerOperand(); - - // Forward this query to getModRefInfo. - if (getModRefInfo(Second, FirstPHITranslatedAddr, UnknownSize) == NoModRef) - // Second doesn't reference First's memory, so they're independent. - return Independent; - - } else if (ImmutableCallSite FirstCS = cast(First)) { - assert(!FirstPHITranslatedAddr && - !SecondPHITranslatedAddr && - "PHI translation with calls not supported yet!"); - - // If both instructions are calls/invokes we can use the two-callsite - // form of getModRefInfo. - if (ImmutableCallSite SecondCS = cast(Second)) - // getModRefInfo's arguments are backwards from intuition. - switch (getModRefInfo(SecondCS, FirstCS)) { - case NoModRef: - // Second doesn't reference First's memory, so they're independent. - return Independent; - - case Ref: - // If they're both read-only, there's no dependence. - if (FirstCS.onlyReadsMemory() && SecondCS.onlyReadsMemory()) - return Independent; - - // Otherwise it's not obvious what we can do here. - return Unknown; - - case Mod: - // It's not obvious what we can do here. - return Unknown; - - case ModRef: - // I know, right? - return Unknown; - } - } - - // For anything else, be conservative. - return Unknown; -} - AliasAnalysis::ModRefBehavior AliasAnalysis::getIntrinsicModRefBehavior(unsigned iid) { #define GET_INTRINSIC_MODREF_BEHAVIOR @@ -514,8 +291,8 @@ unsigned AliasAnalysis::getTypeStoreSize(const Type *Ty) { /// specified basic block to modify the value pointed to by Ptr. /// bool AliasAnalysis::canBasicBlockModify(const BasicBlock &BB, - const Value *Ptr, unsigned Size) { - return canInstructionRangeModify(BB.front(), BB.back(), Ptr, Size); + const Location &Loc) { + return canInstructionRangeModify(BB.front(), BB.back(), Loc); } /// canInstructionRangeModify - Return true if it is possible for the execution @@ -525,7 +302,7 @@ bool AliasAnalysis::canBasicBlockModify(const BasicBlock &BB, /// bool AliasAnalysis::canInstructionRangeModify(const Instruction &I1, const Instruction &I2, - const Value *Ptr, unsigned Size) { + const Location &Loc) { assert(I1.getParent() == I2.getParent() && "Instructions not in same basic block!"); BasicBlock::const_iterator I = &I1; @@ -533,7 +310,7 @@ bool AliasAnalysis::canInstructionRangeModify(const Instruction &I1, ++E; // Convert from inclusive to exclusive range. for (; I != E; ++I) // Check every instruction in range - if (getModRefInfo(I, Ptr, Size) & Mod) + if (getModRefInfo(I, Loc) & Mod) return true; return false; } diff --git a/lib/Analysis/AliasAnalysisCounter.cpp b/lib/Analysis/AliasAnalysisCounter.cpp index b17804186a6..48f7a9f223f 100644 --- a/lib/Analysis/AliasAnalysisCounter.cpp +++ b/lib/Analysis/AliasAnalysisCounter.cpp @@ -94,17 +94,16 @@ namespace { } // FIXME: We could count these too... - bool pointsToConstantMemory(const Value *P) { - return getAnalysis().pointsToConstantMemory(P); + bool pointsToConstantMemory(const Location &Loc) { + return getAnalysis().pointsToConstantMemory(Loc); } // Forwarding functions: just delegate to a real AA implementation, counting // the number of responses... - AliasResult alias(const Value *V1, unsigned V1Size, - const Value *V2, unsigned V2Size); + AliasResult alias(const Location &LocA, const Location &LocB); ModRefResult getModRefInfo(ImmutableCallSite CS, - const Value *P, unsigned Size); + const Location &Loc); ModRefResult getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) { return AliasAnalysis::getModRefInfo(CS1,CS2); @@ -121,9 +120,8 @@ ModulePass *llvm::createAliasAnalysisCounterPass() { } AliasAnalysis::AliasResult -AliasAnalysisCounter::alias(const Value *V1, unsigned V1Size, - const Value *V2, unsigned V2Size) { - AliasResult R = getAnalysis().alias(V1, V1Size, V2, V2Size); +AliasAnalysisCounter::alias(const Location &LocA, const Location &LocB) { + AliasResult R = getAnalysis().alias(LocA, LocB); const char *AliasString; switch (R) { @@ -135,11 +133,11 @@ AliasAnalysisCounter::alias(const Value *V1, unsigned V1Size, if (PrintAll || (PrintAllFailures && R == MayAlias)) { errs() << AliasString << ":\t"; - errs() << "[" << V1Size << "B] "; - WriteAsOperand(errs(), V1, true, M); + errs() << "[" << LocA.Size << "B] "; + WriteAsOperand(errs(), LocA.Ptr, true, M); errs() << ", "; - errs() << "[" << V2Size << "B] "; - WriteAsOperand(errs(), V2, true, M); + errs() << "[" << LocB.Size << "B] "; + WriteAsOperand(errs(), LocB.Ptr, true, M); errs() << "\n"; } @@ -148,8 +146,8 @@ AliasAnalysisCounter::alias(const Value *V1, unsigned V1Size, AliasAnalysis::ModRefResult AliasAnalysisCounter::getModRefInfo(ImmutableCallSite CS, - const Value *P, unsigned Size) { - ModRefResult R = getAnalysis().getModRefInfo(CS, P, Size); + const Location &Loc) { + ModRefResult R = getAnalysis().getModRefInfo(CS, Loc); const char *MRString; switch (R) { @@ -162,8 +160,8 @@ AliasAnalysisCounter::getModRefInfo(ImmutableCallSite CS, if (PrintAll || (PrintAllFailures && R == ModRef)) { errs() << MRString << ": Ptr: "; - errs() << "[" << Size << "B] "; - WriteAsOperand(errs(), P, true, M); + errs() << "[" << Loc.Size << "B] "; + WriteAsOperand(errs(), Loc.Ptr, true, M); errs() << "\t<->" << *CS.getInstruction() << '\n'; } return R; diff --git a/lib/Analysis/AliasDebugger.cpp b/lib/Analysis/AliasDebugger.cpp index b9fe64608c0..82e705dd1cc 100644 --- a/lib/Analysis/AliasDebugger.cpp +++ b/lib/Analysis/AliasDebugger.cpp @@ -92,17 +92,18 @@ namespace { //------------------------------------------------ // Implement the AliasAnalysis API // - AliasResult alias(const Value *V1, unsigned V1Size, - const Value *V2, unsigned V2Size) { - assert(Vals.find(V1) != Vals.end() && "Never seen value in AA before"); - assert(Vals.find(V2) != Vals.end() && "Never seen value in AA before"); - return AliasAnalysis::alias(V1, V1Size, V2, V2Size); + AliasResult alias(const Location &LocA, const Location &LocB) { + assert(Vals.find(LocA.Ptr) != Vals.end() && + "Never seen value in AA before"); + assert(Vals.find(LocB.Ptr) != Vals.end() && + "Never seen value in AA before"); + return AliasAnalysis::alias(LocA, LocB); } ModRefResult getModRefInfo(ImmutableCallSite CS, - const Value *P, unsigned Size) { - assert(Vals.find(P) != Vals.end() && "Never seen value in AA before"); - return AliasAnalysis::getModRefInfo(CS, P, Size); + const Location &Loc) { + assert(Vals.find(Loc.Ptr) != Vals.end() && "Never seen value in AA before"); + return AliasAnalysis::getModRefInfo(CS, Loc); } ModRefResult getModRefInfo(ImmutableCallSite CS1, @@ -110,9 +111,9 @@ namespace { return AliasAnalysis::getModRefInfo(CS1,CS2); } - bool pointsToConstantMemory(const Value *P) { - assert(Vals.find(P) != Vals.end() && "Never seen value in AA before"); - return AliasAnalysis::pointsToConstantMemory(P); + bool pointsToConstantMemory(const Location &Loc) { + assert(Vals.find(Loc.Ptr) != Vals.end() && "Never seen value in AA before"); + return AliasAnalysis::pointsToConstantMemory(Loc); } virtual void deleteValue(Value *V) { diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index 354e66df0c0..69a1c0c772d 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -22,6 +22,7 @@ #include "llvm/GlobalVariable.h" #include "llvm/Instructions.h" #include "llvm/IntrinsicInst.h" +#include "llvm/LLVMContext.h" #include "llvm/Operator.h" #include "llvm/Pass.h" #include "llvm/Analysis/CaptureTracking.h" @@ -149,8 +150,7 @@ namespace { TD = getAnalysisIfAvailable(); } - virtual AliasResult alias(const Value *V1, unsigned V1Size, - const Value *V2, unsigned V2Size) { + virtual AliasResult alias(const Location &LocA, const Location &LocB) { return MayAlias; } @@ -161,9 +161,9 @@ namespace { return UnknownModRefBehavior; } - virtual bool pointsToConstantMemory(const Value *P) { return false; } + virtual bool pointsToConstantMemory(const Location &Loc) { return false; } virtual ModRefResult getModRefInfo(ImmutableCallSite CS, - const Value *P, unsigned Size) { + const Location &Loc) { return ModRef; } virtual ModRefResult getModRefInfo(ImmutableCallSite CS1, @@ -171,15 +171,6 @@ namespace { return ModRef; } - virtual DependenceResult getDependence(const Instruction *First, - const Value *FirstPHITranslatedAddr, - DependenceQueryFlags FirstFlags, - const Instruction *Second, - const Value *SecondPHITranslatedAddr, - DependenceQueryFlags SecondFlags) { - return Unknown; - } - virtual void deleteValue(Value *V) {} virtual void copyValue(Value *From, Value *To) {} @@ -501,18 +492,18 @@ namespace { static char ID; // Class identification, replacement for typeinfo BasicAliasAnalysis() : NoAA(ID) {} - virtual AliasResult alias(const Value *V1, unsigned V1Size, - const Value *V2, unsigned V2Size) { + virtual AliasResult alias(const Location &LocA, + const Location &LocB) { assert(Visited.empty() && "Visited must be cleared after use!"); - assert(notDifferentParent(V1, V2) && + assert(notDifferentParent(LocA.Ptr, LocB.Ptr) && "BasicAliasAnalysis doesn't support interprocedural queries."); - AliasResult Alias = aliasCheck(V1, V1Size, V2, V2Size); + AliasResult Alias = aliasCheck(LocA.Ptr, LocA.Size, LocB.Ptr, LocB.Size); Visited.clear(); return Alias; } virtual ModRefResult getModRefInfo(ImmutableCallSite CS, - const Value *P, unsigned Size); + const Location &Loc); virtual ModRefResult getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) { @@ -522,7 +513,7 @@ namespace { /// pointsToConstantMemory - Chase pointers until we find a (constant /// global) or not. - virtual bool pointsToConstantMemory(const Value *P); + virtual bool pointsToConstantMemory(const Location &Loc); /// getModRefBehavior - Return the behavior when calling the given /// call site. @@ -532,13 +523,6 @@ namespace { /// For use when the call site is not known. virtual ModRefBehavior getModRefBehavior(const Function *F); - virtual DependenceResult getDependence(const Instruction *First, - const Value *FirstPHITranslatedAddr, - DependenceQueryFlags FirstFlags, - const Instruction *Second, - const Value *SecondPHITranslatedAddr, - DependenceQueryFlags SecondFlags); - /// getAdjustedAnalysisPointer - This method is used when a pass implements /// an analysis interface through multiple inheritance. If needed, it /// should override this to adjust the this pointer as needed for the @@ -586,15 +570,15 @@ ImmutablePass *llvm::createBasicAliasAnalysisPass() { /// pointsToConstantMemory - Chase pointers until we find a (constant /// global) or not. -bool BasicAliasAnalysis::pointsToConstantMemory(const Value *P) { +bool BasicAliasAnalysis::pointsToConstantMemory(const Location &Loc) { if (const GlobalVariable *GV = - dyn_cast(P->getUnderlyingObject())) + dyn_cast(Loc.Ptr->getUnderlyingObject())) // Note: this doesn't require GV to be "ODR" because it isn't legal for a // global to be marked constant in some modules and non-constant in others. // GV may even be a declaration, not a definition. return GV->isConstant(); - return NoAA::pointsToConstantMemory(P); + return NoAA::pointsToConstantMemory(Loc); } /// getModRefBehavior - Return the behavior when calling the given call site. @@ -636,13 +620,13 @@ BasicAliasAnalysis::getModRefBehavior(const Function *F) { /// simple "address taken" analysis on local objects. AliasAnalysis::ModRefResult BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, - const Value *P, unsigned Size) { - assert(notDifferentParent(CS.getInstruction(), P) && + const Location &Loc) { + assert(notDifferentParent(CS.getInstruction(), Loc.Ptr) && "AliasAnalysis query involving multiple functions!"); - const Value *Object = P->getUnderlyingObject(); + const Value *Object = Loc.Ptr->getUnderlyingObject(); - // If this is a tail call and P points to a stack location, we know that + // If this is a tail call and Loc.Ptr points to a stack location, we know that // the tail call cannot access or modify the local stack. // We cannot exclude byval arguments here; these belong to the caller of // the current function not to the current function, and a tail callee @@ -666,11 +650,11 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, !CS.paramHasAttr(ArgNo+1, Attribute::NoCapture)) continue; - // If this is a no-capture pointer argument, see if we can tell that it + // 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. - if (!isNoAlias(cast(CI), UnknownSize, P, UnknownSize)) { + if (!isNoAlias(Location(cast(CI)), Loc)) { PassedAsArg = true; break; } @@ -692,8 +676,8 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, Len = LenCI->getZExtValue(); Value *Dest = II->getArgOperand(0); Value *Src = II->getArgOperand(1); - if (isNoAlias(Dest, Len, P, Size)) { - if (isNoAlias(Src, Len, P, Size)) + if (isNoAlias(Location(Dest, Len), Loc)) { + if (isNoAlias(Location(Src, Len), Loc)) return NoModRef; return Ref; } @@ -705,7 +689,7 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, if (ConstantInt *LenCI = dyn_cast(II->getArgOperand(2))) { unsigned Len = LenCI->getZExtValue(); Value *Dest = II->getArgOperand(0); - if (isNoAlias(Dest, Len, P, Size)) + if (isNoAlias(Location(Dest, Len), Loc)) return NoModRef; } break; @@ -724,7 +708,8 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, if (TD) { Value *Op1 = II->getArgOperand(0); unsigned Op1Size = TD->getTypeStoreSize(Op1->getType()); - if (isNoAlias(Op1, Op1Size, P, Size)) + MDNode *Tag = II->getMetadata(LLVMContext::MD_tbaa); + if (isNoAlias(Location(Op1, Op1Size, Tag), Loc)) return NoModRef; } break; @@ -733,33 +718,27 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, case Intrinsic::invariant_start: { unsigned PtrSize = cast(II->getArgOperand(0))->getZExtValue(); - if (isNoAlias(II->getArgOperand(1), PtrSize, P, Size)) + if (isNoAlias(Location(II->getArgOperand(1), + PtrSize, + II->getMetadata(LLVMContext::MD_tbaa)), + Loc)) return NoModRef; break; } case Intrinsic::invariant_end: { unsigned PtrSize = cast(II->getArgOperand(1))->getZExtValue(); - if (isNoAlias(II->getArgOperand(2), PtrSize, P, Size)) + if (isNoAlias(Location(II->getArgOperand(2), + PtrSize, + II->getMetadata(LLVMContext::MD_tbaa)), + Loc)) return NoModRef; break; } } // The AliasAnalysis base class has some smarts, lets use them. - return AliasAnalysis::getModRefInfo(CS, P, Size); -} - -AliasAnalysis::DependenceResult -BasicAliasAnalysis::getDependence(const Instruction *First, - const Value *FirstPHITranslatedAddr, - DependenceQueryFlags FirstFlags, - const Instruction *Second, - const Value *SecondPHITranslatedAddr, - DependenceQueryFlags SecondFlags) { - // We don't have anything special to say yet. - return getDependenceViaModRefInfo(First, FirstPHITranslatedAddr, FirstFlags, - Second, SecondPHITranslatedAddr, SecondFlags); + return AliasAnalysis::getModRefInfo(CS, Loc); } /// aliasGEP - Provide a bunch of ad-hoc rules to disambiguate a GEP instruction @@ -1103,7 +1082,7 @@ BasicAliasAnalysis::aliasCheck(const Value *V1, unsigned V1Size, if (const SelectInst *S1 = dyn_cast(V1)) return aliasSelect(S1, V1Size, V2, V2Size); - return NoAA::alias(V1, V1Size, V2, V2Size); + return NoAA::alias(Location(V1, V1Size), Location(V2, V2Size)); } // Make sure that anything that uses AliasAnalysis pulls in this file. diff --git a/lib/Analysis/IPA/GlobalsModRef.cpp b/lib/Analysis/IPA/GlobalsModRef.cpp index 6759b0afdce..8622c1137ca 100644 --- a/lib/Analysis/IPA/GlobalsModRef.cpp +++ b/lib/Analysis/IPA/GlobalsModRef.cpp @@ -106,10 +106,9 @@ namespace { //------------------------------------------------ // Implement the AliasAnalysis API // - AliasResult alias(const Value *V1, unsigned V1Size, - const Value *V2, unsigned V2Size); + AliasResult alias(const Location &LocA, const Location &LocB); ModRefResult getModRefInfo(ImmutableCallSite CS, - const Value *P, unsigned Size); + const Location &Loc); ModRefResult getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) { return AliasAnalysis::getModRefInfo(CS1, CS2); @@ -476,11 +475,11 @@ void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) { /// other is some random pointer, we know there cannot be an alias, because the /// address of the global isn't taken. AliasAnalysis::AliasResult -GlobalsModRef::alias(const Value *V1, unsigned V1Size, - const Value *V2, unsigned V2Size) { +GlobalsModRef::alias(const Location &LocA, + const Location &LocB) { // Get the base object these pointers point to. - const Value *UV1 = V1->getUnderlyingObject(); - const Value *UV2 = V2->getUnderlyingObject(); + const Value *UV1 = LocA.Ptr->getUnderlyingObject(); + const Value *UV2 = LocB.Ptr->getUnderlyingObject(); // If either of the underlying values is a global, they may be non-addr-taken // globals, which we can answer queries about. @@ -528,17 +527,18 @@ GlobalsModRef::alias(const Value *V1, unsigned V1Size, if ((GV1 || GV2) && GV1 != GV2) return NoAlias; - return AliasAnalysis::alias(V1, V1Size, V2, V2Size); + return AliasAnalysis::alias(LocA, LocB); } AliasAnalysis::ModRefResult GlobalsModRef::getModRefInfo(ImmutableCallSite CS, - const Value *P, unsigned Size) { + const Location &Loc) { unsigned Known = ModRef; // If we are asking for mod/ref info of a direct call with a pointer to a // global we are tracking, return information if we have it. - if (const GlobalValue *GV = dyn_cast(P->getUnderlyingObject())) + if (const GlobalValue *GV = + dyn_cast(Loc.Ptr->getUnderlyingObject())) if (GV->hasLocalLinkage()) if (const Function *F = CS.getCalledFunction()) if (NonAddressTakenGlobals.count(GV)) @@ -547,7 +547,7 @@ GlobalsModRef::getModRefInfo(ImmutableCallSite CS, if (Known == NoModRef) return NoModRef; // No need to query other mod/ref analyses - return ModRefResult(Known & AliasAnalysis::getModRefInfo(CS, P, Size)); + return ModRefResult(Known & AliasAnalysis::getModRefInfo(CS, Loc)); } diff --git a/lib/Analysis/LibCallAliasAnalysis.cpp b/lib/Analysis/LibCallAliasAnalysis.cpp index 7f51202ecb5..62b9f463cbf 100644 --- a/lib/Analysis/LibCallAliasAnalysis.cpp +++ b/lib/Analysis/LibCallAliasAnalysis.cpp @@ -43,8 +43,8 @@ void LibCallAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { /// vs the specified pointer/size. AliasAnalysis::ModRefResult LibCallAliasAnalysis::AnalyzeLibCallDetails(const LibCallFunctionInfo *FI, - ImmutableCallSite CS, const Value *P, - unsigned Size) { + ImmutableCallSite CS, + const Location &Loc) { // If we have a function, check to see what kind of mod/ref effects it // has. Start by including any info globally known about the function. AliasAnalysis::ModRefResult MRInfo = FI->UniversalBehavior; @@ -64,9 +64,9 @@ LibCallAliasAnalysis::AnalyzeLibCallDetails(const LibCallFunctionInfo *FI, if (FI->DetailsType == LibCallFunctionInfo::DoesNot) { // Find out if the pointer refers to a known location. for (unsigned i = 0; Details[i].LocationID != ~0U; ++i) { - const LibCallLocationInfo &Loc = + const LibCallLocationInfo &LocInfo = LCI->getLocationInfo(Details[i].LocationID); - LibCallLocationInfo::LocResult Res = Loc.isLocation(CS, P, Size); + LibCallLocationInfo::LocResult Res = LocInfo.isLocation(CS, Loc); if (Res != LibCallLocationInfo::Yes) continue; // If we find a match against a location that we 'do not' interact with, @@ -85,9 +85,9 @@ LibCallAliasAnalysis::AnalyzeLibCallDetails(const LibCallFunctionInfo *FI, // Find out if the pointer refers to a known location. bool NoneMatch = true; for (unsigned i = 0; Details[i].LocationID != ~0U; ++i) { - const LibCallLocationInfo &Loc = + const LibCallLocationInfo &LocInfo = LCI->getLocationInfo(Details[i].LocationID); - LibCallLocationInfo::LocResult Res = Loc.isLocation(CS, P, Size); + LibCallLocationInfo::LocResult Res = LocInfo.isLocation(CS, Loc); if (Res == LibCallLocationInfo::No) continue; // If we don't know if this pointer points to the location, then we have to @@ -118,7 +118,7 @@ LibCallAliasAnalysis::AnalyzeLibCallDetails(const LibCallFunctionInfo *FI, // AliasAnalysis::ModRefResult LibCallAliasAnalysis::getModRefInfo(ImmutableCallSite CS, - const Value *P, unsigned Size) { + const Location &Loc) { ModRefResult MRInfo = ModRef; // If this is a direct call to a function that LCI knows about, get the @@ -126,12 +126,12 @@ LibCallAliasAnalysis::getModRefInfo(ImmutableCallSite CS, if (LCI) { if (const Function *F = CS.getCalledFunction()) { if (const LibCallFunctionInfo *FI = LCI->getFunctionInfo(F)) { - MRInfo = ModRefResult(MRInfo & AnalyzeLibCallDetails(FI, CS, P, Size)); + MRInfo = ModRefResult(MRInfo & AnalyzeLibCallDetails(FI, CS, Loc)); if (MRInfo == NoModRef) return NoModRef; } } } // The AliasAnalysis base class has some smarts, lets use them. - return (ModRefResult)(MRInfo | AliasAnalysis::getModRefInfo(CS, P, Size)); + return (ModRefResult)(MRInfo | AliasAnalysis::getModRefInfo(CS, Loc)); } diff --git a/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp b/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp index 93b2a8b06fb..d7ecdde3e6c 100644 --- a/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp +++ b/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp @@ -49,8 +49,7 @@ namespace { private: virtual void getAnalysisUsage(AnalysisUsage &AU) const; virtual bool runOnFunction(Function &F); - virtual AliasResult alias(const Value *V1, unsigned V1Size, - const Value *V2, unsigned V2Size); + virtual AliasResult alias(const Location &LocA, const Location &LocB); Value *GetBaseValue(const SCEV *S); }; @@ -101,17 +100,17 @@ ScalarEvolutionAliasAnalysis::GetBaseValue(const SCEV *S) { } AliasAnalysis::AliasResult -ScalarEvolutionAliasAnalysis::alias(const Value *A, unsigned ASize, - const Value *B, unsigned BSize) { +ScalarEvolutionAliasAnalysis::alias(const Location &LocA, + const Location &LocB) { // If either of the memory references is empty, it doesn't matter what the // pointer values are. This allows the code below to ignore this special // case. - if (ASize == 0 || BSize == 0) + if (LocA.Size == 0 || LocB.Size == 0) return NoAlias; // This is ScalarEvolutionAliasAnalysis. Get the SCEVs! - const SCEV *AS = SE->getSCEV(const_cast(A)); - const SCEV *BS = SE->getSCEV(const_cast(B)); + const SCEV *AS = SE->getSCEV(const_cast(LocA.Ptr)); + const SCEV *BS = SE->getSCEV(const_cast(LocB.Ptr)); // If they evaluate to the same expression, it's a MustAlias. if (AS == BS) return MustAlias; @@ -121,8 +120,8 @@ ScalarEvolutionAliasAnalysis::alias(const Value *A, unsigned ASize, if (SE->getEffectiveSCEVType(AS->getType()) == SE->getEffectiveSCEVType(BS->getType())) { unsigned BitWidth = SE->getTypeSizeInBits(AS->getType()); - APInt ASizeInt(BitWidth, ASize); - APInt BSizeInt(BitWidth, BSize); + APInt ASizeInt(BitWidth, LocA.Size); + APInt BSizeInt(BitWidth, LocB.Size); // Compute the difference between the two pointers. const SCEV *BA = SE->getMinusSCEV(BS, AS); @@ -154,11 +153,15 @@ ScalarEvolutionAliasAnalysis::alias(const Value *A, unsigned ASize, // inttoptr and ptrtoint operators. Value *AO = GetBaseValue(AS); Value *BO = GetBaseValue(BS); - if ((AO && AO != A) || (BO && BO != B)) - if (alias(AO ? AO : A, AO ? UnknownSize : ASize, - BO ? BO : B, BO ? UnknownSize : BSize) == NoAlias) + if ((AO && AO != LocA.Ptr) || (BO && BO != LocB.Ptr)) + if (alias(Location(AO ? AO : LocA.Ptr, + AO ? +UnknownSize : LocA.Size, + AO ? 0 : LocA.TBAATag), + Location(BO ? BO : LocB.Ptr, + BO ? +UnknownSize : LocB.Size, + BO ? 0 : LocB.TBAATag)) == NoAlias) return NoAlias; // Forward the query to the next analysis. - return AliasAnalysis::alias(A, ASize, B, BSize); + return AliasAnalysis::alias(LocA, LocB); } diff --git a/lib/Analysis/TypeBasedAliasAnalysis.cpp b/lib/Analysis/TypeBasedAliasAnalysis.cpp index bbfdcec3f9b..f6c8201c035 100644 --- a/lib/Analysis/TypeBasedAliasAnalysis.cpp +++ b/lib/Analysis/TypeBasedAliasAnalysis.cpp @@ -96,9 +96,8 @@ namespace { private: virtual void getAnalysisUsage(AnalysisUsage &AU) const; - virtual AliasResult alias(const Value *V1, unsigned V1Size, - const Value *V2, unsigned V2Size); - virtual bool pointsToConstantMemory(const Value *P); + virtual AliasResult alias(const Location &LocA, const Location &LocB); + virtual bool pointsToConstantMemory(const Location &Loc); }; } // End of anonymous namespace @@ -118,12 +117,12 @@ TypeBasedAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { } AliasAnalysis::AliasResult -TypeBasedAliasAnalysis::alias(const Value *A, unsigned ASize, - const Value *B, unsigned BSize) { +TypeBasedAliasAnalysis::alias(const Location &LocA, + const Location &LocB) { // Currently, metadata can only be attached to Instructions. - const Instruction *AI = dyn_cast(A); + const Instruction *AI = dyn_cast(LocA.Ptr); if (!AI) return MayAlias; - const Instruction *BI = dyn_cast(B); + const Instruction *BI = dyn_cast(LocB.Ptr); if (!BI) return MayAlias; // Get the attached MDNodes. If either value lacks a tbaa MDNode, we must @@ -175,9 +174,9 @@ TypeBasedAliasAnalysis::alias(const Value *A, unsigned ASize, return MayAlias; } -bool TypeBasedAliasAnalysis::pointsToConstantMemory(const Value *P) { +bool TypeBasedAliasAnalysis::pointsToConstantMemory(const Location &Loc) { // Currently, metadata can only be attached to Instructions. - const Instruction *I = dyn_cast(P); + const Instruction *I = dyn_cast(Loc.Ptr); if (!I) return false; MDNode *M = diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp index 60fb830e9b5..15ae0ec5d5a 100644 --- a/lib/VMCore/LLVMContext.cpp +++ b/lib/VMCore/LLVMContext.cpp @@ -28,9 +28,16 @@ LLVMContext& llvm::getGlobalContext() { } LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { - // Create the first metadata kind, which is always 'dbg'. + // Create the fixed metadata kinds. This is done in the same order as the + // MD_* enum values so that they correspond. + + // Create the 'dbg' metadata kind. unsigned DbgID = getMDKindID("dbg"); assert(DbgID == MD_dbg && "dbg kind id drifted"); (void)DbgID; + + // Create the 'tbaa' metadata kind. + unsigned TBAAID = getMDKindID("tbaa"); + assert(TBAAID == MD_tbaa && "tbaa kind id drifted"); (void)TBAAID; } LLVMContext::~LLVMContext() { delete pImpl; }