llvm.org GIT mirror llvm / 611afc0
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154497 91177308-0d34-0410-b5e6-96231b3b80d8 Benjamin Kramer 8 years ago
3 changed file(s) with 29 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
7474 void operator=(const MDNode &); // DO NOT IMPLEMENT
7575 friend class MDNodeOperand;
7676 friend class LLVMContextImpl;
77 friend struct FoldingSetTrait;
78
79 /// NumOperands - If the MDNode is uniqued cache the hash to speed up lookup.
80 unsigned Hash;
7781
7882 /// NumOperands - This many 'MDNodeOperand' items are co-allocated onto the
7983 /// end of this MDNode.
193193 }
194194 };
195195
196 // Provide a FoldingSetTrait::Equals specialization for MDNode that can use a
197 // shortcut to avoid comparing all operands.
198 template<> struct FoldingSetTrait : DefaultFoldingSetTrait {
199 static bool Equals(const MDNode &X, const FoldingSetNodeID &ID,
200 unsigned IDHash, FoldingSetNodeID &TempID) {
201 assert(!X.isNotUniqued() && "Non-uniqued MDNode in FoldingSet?");
202 // First, check if the cached hashes match. If they don't we can skip the
203 // expensive operand walk.
204 if (X.Hash != IDHash)
205 return false;
206
207 // If they match we have to compare the operands.
208 X.Profile(TempID);
209 return TempID == ID;
210 }
211 static unsigned ComputeHash(const MDNode &X, FoldingSetNodeID &) {
212 return X.Hash; // Return cached hash.
213 }
214 };
215
196216 /// DebugRecVH - This is a CallbackVH used to keep the Scope -> index maps
197217 /// up to date as MDNodes mutate. This class is implemented in DebugLoc.cpp.
198218 class DebugRecVH : public CallbackVH {
249249 void *Ptr = malloc(sizeof(MDNode)+Vals.size()*sizeof(MDNodeOperand));
250250 N = new (Ptr) MDNode(Context, Vals, isFunctionLocal);
251251
252 // Cache the operand hash.
253 N->Hash = ID.ComputeHash();
254
252255 // InsertPoint will have been set by the FindNodeOrInsertPos call.
253256 pImpl->MDNodeSet.InsertNode(N, InsertPoint);
254257
372375 return;
373376 }
374377
378 // Cache the operand hash.
379 Hash = ID.ComputeHash();
375380 // InsertPoint will have been set by the FindNodeOrInsertPos call.
376381 pImpl->MDNodeSet.InsertNode(this, InsertPoint);
377382