[llvm] f99a020 - Reapply "[DebugInfo] Make DIArgList inherit from Metadata and always unique"
Stephen Tozer via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 17 09:55:56 PST 2023
Author: Stephen Tozer
Date: 2023-11-17T17:55:41Z
New Revision: f99a02005970cdcb0aad0de80fa4e5b546c6546b
URL: https://github.com/llvm/llvm-project/commit/f99a02005970cdcb0aad0de80fa4e5b546c6546b
DIFF: https://github.com/llvm/llvm-project/commit/f99a02005970cdcb0aad0de80fa4e5b546c6546b.diff
LOG: Reapply "[DebugInfo] Make DIArgList inherit from Metadata and always unique"
This reverts commit 0fd5dc94380d5fe666dc6c603b4bb782cef743e7.
The original commit removed DIArgLists from being in an MDNode map, but did
not insert a new `delete` in the LLVMContextImpl destructor. This
reapply adds that call to delete, preventing a memory leak.
Added:
Modified:
llvm/include/llvm/AsmParser/LLParser.h
llvm/include/llvm/IR/DebugInfoMetadata.h
llvm/include/llvm/IR/Metadata.def
llvm/include/llvm/IR/Metadata.h
llvm/lib/AsmParser/LLParser.cpp
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
llvm/lib/IR/AsmWriter.cpp
llvm/lib/IR/DebugInfoMetadata.cpp
llvm/lib/IR/LLVMContextImpl.cpp
llvm/lib/IR/LLVMContextImpl.h
llvm/lib/IR/Metadata.cpp
llvm/lib/IR/TypeFinder.cpp
llvm/lib/IR/Verifier.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h
index eca908a24aac7b2..810f3668d05d449 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -548,6 +548,7 @@ namespace llvm {
bool parseMetadataAsValue(Value *&V, PerFunctionState &PFS);
bool parseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg,
PerFunctionState *PFS);
+ bool parseDIArgList(Metadata *&MD, PerFunctionState *PFS);
bool parseMetadata(Metadata *&MD, PerFunctionState *PFS);
bool parseMDTuple(MDNode *&MD, bool IsDistinct = false);
bool parseMDNode(MDNode *&N);
@@ -569,8 +570,6 @@ namespace llvm {
#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) \
bool parse##CLASS(MDNode *&Result, bool IsDistinct);
#include "llvm/IR/Metadata.def"
- bool parseDIArgList(MDNode *&Result, bool IsDistinct,
- PerFunctionState *PFS);
// Function Parsing.
struct ArgInfo {
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index 3d9ee1c33e9461e..50ba00cf8df3e96 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -3753,51 +3753,40 @@ class DIMacroFile : public DIMacroNode {
/// List of ValueAsMetadata, to be used as an argument to a dbg.value
/// intrinsic.
-class DIArgList : public MDNode {
+class DIArgList : public Metadata, ReplaceableMetadataImpl {
+ friend class ReplaceableMetadataImpl;
friend class LLVMContextImpl;
- friend class MDNode;
using iterator = SmallVectorImpl<ValueAsMetadata *>::iterator;
SmallVector<ValueAsMetadata *, 4> Args;
- DIArgList(LLVMContext &C, StorageType Storage,
- ArrayRef<ValueAsMetadata *> Args)
- : MDNode(C, DIArgListKind, Storage, std::nullopt),
+ DIArgList(LLVMContext &Context, ArrayRef<ValueAsMetadata *> Args)
+ : Metadata(DIArgListKind, Uniqued), ReplaceableMetadataImpl(Context),
Args(Args.begin(), Args.end()) {
track();
}
~DIArgList() { untrack(); }
- static DIArgList *getImpl(LLVMContext &Context,
- ArrayRef<ValueAsMetadata *> Args,
- StorageType Storage, bool ShouldCreate = true);
-
- TempDIArgList cloneImpl() const {
- return getTemporary(getContext(), getArgs());
- }
-
void track();
void untrack();
- void dropAllReferences();
+ void dropAllReferences(bool Untrack);
public:
- DEFINE_MDNODE_GET(DIArgList, (ArrayRef<ValueAsMetadata *> Args), (Args))
-
- TempDIArgList clone() const { return cloneImpl(); }
+ static DIArgList *get(LLVMContext &Context, ArrayRef<ValueAsMetadata *> Args);
ArrayRef<ValueAsMetadata *> getArgs() const { return Args; }
iterator args_begin() { return Args.begin(); }
iterator args_end() { return Args.end(); }
- ReplaceableMetadataImpl *getReplaceableUses() {
- return Context.getReplaceableUses();
- }
-
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIArgListKind;
}
+ SmallVector<DPValue *> getAllDPValueUsers() {
+ return ReplaceableMetadataImpl::getAllDPValueUsers();
+ }
+
void handleChangedOperand(void *Ref, Metadata *New);
};
diff --git a/llvm/include/llvm/IR/Metadata.def b/llvm/include/llvm/IR/Metadata.def
index 36c34c1d2347c08..a3cfb9ad6e3e785 100644
--- a/llvm/include/llvm/IR/Metadata.def
+++ b/llvm/include/llvm/IR/Metadata.def
@@ -77,6 +77,7 @@ HANDLE_METADATA_BRANCH(ValueAsMetadata)
HANDLE_METADATA_LEAF(ConstantAsMetadata)
HANDLE_METADATA_LEAF(LocalAsMetadata)
HANDLE_METADATA_LEAF(DistinctMDOperandPlaceholder)
+HANDLE_METADATA_LEAF(DIArgList)
HANDLE_MDNODE_BRANCH(MDNode)
HANDLE_MDNODE_LEAF_UNIQUABLE(MDTuple)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILocation)
@@ -115,7 +116,6 @@ HANDLE_SPECIALIZED_MDNODE_BRANCH(DIMacroNode)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacro)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacroFile)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DICommonBlock)
-HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIArgList)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIStringType)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIGenericSubrange)
diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h
index a245dabe086f045..4498423c4c460d9 100644
--- a/llvm/include/llvm/IR/Metadata.h
+++ b/llvm/include/llvm/IR/Metadata.h
@@ -1037,7 +1037,6 @@ struct TempMDNodeDeleter {
class MDNode : public Metadata {
friend class ReplaceableMetadataImpl;
friend class LLVMContextImpl;
- friend class DIArgList;
/// The header that is coallocated with an MDNode along with its "small"
/// operands. It is located immediately before the main body of the node.
@@ -1220,9 +1219,7 @@ class MDNode : public Metadata {
bool isDistinct() const { return Storage == Distinct; }
bool isTemporary() const { return Storage == Temporary; }
- bool isReplaceable() const {
- return isTemporary() || getMetadataID() == DIArgListKind;
- }
+ bool isReplaceable() const { return isTemporary(); }
/// RAUW a temporary.
///
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index a09d19c11c6eb31..2d2c1bf65311c01 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -5488,13 +5488,9 @@ bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) {
return false;
}
-bool LLParser::parseDIArgList(MDNode *&Result, bool IsDistinct) {
- return parseDIArgList(Result, IsDistinct, nullptr);
-}
/// ParseDIArgList:
/// ::= !DIArgList(i32 7, i64 %0)
-bool LLParser::parseDIArgList(MDNode *&Result, bool IsDistinct,
- PerFunctionState *PFS) {
+bool LLParser::parseDIArgList(Metadata *&MD, PerFunctionState *PFS) {
assert(PFS && "Expected valid function state");
assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
Lex.Lex();
@@ -5514,7 +5510,7 @@ bool LLParser::parseDIArgList(MDNode *&Result, bool IsDistinct,
if (parseToken(lltok::rparen, "expected ')' here"))
return true;
- Result = GET_OR_DISTINCT(DIArgList, (Context, Args));
+ MD = DIArgList::get(Context, Args);
return false;
}
@@ -5628,13 +5624,17 @@ bool LLParser::parseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg,
/// ::= !DILocation(...)
bool LLParser::parseMetadata(Metadata *&MD, PerFunctionState *PFS) {
if (Lex.getKind() == lltok::MetadataVar) {
- MDNode *N;
// DIArgLists are a special case, as they are a list of ValueAsMetadata and
// so parsing this requires a Function State.
if (Lex.getStrVal() == "DIArgList") {
- if (parseDIArgList(N, false, PFS))
+ Metadata *AL;
+ if (parseDIArgList(AL, PFS))
return true;
- } else if (parseSpecializedMDNode(N)) {
+ MD = AL;
+ return false;
+ }
+ MDNode *N;
+ if (parseSpecializedMDNode(N)) {
return true;
}
MD = N;
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index d16b5c7781c2413..9c21cc69179e555 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -336,8 +336,7 @@ class ModuleBitcodeWriter : public ModuleBitcodeWriterBase {
unsigned Abbrev);
void writeDIMacroFile(const DIMacroFile *N, SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev);
- void writeDIArgList(const DIArgList *N, SmallVectorImpl<uint64_t> &Record,
- unsigned Abbrev);
+ void writeDIArgList(const DIArgList *N, SmallVectorImpl<uint64_t> &Record);
void writeDIModule(const DIModule *N, SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev);
void writeDIAssignID(const DIAssignID *N, SmallVectorImpl<uint64_t> &Record,
@@ -1975,13 +1974,12 @@ void ModuleBitcodeWriter::writeDIMacroFile(const DIMacroFile *N,
}
void ModuleBitcodeWriter::writeDIArgList(const DIArgList *N,
- SmallVectorImpl<uint64_t> &Record,
- unsigned Abbrev) {
+ SmallVectorImpl<uint64_t> &Record) {
Record.reserve(N->getArgs().size());
for (ValueAsMetadata *MD : N->getArgs())
Record.push_back(VE.getMetadataID(MD));
- Stream.EmitRecord(bitc::METADATA_ARG_LIST, Record, Abbrev);
+ Stream.EmitRecord(bitc::METADATA_ARG_LIST, Record);
Record.clear();
}
@@ -2264,6 +2262,10 @@ void ModuleBitcodeWriter::writeMetadataRecords(
#include "llvm/IR/Metadata.def"
}
}
+ if (auto *AL = dyn_cast<DIArgList>(MD)) {
+ writeDIArgList(AL, Record);
+ continue;
+ }
writeValueAsMetadata(cast<ValueAsMetadata>(MD), Record);
}
}
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index f681e8b99436667..c37adb423397059 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1266,9 +1266,8 @@ void SlotTracker::CreateFunctionSlot(const Value *V) {
void SlotTracker::CreateMetadataSlot(const MDNode *N) {
assert(N && "Can't insert a null Value into SlotTracker!");
- // Don't make slots for DIExpressions or DIArgLists. We just print them inline
- // everywhere.
- if (isa<DIExpression>(N) || isa<DIArgList>(N))
+ // Don't make slots for DIExpressions. We just print them inline everywhere.
+ if (isa<DIExpression>(N))
return;
unsigned DestSlot = mdnNext;
@@ -3517,8 +3516,6 @@ void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) {
// Write DIExpressions inline.
// FIXME: Ban DIExpressions in NamedMDNodes, they will serve no purpose.
MDNode *Op = NMD->getOperand(i);
- assert(!isa<DIArgList>(Op) &&
- "DIArgLists should not appear in NamedMDNodes");
if (auto *Expr = dyn_cast<DIExpression>(Op)) {
writeDIExpression(Out, Expr, AsmWriterContext::getEmpty());
continue;
@@ -4919,7 +4916,7 @@ static void printMetadataImplRec(raw_ostream &ROS, const Metadata &MD,
WriteAsOperandInternal(OS, &MD, WriterCtx, /* FromValue */ true);
auto *N = dyn_cast<MDNode>(&MD);
- if (!N || isa<DIExpression>(MD) || isa<DIArgList>(MD))
+ if (!N || isa<DIExpression>(MD))
return;
OS << " = ";
@@ -4987,7 +4984,7 @@ static void printMetadataImpl(raw_ostream &ROS, const Metadata &MD,
WriteAsOperandInternal(OS, &MD, *WriterCtx, /* FromValue */ true);
auto *N = dyn_cast<MDNode>(&MD);
- if (OnlyAsOperand || !N || isa<DIExpression>(MD) || isa<DIArgList>(MD))
+ if (OnlyAsOperand || !N || isa<DIExpression>(MD))
return;
OS << " = ";
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index 927aefb8bd47772..c507346710b8d52 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -2115,11 +2115,14 @@ DIMacroFile *DIMacroFile::getImpl(LLVMContext &Context, unsigned MIType,
DEFINE_GETIMPL_STORE(DIMacroFile, (MIType, Line), Ops);
}
-DIArgList *DIArgList::getImpl(LLVMContext &Context,
- ArrayRef<ValueAsMetadata *> Args,
- StorageType Storage, bool ShouldCreate) {
- DEFINE_GETIMPL_LOOKUP(DIArgList, (Args));
- DEFINE_GETIMPL_STORE_NO_OPS(DIArgList, (Args));
+DIArgList *DIArgList::get(LLVMContext &Context,
+ ArrayRef<ValueAsMetadata *> Args) {
+ auto ExistingIt = Context.pImpl->DIArgLists.find_as(DIArgListKeyInfo(Args));
+ if (ExistingIt != Context.pImpl->DIArgLists.end())
+ return *ExistingIt;
+ DIArgList *NewArgList = new DIArgList(Context, Args);
+ Context.pImpl->DIArgLists.insert(NewArgList);
+ return NewArgList;
}
void DIArgList::handleChangedOperand(void *Ref, Metadata *New) {
@@ -2127,12 +2130,9 @@ void DIArgList::handleChangedOperand(void *Ref, Metadata *New) {
assert((!New || isa<ValueAsMetadata>(New)) &&
"DIArgList must be passed a ValueAsMetadata");
untrack();
- bool Uniq = isUniqued();
- if (Uniq) {
- // We need to update the uniqueness once the Args are updated since they
- // form the key to the DIArgLists store.
- eraseFromStore();
- }
+ // We need to update the set storage once the Args are updated since they
+ // form the key to the DIArgLists store.
+ getContext().pImpl->DIArgLists.erase(this);
ValueAsMetadata *NewVM = cast_or_null<ValueAsMetadata>(New);
for (ValueAsMetadata *&VM : Args) {
if (&VM == OldVMPtr) {
@@ -2142,28 +2142,19 @@ void DIArgList::handleChangedOperand(void *Ref, Metadata *New) {
VM = ValueAsMetadata::get(PoisonValue::get(VM->getValue()->getType()));
}
}
- if (Uniq) {
- // In the RemoveDIs project (eliminating debug-info-intrinsics), DIArgLists
- // can be referred to by DebugValueUser objects, which necessitates them
- // being unique and replaceable metadata. This causes a slight
- // performance regression that's to be avoided during the early stages of
- // the RemoveDIs prototype, see D154080.
-#ifdef EXPERIMENTAL_DEBUGINFO_ITERATORS
- MDNode *UniqueArgList = uniquify();
- if (UniqueArgList != this) {
- replaceAllUsesWith(UniqueArgList);
- // Clear this here so we don't try to untrack in the destructor.
- Args.clear();
- delete this;
- return;
- }
-#else
- // Otherwise, don't fully unique, become distinct instead. See D108968,
- // there's a latent bug that presents here as nondeterminism otherwise.
- if (uniquify() != this)
- storeDistinctInContext();
-#endif
+ // We've changed the contents of this DIArgList, and the set storage may
+ // already contain a DIArgList with our new set of args; if it does, then we
+ // must RAUW this with the existing DIArgList, otherwise we simply insert this
+ // back into the set storage.
+ DIArgList *ExistingArgList = getUniqued(getContext().pImpl->DIArgLists, this);
+ if (ExistingArgList) {
+ replaceAllUsesWith(ExistingArgList);
+ // Clear this here so we don't try to untrack in the destructor.
+ Args.clear();
+ delete this;
+ return;
}
+ getContext().pImpl->DIArgLists.insert(this);
track();
}
void DIArgList::track() {
@@ -2176,8 +2167,9 @@ void DIArgList::untrack() {
if (VAM)
MetadataTracking::untrack(&VAM, *VAM);
}
-void DIArgList::dropAllReferences() {
- untrack();
+void DIArgList::dropAllReferences(bool Untrack) {
+ if (Untrack)
+ untrack();
Args.clear();
- MDNode::dropAllReferences();
+ ReplaceableMetadataImpl::resolveAllUses(/* ResolveUsers */ false);
}
diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp
index 406850b7de24816..15c90a4fe7b2ec2 100644
--- a/llvm/lib/IR/LLVMContextImpl.cpp
+++ b/llvm/lib/IR/LLVMContextImpl.cpp
@@ -68,15 +68,8 @@ LLVMContextImpl::~LLVMContextImpl() {
// Drop references for MDNodes. Do this before Values get deleted to avoid
// unnecessary RAUW when nodes are still unresolved.
- for (auto *I : DistinctMDNodes) {
- // We may have DIArgList that were uniqued, and as it has a custom
- // implementation of dropAllReferences, it needs to be explicitly invoked.
- if (auto *AL = dyn_cast<DIArgList>(I)) {
- AL->dropAllReferences();
- continue;
- }
+ for (auto *I : DistinctMDNodes)
I->dropAllReferences();
- }
#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
for (auto *I : CLASS##s) \
I->dropAllReferences();
@@ -87,6 +80,13 @@ LLVMContextImpl::~LLVMContextImpl() {
Pair.second->dropUsers();
for (auto &Pair : MetadataAsValues)
Pair.second->dropUse();
+ // Do not untrack ValueAsMetadata references for DIArgLists, as they have
+ // already been more efficiently untracked above.
+ for (DIArgList *AL : DIArgLists) {
+ AL->dropAllReferences(/* Untrack */ false);
+ delete AL;
+ }
+ DIArgLists.clear();
// Destroy MDNodes.
for (MDNode *I : DistinctMDNodes)
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index ebc444fcb6896e9..b55107beba556c8 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -1308,11 +1308,13 @@ template <> struct MDNodeKeyImpl<DIMacroFile> {
}
};
-template <> struct MDNodeKeyImpl<DIArgList> {
+// DIArgLists are not MDNodes, but we still want to unique them in a DenseSet
+// based on a hash of their arguments.
+struct DIArgListKeyInfo {
ArrayRef<ValueAsMetadata *> Args;
- MDNodeKeyImpl(ArrayRef<ValueAsMetadata *> Args) : Args(Args) {}
- MDNodeKeyImpl(const DIArgList *N) : Args(N->getArgs()) {}
+ DIArgListKeyInfo(ArrayRef<ValueAsMetadata *> Args) : Args(Args) {}
+ DIArgListKeyInfo(const DIArgList *N) : Args(N->getArgs()) {}
bool isKeyOf(const DIArgList *RHS) const { return Args == RHS->getArgs(); }
@@ -1321,6 +1323,35 @@ template <> struct MDNodeKeyImpl<DIArgList> {
}
};
+/// DenseMapInfo for DIArgList.
+struct DIArgListInfo {
+ using KeyTy = DIArgListKeyInfo;
+
+ static inline DIArgList *getEmptyKey() {
+ return DenseMapInfo<DIArgList *>::getEmptyKey();
+ }
+
+ static inline DIArgList *getTombstoneKey() {
+ return DenseMapInfo<DIArgList *>::getTombstoneKey();
+ }
+
+ static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); }
+
+ static unsigned getHashValue(const DIArgList *N) {
+ return KeyTy(N).getHashValue();
+ }
+
+ static bool isEqual(const KeyTy &LHS, const DIArgList *RHS) {
+ if (RHS == getEmptyKey() || RHS == getTombstoneKey())
+ return false;
+ return LHS.isKeyOf(RHS);
+ }
+
+ static bool isEqual(const DIArgList *LHS, const DIArgList *RHS) {
+ return LHS == RHS;
+ }
+};
+
/// DenseMapInfo for MDNode subclasses.
template <class NodeTy> struct MDNodeInfo {
using KeyTy = MDNodeKeyImpl<NodeTy>;
@@ -1471,6 +1502,7 @@ class LLVMContextImpl {
StringMap<MDString, BumpPtrAllocator> MDStringCache;
DenseMap<Value *, ValueAsMetadata *> ValuesAsMetadata;
DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues;
+ DenseSet<DIArgList *, DIArgListInfo> DIArgLists;
#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
DenseSet<CLASS *, CLASS##Info> CLASS##s;
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index e040387fceb7436..415e256c817b82f 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -413,33 +413,25 @@ 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) {
-#ifdef EXPERIMENTAL_DEBUGINFO_ITERATORS
- if (auto *ArgList = dyn_cast<DIArgList>(&MD))
- return ArgList->Context.getOrCreateReplaceableUses();
-#endif
if (auto *N = dyn_cast<MDNode>(&MD))
return N->isResolved() ? nullptr : N->Context.getOrCreateReplaceableUses();
+ if (auto ArgList = dyn_cast<DIArgList>(&MD))
+ return ArgList;
return dyn_cast<ValueAsMetadata>(&MD);
}
ReplaceableMetadataImpl *ReplaceableMetadataImpl::getIfExists(Metadata &MD) {
-#ifdef EXPERIMENTAL_DEBUGINFO_ITERATORS
- if (auto *ArgList = dyn_cast<DIArgList>(&MD))
- return ArgList->Context.getReplaceableUses();
-#endif
if (auto *N = dyn_cast<MDNode>(&MD))
return N->isResolved() ? nullptr : N->Context.getReplaceableUses();
+ if (auto ArgList = dyn_cast<DIArgList>(&MD))
+ return ArgList;
return dyn_cast<ValueAsMetadata>(&MD);
}
bool ReplaceableMetadataImpl::isReplaceable(const Metadata &MD) {
-#ifdef EXPERIMENTAL_DEBUGINFO_ITERATORS
- if (isa<DIArgList>(&MD))
- return true;
-#endif
if (auto *N = dyn_cast<MDNode>(&MD))
return !N->isResolved();
- return isa<ValueAsMetadata>(&MD);
+ return isa<ValueAsMetadata>(&MD) || isa<DIArgList>(&MD);
}
static DISubprogram *getLocalFunctionMetadata(Value *V) {
diff --git a/llvm/lib/IR/TypeFinder.cpp b/llvm/lib/IR/TypeFinder.cpp
index 904af7e737ccfca..003155a4af4877b 100644
--- a/llvm/lib/IR/TypeFinder.cpp
+++ b/llvm/lib/IR/TypeFinder.cpp
@@ -136,6 +136,11 @@ void TypeFinder::incorporateValue(const Value *V) {
return incorporateMDNode(N);
if (const auto *MDV = dyn_cast<ValueAsMetadata>(M->getMetadata()))
return incorporateValue(MDV->getValue());
+ if (const auto *AL = dyn_cast<DIArgList>(M->getMetadata())) {
+ for (auto *Arg : AL->getArgs())
+ incorporateValue(Arg->getValue());
+ return;
+ }
return;
}
@@ -168,14 +173,6 @@ void TypeFinder::incorporateMDNode(const MDNode *V) {
if (!VisitedMetadata.insert(V).second)
return;
- // The arguments in DIArgList are not exposed as operands, so handle such
- // nodes specifically here.
- if (const auto *AL = dyn_cast<DIArgList>(V)) {
- for (auto *Arg : AL->getArgs())
- incorporateValue(Arg->getValue());
- return;
- }
-
// Look in operands for types.
for (Metadata *Op : V->operands()) {
if (!Op)
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 25981d8dccb11e7..5560c037aa3ee6b 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -483,6 +483,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
void visitMDNode(const MDNode &MD, AreDebugLocsAllowed AllowLocs);
void visitMetadataAsValue(const MetadataAsValue &MD, Function *F);
void visitValueAsMetadata(const ValueAsMetadata &MD, Function *F);
+ void visitDIArgList(const DIArgList &AL, Function *F);
void visitComdat(const Comdat &C);
void visitModuleIdents();
void visitModuleCommandLines();
@@ -1046,6 +1047,11 @@ void Verifier::visitValueAsMetadata(const ValueAsMetadata &MD, Function *F) {
Check(ActualF == F, "function-local metadata used in wrong function", L);
}
+void Verifier::visitDIArgList(const DIArgList &AL, Function *F) {
+ for (const ValueAsMetadata *VAM : AL.getArgs())
+ visitValueAsMetadata(*VAM, F);
+}
+
void Verifier::visitMetadataAsValue(const MetadataAsValue &MDV, Function *F) {
Metadata *MD = MDV.getMetadata();
if (auto *N = dyn_cast<MDNode>(MD)) {
@@ -1060,6 +1066,9 @@ void Verifier::visitMetadataAsValue(const MetadataAsValue &MDV, Function *F) {
if (auto *V = dyn_cast<ValueAsMetadata>(MD))
visitValueAsMetadata(*V, F);
+
+ if (auto *AL = dyn_cast<DIArgList>(MD))
+ visitDIArgList(*AL, F);
}
static bool isType(const Metadata *MD) { return !MD || isa<DIType>(MD); }
@@ -1512,13 +1521,6 @@ void Verifier::visitDIMacroFile(const DIMacroFile &N) {
}
}
-void Verifier::visitDIArgList(const DIArgList &N) {
- CheckDI(!N.getNumOperands(),
- "DIArgList should have no operands other than a list of "
- "ValueAsMetadata",
- &N);
-}
-
void Verifier::visitDIModule(const DIModule &N) {
CheckDI(N.getTag() == dwarf::DW_TAG_module, "invalid tag", &N);
CheckDI(!N.getName().empty(), "anonymous module", &N);
More information about the llvm-commits
mailing list