summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/IR/Metadata.h21
-rw-r--r--llvm/lib/IR/Metadata.cpp2
-rw-r--r--llvm/lib/Transforms/Utils/ValueMapper.cpp13
3 files changed, 30 insertions, 6 deletions
diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h
index 4a8557d074f..df8ce354bb7 100644
--- a/llvm/include/llvm/IR/Metadata.h
+++ b/llvm/include/llvm/IR/Metadata.h
@@ -915,11 +915,21 @@ public:
/// \brief Resolve cycles.
///
/// Once all forward declarations have been resolved, force cycles to be
- /// resolved. If \p AllowTemps is true, then any temporary metadata
- /// is ignored, otherwise it asserts when encountering temporary metadata.
+ /// resolved. This interface is used when there are no more temporaries,
+ /// and thus unresolved nodes are part of cycles and no longer need RAUW
+ /// support.
///
/// \pre No operands (or operands' operands, etc.) have \a isTemporary().
- void resolveCycles(bool AllowTemps = false);
+ void resolveCycles() { resolveRecursivelyImpl(/* AllowTemps */ false); }
+
+ /// \brief Resolve cycles while ignoring temporaries.
+ ///
+ /// This drops RAUW support for any temporaries, which can no longer
+ /// be uniqued.
+ ///
+ void resolveNonTemporaries() {
+ resolveRecursivelyImpl(/* AllowTemps */ true);
+ }
/// \brief Replace a temporary node with a permanent one.
///
@@ -977,6 +987,11 @@ private:
void decrementUnresolvedOperandCount();
unsigned countUnresolvedOperands();
+ /// Resolve cycles recursively. If \p AllowTemps is true, then any temporary
+ /// metadata is ignored, otherwise it asserts when encountering temporary
+ /// metadata.
+ void resolveRecursivelyImpl(bool AllowTemps);
+
/// \brief Mutate this to be "uniqued".
///
/// Mutate this so that \a isUniqued().
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index d8eaceb9ea2..9a9a5017841 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -557,7 +557,7 @@ void MDNode::decrementUnresolvedOperandCount() {
resolve();
}
-void MDNode::resolveCycles(bool AllowTemps) {
+void MDNode::resolveRecursivelyImpl(bool AllowTemps) {
if (isResolved())
return;
diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp
index 2e361d38ed0..f47ddb9f064 100644
--- a/llvm/lib/Transforms/Utils/ValueMapper.cpp
+++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp
@@ -222,8 +222,17 @@ static void resolveCycles(Metadata *MD, bool AllowTemps) {
if (auto *N = dyn_cast_or_null<MDNode>(MD)) {
if (AllowTemps && N->isTemporary())
return;
- if (!N->isResolved())
- N->resolveCycles(AllowTemps);
+ if (!N->isResolved()) {
+ if (AllowTemps)
+ // Note that this will drop RAUW support on any temporaries, which
+ // blocks uniquing. If this ends up being an issue, in the future
+ // we can experiment with delaying resolving these nodes until
+ // after metadata is fully materialized (i.e. when linking metadata
+ // as a postpass after function importing).
+ N->resolveNonTemporaries();
+ else
+ N->resolveCycles();
+ }
}
}
OpenPOWER on IntegriCloud