Index: include/llvm/Analysis/MemoryDependenceAnalysis.h =================================================================== --- include/llvm/Analysis/MemoryDependenceAnalysis.h +++ include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -15,7 +15,8 @@ #define LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/PointerSumType.h" +#include "llvm/ADT/PointerEmbeddedInt.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/IR/BasicBlock.h" @@ -38,8 +39,16 @@ /// answers, described below. class MemDepResult { enum DepType { - /// Invalid - Clients of MemDep never see this. - Invalid = 0, + /// Dirty - Entries with this marker are never exposed to users of this + /// interface, but occur in a LocalDeps map or NonLocalDeps map when the + /// instruction they previously referenced was removed from MemDep. In + /// either case, the entry may include an instruction pointer. If so, the + /// pointer is an instruction in the block where scanning can start from, + /// saving some work. + /// + /// In a default-constructed MemDepResult object, the type will be Dirty + /// and the instruction pointer will be null. + Dirty = 0, /// Clobber - This is a dependence on the specified instruction which /// clobbers the desired value. The pointer member of the MemDepResult @@ -73,9 +82,10 @@ Def, /// Other - This marker indicates that the query has no known dependency - /// in the specified block. More detailed state info is encoded in the - /// upper part of the pair (i.e. the Instruction*) + /// in the specified block. More detailed state info is provided as + /// a PointerEmbeddedInt. Other + }; /// If DepType is "Other", the upper part of the pair /// (i.e. the Instruction* part) is instead used to encode more detailed @@ -84,80 +94,90 @@ /// NonLocal - This marker indicates that the query has no dependency in /// the specified block. To find out more, the client should query other /// predecessor blocks. - NonLocal = 0x4, + NonLocal = 1, + /// NonFuncLocal - This marker indicates that the query has no /// dependency in the specified function. - NonFuncLocal = 0x8, + NonFuncLocal, + /// Unknown - This marker indicates that the query dependency /// is unknown. - Unknown = 0xc + Unknown }; - typedef PointerIntPair PairTy; - PairTy Value; - explicit MemDepResult(PairTy V) : Value(V) {} + typedef PointerSumType< + DepType, PointerSumTypeMember, + PointerSumTypeMember, + PointerSumTypeMember, + PointerSumTypeMember>> + ValueTy; + ValueTy Value; + explicit MemDepResult(ValueTy V) : Value(V) {} public: - MemDepResult() : Value(nullptr, Invalid) {} + MemDepResult() : Value() {} /// get methods: These are static ctor methods for creating various /// MemDepResult kinds. static MemDepResult getDef(Instruction *Inst) { assert(Inst && "Def requires inst"); - return MemDepResult(PairTy(Inst, Def)); + return MemDepResult(ValueTy::create(Inst)); } static MemDepResult getClobber(Instruction *Inst) { assert(Inst && "Clobber requires inst"); - return MemDepResult(PairTy(Inst, Clobber)); + return MemDepResult(ValueTy::create(Inst)); } static MemDepResult getNonLocal() { - return MemDepResult( - PairTy(reinterpret_cast(NonLocal), Other)); + return MemDepResult(ValueTy::create(NonLocal)); } static MemDepResult getNonFuncLocal() { - return MemDepResult( - PairTy(reinterpret_cast(NonFuncLocal), Other)); + return MemDepResult(ValueTy::create(NonFuncLocal)); } static MemDepResult getUnknown() { - return MemDepResult( - PairTy(reinterpret_cast(Unknown), Other)); + return MemDepResult(ValueTy::create(Unknown)); } /// isClobber - Return true if this MemDepResult represents a query that is /// an instruction clobber dependency. - bool isClobber() const { return Value.getInt() == Clobber; } + bool isClobber() const { return Value.is(); } /// isDef - Return true if this MemDepResult represents a query that is /// an instruction definition dependency. - bool isDef() const { return Value.getInt() == Def; } + bool isDef() const { return Value.is(); } /// isNonLocal - Return true if this MemDepResult represents a query that /// is transparent to the start of the block, but where a non-local hasn't /// been done. bool isNonLocal() const { - return Value.getInt() == Other - && Value.getPointer() == reinterpret_cast(NonLocal); + return Value.is() && Value.cast() == NonLocal; } /// isNonFuncLocal - Return true if this MemDepResult represents a query /// that is transparent to the start of the function. bool isNonFuncLocal() const { - return Value.getInt() == Other - && Value.getPointer() == reinterpret_cast(NonFuncLocal); + return Value.is() && Value.cast() == NonFuncLocal; } /// isUnknown - Return true if this MemDepResult represents a query which /// cannot and/or will not be computed. bool isUnknown() const { - return Value.getInt() == Other - && Value.getPointer() == reinterpret_cast(Unknown); + return Value.is() && Value.cast() == Unknown; } /// getInst() - If this is a normal dependency, return the instruction that /// is depended on. Otherwise, return null. Instruction *getInst() const { - if (Value.getInt() == Other) return nullptr; - return Value.getPointer(); + switch (Value.getTag()) { + case Dirty: + return Value.cast(); + case Clobber: + return Value.cast(); + case Def: + return Value.cast(); + case Other: + return nullptr; + } + llvm_unreachable("Unknown discriminant!"); } bool operator==(const MemDepResult &M) const { return Value == M.Value; } @@ -167,22 +187,13 @@ private: friend class MemoryDependenceAnalysis; - /// Dirty - Entries with this marker occur in a LocalDeps map or - /// NonLocalDeps map when the instruction they previously referenced was - /// removed from MemDep. In either case, the entry may include an - /// instruction pointer. If so, the pointer is an instruction in the - /// block where scanning can start from, saving some work. - /// - /// In a default-constructed MemDepResult object, the type will be Dirty - /// and the instruction pointer will be null. - /// /// isDirty - Return true if this is a MemDepResult in its dirty/invalid. /// state. - bool isDirty() const { return Value.getInt() == Invalid; } + bool isDirty() const { return Value.is(); } static MemDepResult getDirty(Instruction *Inst) { - return MemDepResult(PairTy(Inst, Invalid)); + return MemDepResult(ValueTy::create(Inst)); } };