diff options
Diffstat (limited to 'llvm/lib/IR/LLVMContextImpl.h')
-rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 62 |
1 files changed, 46 insertions, 16 deletions
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 3190c22fceb..48343b2989e 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -22,6 +22,7 @@ #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/SmallPtrSet.h" @@ -190,23 +191,52 @@ struct FunctionTypeKeyInfo { } }; -// Provide a FoldingSetTrait::Equals specialization for MDNode that can use a -// shortcut to avoid comparing all operands. -template<> struct FoldingSetTrait<MDNode> : DefaultFoldingSetTrait<MDNode> { - static bool Equals(const MDNode &X, const FoldingSetNodeID &ID, - unsigned IDHash, FoldingSetNodeID &TempID) { - assert(!X.isNotUniqued() && "Non-uniqued MDNode in FoldingSet?"); - // First, check if the cached hashes match. If they don't we can skip the - // expensive operand walk. - if (X.Hash != IDHash) - return false; +/// \brief DenseMapInfo for MDNode. +/// +/// Note that we don't need the is-function-local bit, since that's implicit in +/// the operands. +struct GenericMDNodeInfo { + struct KeyTy { + ArrayRef<Value *> Ops; + unsigned Hash; + + KeyTy(ArrayRef<Value *> Ops) + : Ops(Ops), Hash(hash_combine_range(Ops.begin(), Ops.end())) {} + + KeyTy(MDNode *N, SmallVectorImpl<Value *> &Storage) { + Storage.resize(N->getNumOperands()); + for (unsigned I = 0, E = N->getNumOperands(); I != E; ++I) + Storage[I] = N->getOperand(I); + Ops = Storage; + Hash = hash_combine_range(Ops.begin(), Ops.end()); + } - // If they match we have to compare the operands. - X.Profile(TempID); - return TempID == ID; + bool operator==(const MDNode *RHS) const { + if (RHS == getEmptyKey() || RHS == getTombstoneKey()) + return false; + if (Hash != RHS->getHash() || Ops.size() != RHS->getNumOperands()) + return false; + for (unsigned I = 0, E = Ops.size(); I != E; ++I) + if (Ops[I] != RHS->getOperand(I)) + return false; + return true; + } + }; + static inline MDNode *getEmptyKey() { + return DenseMapInfo<MDNode *>::getEmptyKey(); + } + static inline MDNode *getTombstoneKey() { + return DenseMapInfo<MDNode *>::getTombstoneKey(); + } + static unsigned getHashValue(const KeyTy &Key) { return Key.Hash; } + static unsigned getHashValue(const MDNode *U) { + return U->getHash(); } - static unsigned ComputeHash(const MDNode &X, FoldingSetNodeID &) { - return X.Hash; // Return cached hash. + static bool isEqual(const KeyTy &LHS, const MDNode *RHS) { + return LHS == RHS; + } + static bool isEqual(const MDNode *LHS, const MDNode *RHS) { + return LHS == RHS; } }; @@ -263,7 +293,7 @@ public: StringMap<MDString> MDStringCache; - FoldingSet<MDNode> MDNodeSet; + DenseSet<MDNode *, GenericMDNodeInfo> MDNodeSet; // MDNodes may be uniqued or not uniqued. When they're not uniqued, they // aren't in the MDNodeSet, but they're still shared between objects, so no |