diff options
author | Dan Gohman <gohman@apple.com> | 2010-09-14 21:25:10 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2010-09-14 21:25:10 +0000 |
commit | b2143b6247901ae4eca2192ee134564c4f5f7853 (patch) | |
tree | 7991b48f4a6ee8090de80fbb9cb17c6ed75d6227 /include/llvm/Analysis | |
parent | fe3ac088ee0a536f60b3c30ad97703d5d6cd2167 (diff) | |
download | llvm-b2143b6247901ae4eca2192ee134564c4f5f7853.tar.gz llvm-b2143b6247901ae4eca2192ee134564c4f5f7853.tar.bz2 llvm-b2143b6247901ae4eca2192ee134564c4f5f7853.tar.xz |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113858 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/Analysis')
-rw-r--r-- | include/llvm/Analysis/AliasAnalysis.h | 235 | ||||
-rw-r--r-- | include/llvm/Analysis/LibCallAliasAnalysis.h | 4 | ||||
-rw-r--r-- | include/llvm/Analysis/LibCallSemantics.h | 2 |
3 files changed, 111 insertions, 130 deletions
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index a03e0c8806..cae7addd3b 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 Location &LocA, const Location &LocB) { + return alias(LocA, LocB) == NoAlias; + } + + /// isNoAlias - A convenience wrapper. bool isNoAlias(const Value *V1, unsigned V1Size, const Value *V2, unsigned V2Size) { - return alias(V1, V1Size, V2, V2Size) == NoAlias; + return isNoAlias(Location(V1, V1Size), Location(V2, V2Size)); } - /// pointsToConstantMemory - If the specified pointer is known to point into - /// constant global memory, return true. This allows disambiguation of store + /// 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 @@ -278,100 +340,30 @@ public: 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 c9adf3f36a..7d7782ab7c 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 31d7cc56ce..f5a9e96cbd 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 |