forked from OSchip/llvm-project
do not bother reuniquing mdnodes whose operands drop to null. Doing
so can be a huge performance issue when tearing down modules and mdnodes are not guaranteed to be unique anyway. This speeds up: $ time ~/llvm/Release/bin/clang gcc.c -w -S -g from 72 to 35s, where gcc.c is from: http://people.csail.mit.edu/smcc/projects/single-file-programs/ llvm-svn: 92315
This commit is contained in:
parent
1563a76fd3
commit
30ae06be14
|
@ -85,8 +85,6 @@ class MDNodeElement;
|
|||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// MDNode - a tuple of other values.
|
||||
/// These contain a list of the values that represent the metadata.
|
||||
/// MDNode is always unnamed.
|
||||
class MDNode : public MetadataBase, public FoldingSetNode {
|
||||
MDNode(const MDNode &); // DO NOT IMPLEMENT
|
||||
void operator=(const MDNode &); // DO NOT IMPLEMENT
|
||||
|
@ -97,7 +95,14 @@ class MDNode : public MetadataBase, public FoldingSetNode {
|
|||
|
||||
// Subclass data enums.
|
||||
enum {
|
||||
FunctionLocalBit = 1
|
||||
/// FunctionLocalBit - This bit is set if this MDNode is function local.
|
||||
/// This is true when it (potentially transitively) contains a reference to
|
||||
/// something in a function, like an argument, basicblock, or instruction.
|
||||
FunctionLocalBit = 1 << 0,
|
||||
|
||||
/// NotUniquedBit - This is set on MDNodes that are not uniqued because they
|
||||
/// have a null perand.
|
||||
NotUniquedBit = 1 << 1
|
||||
};
|
||||
|
||||
// Replace each instance of F from the element list of this node with T.
|
||||
|
@ -138,6 +143,13 @@ public:
|
|||
return V->getValueID() == MDNodeVal;
|
||||
}
|
||||
private:
|
||||
bool isNotUniqued() const {
|
||||
return (getSubclassDataFromValue() & NotUniquedBit) != 0;
|
||||
}
|
||||
void setIsNotUniqued() {
|
||||
setValueSubclassData(getSubclassDataFromValue() | NotUniquedBit);
|
||||
}
|
||||
|
||||
// Shadow Value::setValueSubclassData with a private forwarding method so that
|
||||
// any future subclasses cannot accidentally use it.
|
||||
void setValueSubclassData(unsigned short D) {
|
||||
|
|
|
@ -87,8 +87,10 @@ void MDNodeElement::allUsesReplacedWith(Value *NV) {
|
|||
|
||||
/// ~MDNode - Destroy MDNode.
|
||||
MDNode::~MDNode() {
|
||||
LLVMContextImpl *pImpl = getType()->getContext().pImpl;
|
||||
pImpl->MDNodeSet.RemoveNode(this);
|
||||
if (!isNotUniqued()) {
|
||||
LLVMContextImpl *pImpl = getType()->getContext().pImpl;
|
||||
pImpl->MDNodeSet.RemoveNode(this);
|
||||
}
|
||||
delete [] Operands;
|
||||
Operands = NULL;
|
||||
}
|
||||
|
@ -97,6 +99,7 @@ MDNode::MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
|
|||
bool isFunctionLocal)
|
||||
: MetadataBase(Type::getMetadataTy(C), Value::MDNodeVal) {
|
||||
NumOperands = NumVals;
|
||||
// FIXME: Coallocate the operand list. These have fixed arity.
|
||||
Operands = new MDNodeElement[NumOperands];
|
||||
|
||||
for (unsigned i = 0; i != NumVals; ++i)
|
||||
|
@ -146,25 +149,40 @@ void MDNode::replaceElement(MDNodeElement *Op, Value *To) {
|
|||
if (From == To)
|
||||
return;
|
||||
|
||||
// Update the operand.
|
||||
Op->set(To, this);
|
||||
|
||||
// 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);
|
||||
|
||||
// Update the operand.
|
||||
Op->set(To, this);
|
||||
|
||||
// Insert updated "this" into the context's folding node set.
|
||||
// If a node with same element list already exist then before inserting
|
||||
// updated "this" into the folding node set, replace all uses of existing
|
||||
// node with updated "this" node.
|
||||
// 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.
|
||||
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 it doesn't exist, this returns the position to insert it.
|
||||
FoldingSetNodeID ID;
|
||||
Profile(ID);
|
||||
void *InsertPoint;
|
||||
MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
|
||||
|
||||
if (N) {
|
||||
// FIXME:
|
||||
// If it already exists in the set, we don't reinsert it, we just claim it
|
||||
// isn't uniqued.
|
||||
|
||||
N->replaceAllUsesWith(this);
|
||||
delete N;
|
||||
N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
|
||||
|
|
Loading…
Reference in New Issue