[llvm-commits] [llvm] r154497 - in /llvm/trunk: include/llvm/Metadata.h lib/VMCore/LLVMContextImpl.h lib/VMCore/Metadata.cpp

Benjamin Kramer benny.kra at googlemail.com
Wed Apr 11 07:06:54 PDT 2012


Author: d0k
Date: Wed Apr 11 09:06:54 2012
New Revision: 154497

URL: http://llvm.org/viewvc/llvm-project?rev=154497&view=rev
Log:
Cache the hash value of the operands in the MDNode.

FoldingSet is implemented as a chained hash table. When there is a hash
collision during insertion, which is common as we fill the table until a
load factor of 2.0 is hit, we walk the chained elements, comparing every
operand with the new element's operands. This can be very expensive if the
MDNode has many operands.

We sacrifice a word of space in MDNode to cache the full hash value, reducing
compares on collision to a minimum. MDNode grows from 28 to 32 bytes + operands
on x86. On x86_64 the new bits fit nicely into existing padding, not growing
the struct at all.

The actual speedup depends a lot on the test case and is typically between
1% and 2% for C++ code with clang -c -O0 -g.

Modified:
    llvm/trunk/include/llvm/Metadata.h
    llvm/trunk/lib/VMCore/LLVMContextImpl.h
    llvm/trunk/lib/VMCore/Metadata.cpp

Modified: llvm/trunk/include/llvm/Metadata.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Metadata.h?rev=154497&r1=154496&r2=154497&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Metadata.h (original)
+++ llvm/trunk/include/llvm/Metadata.h Wed Apr 11 09:06:54 2012
@@ -75,6 +75,10 @@
   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.

Modified: llvm/trunk/lib/VMCore/LLVMContextImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/LLVMContextImpl.h?rev=154497&r1=154496&r2=154497&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/LLVMContextImpl.h (original)
+++ llvm/trunk/lib/VMCore/LLVMContextImpl.h Wed Apr 11 09:06:54 2012
@@ -194,6 +194,26 @@
   }
 };
 
+// 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 {

Modified: llvm/trunk/lib/VMCore/Metadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Metadata.cpp?rev=154497&r1=154496&r2=154497&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Metadata.cpp (original)
+++ llvm/trunk/lib/VMCore/Metadata.cpp Wed Apr 11 09:06:54 2012
@@ -250,6 +250,9 @@
   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 @@
     return;
   }
 
+  // Cache the operand hash.
+  Hash = ID.ComputeHash();
   // InsertPoint will have been set by the FindNodeOrInsertPos call.
   pImpl->MDNodeSet.InsertNode(this, InsertPoint);
 





More information about the llvm-commits mailing list