summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-12-07 19:52:06 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-12-07 19:52:06 +0000
commitac8ee289eb5438bdc222252f3e45f156c6b6730e (patch)
treeb454cd450bb525bd2f6c4648e7a8170ca5775fb8 /llvm/lib/IR
parentd06c165bb20ab669d6f94c3207d57dcd9b5cb7ed (diff)
downloadbcm5719-llvm-ac8ee289eb5438bdc222252f3e45f156c6b6730e.tar.gz
bcm5719-llvm-ac8ee289eb5438bdc222252f3e45f156c6b6730e.zip
IR: Drop uniquing for self-referencing MDNodes
It doesn't make sense to unique self-referencing nodes. Drop uniquing for them. Note that `MDNode::intersect()` occasionally returns self-referencing nodes. Previously these would be returned by `MDNode::get()`. I'm not convinced this was intended behaviour -- to me it seems it should return a node whose only operand is the self-reference -- but I don't know much about alias scopes so I'm preserving it for now. This is part of PR21532. llvm-svn: 223618
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r--llvm/lib/IR/Metadata.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index e5dfaec74e5..70415b01016 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -353,7 +353,9 @@ void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) {
// anymore. This commonly occurs during destruction, and uniquing these
// brings little reuse. Also, this means we don't need to include
// isFunctionLocal bits in the hash for MDNodes.
- if (!To) {
+ //
+ // Also drop uniquing if this has a reference to itself.
+ if (!To || To == this) {
setIsNotUniqued();
return;
}
@@ -406,6 +408,18 @@ MDNode *MDNode::intersect(MDNode *A, MDNode *B) {
}
}
+ // Handle alias scope self-references specially.
+ //
+ // FIXME: This preserves long-standing behaviour, but is it really the right
+ // behaviour? Or was that an unintended side-effect of node uniquing?
+ if (!Vals.empty())
+ if (MDNode *N = dyn_cast_or_null<MDNode>(Vals[0]))
+ if (N->getNumOperands() == Vals.size() && N == N->getOperand(0)) {
+ for (unsigned I = 1, E = Vals.size(); I != E; ++I)
+ if (Vals[I] != N->getOperand(I))
+ return MDNode::get(A->getContext(), Vals);
+ return N;
+ }
return MDNode::get(A->getContext(), Vals);
}
OpenPOWER on IntegriCloud