static unsigned node_hash(GepNode *N) { // Include everything except flags and parent. FoldingSetNodeID ID; ID.AddPointer(N->Idx); ID.AddPointer(N->PTy); return ID.ComputeHash(); }
/// Creates a hash-code for the function which is the same for any two /// functions that will compare equal, without looking at the instructions /// inside the function. static unsigned profileFunction(const Function *F) { FunctionType *FTy = F->getFunctionType(); FoldingSetNodeID ID; ID.AddInteger(F->size()); ID.AddInteger(F->getCallingConv()); ID.AddBoolean(F->hasGC()); ID.AddBoolean(FTy->isVarArg()); ID.AddInteger(getTypeIDForHash(FTy->getReturnType())); for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) ID.AddInteger(getTypeIDForHash(FTy->getParamType(i))); return ID.ComputeHash(); }
MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Value*> Vals, FunctionLocalness FL, bool Insert) { LLVMContextImpl *pImpl = Context.pImpl; // Add all the operand pointers. Note that we don't have to add the // isFunctionLocal bit because that's implied by the operands. // Note that if the operands are later nulled out, the node will be // removed from the uniquing map. FoldingSetNodeID ID; for (unsigned i = 0; i != Vals.size(); ++i) ID.AddPointer(Vals[i]); void *InsertPoint; MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); if (N || !Insert) return N; bool isFunctionLocal = false; switch (FL) { case FL_Unknown: for (unsigned i = 0; i != Vals.size(); ++i) { Value *V = Vals[i]; if (!V) continue; if (isFunctionLocalValue(V)) { isFunctionLocal = true; break; } } break; case FL_No: isFunctionLocal = false; break; case FL_Yes: isFunctionLocal = true; break; } // Coallocate space for the node and Operands together, then placement new. 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); return N; }
// Replace value from this node's operand list. void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) { Value *From = *Op; // If is possible that someone did GV->RAUW(inst), replacing a global variable // with an instruction or some other function-local object. If this is a // non-function-local MDNode, it can't point to a function-local object. // Handle this case by implicitly dropping the MDNode reference to null. // Likewise if the MDNode is function-local but for a different function. if (To && isFunctionLocalValue(To)) { if (!isFunctionLocal()) To = 0; else { const Function *F = getFunction(); const Function *FV = getFunctionForValue(To); // Metadata can be function-local without having an associated function. // So only consider functions to have changed if non-null. if (F && FV && F != FV) To = 0; } } if (From == To) return; // Update the operand. Op->set(To); // If this node is already not being uniqued (because one of the operands // already went to null), then there is nothing else to do here. if (isNotUniqued()) return; LLVMContextImpl *pImpl = getType()->getContext().pImpl; // Remove "this" from the context map. FoldingSet doesn't have to reprofile // this node to remove it, so we don't care what state the operands are in. pImpl->MDNodeSet.RemoveNode(this); // If we are dropping an argument to null, we choose to not unique the MDNode // anymore. This commonly occurs during destruction, and uniquing these // brings little reuse. Also, this means we don't need to include // isFunctionLocal bits in FoldingSetNodeIDs for MDNodes. if (To == 0) { setIsNotUniqued(); return; } // Now that the node is out of the folding set, get ready to reinsert it. // First, check to see if another node with the same operands already exists // in the set. If so, then this node is redundant. FoldingSetNodeID ID; Profile(ID); void *InsertPoint; if (MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint)) { replaceAllUsesWith(N); destroy(); return; } // Cache the operand hash. Hash = ID.ComputeHash(); // InsertPoint will have been set by the FindNodeOrInsertPos call. pImpl->MDNodeSet.InsertNode(this, InsertPoint); // If this MDValue was previously function-local but no longer is, clear // its function-local flag. if (isFunctionLocal() && !isFunctionLocalValue(To)) { bool isStillFunctionLocal = false; for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { Value *V = getOperand(i); if (!V) continue; if (isFunctionLocalValue(V)) { isStillFunctionLocal = true; break; } } if (!isStillFunctionLocal) setValueSubclassData(getSubclassDataFromValue() & ~FunctionLocalBit); } }
unsigned DenseMapInfo<DebugLoc>::getHashValue(const DebugLoc &Key) { FoldingSetNodeID ID; ID.AddInteger(Key.LineCol); ID.AddInteger(Key.ScopeIdx); return ID.ComputeHash(); }