summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/Metadata.cpp
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-02-10 19:13:46 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-02-10 19:13:46 +0000
commit4ee4a98eaae16bbf9041acd3bc0f605b03d196e2 (patch)
treed96a528b2f7d05c661b4ebd3084552754202c905 /llvm/lib/IR/Metadata.cpp
parent82f1c775a074feaa724948cbc1795336deaa2b4f (diff)
downloadbcm5719-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.cpp16
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:
OpenPOWER on IntegriCloud