diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index f521862b1a54c..156f6eb49253d 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -323,6 +323,10 @@ class DIAssignID : public MDNode { // This node has no operands to replace. void replaceOperandWith(unsigned I, Metadata *New) = delete; + SmallVector getAllDPValueUsers() { + return Context.getReplaceableUses()->getAllDPValueUsers(); + } + static DIAssignID *getDistinct(LLVMContext &Context) { return getImpl(Context, Distinct); } diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h index b512451d385f6..befb6975ca18d 100644 --- a/llvm/include/llvm/IR/Metadata.h +++ b/llvm/include/llvm/IR/Metadata.h @@ -1057,6 +1057,7 @@ struct TempMDNodeDeleter { class MDNode : public Metadata { friend class ReplaceableMetadataImpl; friend class LLVMContextImpl; + friend class DIAssignID; /// The header that is coallocated with an MDNode along with its "small" /// operands. It is located immediately before the main body of the node. @@ -1239,7 +1240,8 @@ class MDNode : public Metadata { bool isDistinct() const { return Storage == Distinct; } bool isTemporary() const { return Storage == Temporary; } - bool isReplaceable() const { return isTemporary(); } + bool isReplaceable() const { return isTemporary() || isAlwaysReplaceable(); } + bool isAlwaysReplaceable() const { return getMetadataID() == DIAssignIDKind; } /// RAUW a temporary. /// diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 6b7dd74916517..e4fcf7acebc06 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -1793,13 +1793,6 @@ void at::deleteAssignmentMarkers(const Instruction *Inst) { } void at::RAUW(DIAssignID *Old, DIAssignID *New) { - // Replace MetadataAsValue uses. - if (auto *OldIDAsValue = - MetadataAsValue::getIfExists(Old->getContext(), Old)) { - auto *NewIDAsValue = MetadataAsValue::get(Old->getContext(), New); - OldIDAsValue->replaceAllUsesWith(NewIDAsValue); - } - // Replace attachments. AssignmentInstRange InstRange = getAssignmentInsts(Old); // Use intermediate storage for the instruction ptrs because the @@ -1808,6 +1801,8 @@ void at::RAUW(DIAssignID *Old, DIAssignID *New) { SmallVector InstVec(InstRange.begin(), InstRange.end()); for (auto *I : InstVec) I->setMetadata(LLVMContext::MD_DIAssignID, New); + + Old->replaceAllUsesWith(New); } void at::deleteAll(Function *F) { diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp index c8f01da30b99a..a9f64f5442341 100644 --- a/llvm/lib/IR/Metadata.cpp +++ b/llvm/lib/IR/Metadata.cpp @@ -439,16 +439,22 @@ void ReplaceableMetadataImpl::resolveAllUses(bool ResolveUsers) { // commentry in DIArgList::handleChangedOperand for details. Hidden behind // conditional compilation to avoid a compile time regression. ReplaceableMetadataImpl *ReplaceableMetadataImpl::getOrCreate(Metadata &MD) { - if (auto *N = dyn_cast(&MD)) - return N->isResolved() ? nullptr : N->Context.getOrCreateReplaceableUses(); + if (auto *N = dyn_cast(&MD)) { + return !N->isResolved() || N->isAlwaysReplaceable() + ? N->Context.getOrCreateReplaceableUses() + : nullptr; + } if (auto ArgList = dyn_cast(&MD)) return ArgList; return dyn_cast(&MD); } ReplaceableMetadataImpl *ReplaceableMetadataImpl::getIfExists(Metadata &MD) { - if (auto *N = dyn_cast(&MD)) - return N->isResolved() ? nullptr : N->Context.getReplaceableUses(); + if (auto *N = dyn_cast(&MD)) { + return !N->isResolved() || N->isAlwaysReplaceable() + ? N->Context.getReplaceableUses() + : nullptr; + } if (auto ArgList = dyn_cast(&MD)) return ArgList; return dyn_cast(&MD); @@ -456,7 +462,7 @@ ReplaceableMetadataImpl *ReplaceableMetadataImpl::getIfExists(Metadata &MD) { bool ReplaceableMetadataImpl::isReplaceable(const Metadata &MD) { if (auto *N = dyn_cast(&MD)) - return !N->isResolved(); + return !N->isResolved() || N->isAlwaysReplaceable(); return isa(&MD) || isa(&MD); } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 49241160456cb..49106da7d2420 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -172,6 +172,11 @@ struct VerifierSupport { } } + void Write(const DPValue *V) { + if (V) + V->print(*OS, MST, false); + } + void Write(const Metadata *MD) { if (!MD) return; @@ -4723,6 +4728,12 @@ void Verifier::visitDIAssignIDMetadata(Instruction &I, MDNode *MD) { "dbg.assign not in same function as inst", DAI, &I); } } + for (DPValue *DPV : cast(MD)->getAllDPValueUsers()) { + CheckDI(DPV->isDbgAssign(), + "!DIAssignID should only be used by Assign DPVs.", MD, DPV); + CheckDI(DPV->getFunction() == I.getFunction(), + "DPVAssign not in same function as inst", DPV, &I); + } } void Verifier::visitCallStackMetadata(MDNode *MD) {