diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2015-02-10 19:13:46 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2015-02-10 19:13:46 +0000 |
commit | 4ee4a98eaae16bbf9041acd3bc0f605b03d196e2 (patch) | |
tree | d96a528b2f7d05c661b4ebd3084552754202c905 /llvm/lib/IR/Metadata.cpp | |
parent | 82f1c775a074feaa724948cbc1795336deaa2b4f (diff) | |
download | bcm5719-llvm-4ee4a98eaae16bbf9041acd3bc0f605b03d196e2.tar.gz bcm5719-llvm-4ee4a98eaae16bbf9041acd3bc0f605b03d196e2.zip |
IR: Add MDNode::replaceWithPermanent()
Add new API for converting temporaries that may self-reference.
Self-referencing nodes are not allowed to be uniqued, so sending them
into `replaceWithUniqued()` is dangerous (and this commit adds
assertions that prevent it).
`replaceWithPermanent()` has similar semantics to `get()` followed by
calls to `replaceOperandWith()`. In particular, if there's a
self-reference, it returns a distinct node; otherwise, it returns a
uniqued one. Like `replaceWithUniqued()` and `replaceWithDistinct()`
(well, it calls out to them) it mutates the temporary node in place if
possible, only calling `replaceAllUsesWith()` on a uniquing collision.
llvm-svn: 228726
Diffstat (limited to 'llvm/lib/IR/Metadata.cpp')
-rw-r--r-- | llvm/lib/IR/Metadata.cpp | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp index d5be35a53a0..0ad3c5c04ba 100644 --- a/llvm/lib/IR/Metadata.cpp +++ b/llvm/lib/IR/Metadata.cpp @@ -518,9 +518,23 @@ void MDNode::resolveCycles() { } } +static bool hasSelfReference(MDNode *N) { + for (Metadata *MD : N->operands()) + if (MD == N) + return true; + return false; +} + +MDNode *MDNode::replaceWithPermanentImpl() { + if (hasSelfReference(this)) + return replaceWithDistinctImpl(); + return replaceWithUniquedImpl(); +} + MDNode *MDNode::replaceWithUniquedImpl() { // Try to uniquify in place. MDNode *UniquedNode = uniquify(); + if (UniquedNode == this) { makeUniqued(); return this; @@ -633,6 +647,8 @@ template <class NodeTy> struct MDNode::HasCachedHash { }; MDNode *MDNode::uniquify() { + assert(!hasSelfReference(this) && "Cannot uniquify a self-referencing node"); + // Try to insert into uniquing store. switch (getMetadataID()) { default: |