diff options
| -rw-r--r-- | llvm/include/llvm/IR/Metadata.h | 21 | ||||
| -rw-r--r-- | llvm/lib/IR/Metadata.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Utils/ValueMapper.cpp | 13 |
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(); + } } } |

