diff options
| -rw-r--r-- | llvm/include/llvm/Metadata.h | 4 | ||||
| -rw-r--r-- | llvm/lib/VMCore/LLVMContextImpl.h | 20 | ||||
| -rw-r--r-- | llvm/lib/VMCore/Metadata.cpp | 5 | 
3 files changed, 29 insertions, 0 deletions
diff --git a/llvm/include/llvm/Metadata.h b/llvm/include/llvm/Metadata.h index 0d438522ab1..7f232a3c986 100644 --- a/llvm/include/llvm/Metadata.h +++ b/llvm/include/llvm/Metadata.h @@ -75,6 +75,10 @@ class MDNode : public Value, public FoldingSetNode {    void operator=(const MDNode &);        // DO NOT IMPLEMENT    friend class MDNodeOperand;    friend class LLVMContextImpl; +  friend struct FoldingSetTrait<MDNode>; + +  /// NumOperands - If the MDNode is uniqued cache the hash to speed up lookup. +  unsigned Hash;    /// NumOperands - This many 'MDNodeOperand' items are co-allocated onto the    /// end of this MDNode. diff --git a/llvm/lib/VMCore/LLVMContextImpl.h b/llvm/lib/VMCore/LLVMContextImpl.h index 1a4bf6d7b44..2252028b156 100644 --- a/llvm/lib/VMCore/LLVMContextImpl.h +++ b/llvm/lib/VMCore/LLVMContextImpl.h @@ -194,6 +194,26 @@ 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; + +    // If they match we have to compare the operands. +    X.Profile(TempID); +    return TempID == ID; +  } +  static unsigned ComputeHash(const MDNode &X, FoldingSetNodeID &) { +    return X.Hash; // Return cached hash. +  } +}; +  /// DebugRecVH - This is a CallbackVH used to keep the Scope -> index maps  /// up to date as MDNodes mutate.  This class is implemented in DebugLoc.cpp.  class DebugRecVH : public CallbackVH { diff --git a/llvm/lib/VMCore/Metadata.cpp b/llvm/lib/VMCore/Metadata.cpp index 55de0dc6515..090b09a4ccd 100644 --- a/llvm/lib/VMCore/Metadata.cpp +++ b/llvm/lib/VMCore/Metadata.cpp @@ -250,6 +250,9 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Value*> Vals,    void *Ptr = malloc(sizeof(MDNode)+Vals.size()*sizeof(MDNodeOperand));    N = new (Ptr) MDNode(Context, Vals, isFunctionLocal); +  // Cache the operand hash. +  N->Hash = ID.ComputeHash(); +    // InsertPoint will have been set by the FindNodeOrInsertPos call.    pImpl->MDNodeSet.InsertNode(N, InsertPoint); @@ -373,6 +376,8 @@ void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) {      return;    } +  // Cache the operand hash. +  Hash = ID.ComputeHash();    // InsertPoint will have been set by the FindNodeOrInsertPos call.    pImpl->MDNodeSet.InsertNode(this, InsertPoint);  | 

