diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h index eca908a24aac7..810f3668d05d4 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 3d9ee1c33e946..50ba00cf8df3e 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::iterator; SmallVector Args; - DIArgList(LLVMContext &C, StorageType Storage, - ArrayRef Args) - : MDNode(C, DIArgListKind, Storage, std::nullopt), + DIArgList(LLVMContext &Context, ArrayRef Args) + : Metadata(DIArgListKind, Uniqued), ReplaceableMetadataImpl(Context), Args(Args.begin(), Args.end()) { track(); } ~DIArgList() { untrack(); } - static DIArgList *getImpl(LLVMContext &Context, - ArrayRef 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 Args), (Args)) - - TempDIArgList clone() const { return cloneImpl(); } + static DIArgList *get(LLVMContext &Context, ArrayRef Args); ArrayRef 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 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 36c34c1d2347c..a3cfb9ad6e3e7 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 a245dabe086f0..4498423c4c460 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 f9df70fb6fc09..b12074375461b 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -5486,13 +5486,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(); @@ -5512,7 +5508,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; } @@ -5626,13 +5622,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 d16b5c7781c24..9c21cc69179e5 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 &Record, unsigned Abbrev); - void writeDIArgList(const DIArgList *N, SmallVectorImpl &Record, - unsigned Abbrev); + void writeDIArgList(const DIArgList *N, SmallVectorImpl &Record); void writeDIModule(const DIModule *N, SmallVectorImpl &Record, unsigned Abbrev); void writeDIAssignID(const DIAssignID *N, SmallVectorImpl &Record, @@ -1975,13 +1974,12 @@ void ModuleBitcodeWriter::writeDIMacroFile(const DIMacroFile *N, } void ModuleBitcodeWriter::writeDIArgList(const DIArgList *N, - SmallVectorImpl &Record, - unsigned Abbrev) { + SmallVectorImpl &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(MD)) { + writeDIArgList(AL, Record); + continue; + } writeValueAsMetadata(cast(MD), Record); } } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 6d66b34423949..a7d667d79880c 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -1265,9 +1265,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(N) || isa(N)) + // Don't make slots for DIExpressions. We just print them inline everywhere. + if (isa(N)) return; unsigned DestSlot = mdnNext; @@ -3516,8 +3515,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(Op) && - "DIArgLists should not appear in NamedMDNodes"); if (auto *Expr = dyn_cast(Op)) { writeDIExpression(Out, Expr, AsmWriterContext::getEmpty()); continue; @@ -4918,7 +4915,7 @@ static void printMetadataImplRec(raw_ostream &ROS, const Metadata &MD, WriteAsOperandInternal(OS, &MD, WriterCtx, /* FromValue */ true); auto *N = dyn_cast(&MD); - if (!N || isa(MD) || isa(MD)) + if (!N || isa(MD)) return; OS << " = "; @@ -4986,7 +4983,7 @@ static void printMetadataImpl(raw_ostream &ROS, const Metadata &MD, WriteAsOperandInternal(OS, &MD, *WriterCtx, /* FromValue */ true); auto *N = dyn_cast(&MD); - if (OnlyAsOperand || !N || isa(MD) || isa(MD)) + if (OnlyAsOperand || !N || isa(MD)) return; OS << " = "; diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 927aefb8bd477..c507346710b8d 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 Args, - StorageType Storage, bool ShouldCreate) { - DEFINE_GETIMPL_LOOKUP(DIArgList, (Args)); - DEFINE_GETIMPL_STORE_NO_OPS(DIArgList, (Args)); +DIArgList *DIArgList::get(LLVMContext &Context, + ArrayRef 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(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(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 406850b7de248..993deafe66270 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(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,10 @@ 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); // Destroy MDNodes. for (MDNode *I : DistinctMDNodes) diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index ebc444fcb6896..b55107beba556 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -1308,11 +1308,13 @@ template <> struct MDNodeKeyImpl { } }; -template <> struct MDNodeKeyImpl { +// DIArgLists are not MDNodes, but we still want to unique them in a DenseSet +// based on a hash of their arguments. +struct DIArgListKeyInfo { ArrayRef Args; - MDNodeKeyImpl(ArrayRef Args) : Args(Args) {} - MDNodeKeyImpl(const DIArgList *N) : Args(N->getArgs()) {} + DIArgListKeyInfo(ArrayRef 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 { } }; +/// DenseMapInfo for DIArgList. +struct DIArgListInfo { + using KeyTy = DIArgListKeyInfo; + + static inline DIArgList *getEmptyKey() { + return DenseMapInfo::getEmptyKey(); + } + + static inline DIArgList *getTombstoneKey() { + return DenseMapInfo::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 struct MDNodeInfo { using KeyTy = MDNodeKeyImpl; @@ -1471,6 +1502,7 @@ class LLVMContextImpl { StringMap MDStringCache; DenseMap ValuesAsMetadata; DenseMap MetadataAsValues; + DenseSet DIArgLists; #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \ DenseSet CLASS##s; diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp index e040387fceb74..415e256c817b8 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(&MD)) - return ArgList->Context.getOrCreateReplaceableUses(); -#endif if (auto *N = dyn_cast(&MD)) return N->isResolved() ? nullptr : N->Context.getOrCreateReplaceableUses(); + if (auto ArgList = dyn_cast(&MD)) + return ArgList; return dyn_cast(&MD); } ReplaceableMetadataImpl *ReplaceableMetadataImpl::getIfExists(Metadata &MD) { -#ifdef EXPERIMENTAL_DEBUGINFO_ITERATORS - if (auto *ArgList = dyn_cast(&MD)) - return ArgList->Context.getReplaceableUses(); -#endif if (auto *N = dyn_cast(&MD)) return N->isResolved() ? nullptr : N->Context.getReplaceableUses(); + if (auto ArgList = dyn_cast(&MD)) + return ArgList; return dyn_cast(&MD); } bool ReplaceableMetadataImpl::isReplaceable(const Metadata &MD) { -#ifdef EXPERIMENTAL_DEBUGINFO_ITERATORS - if (isa(&MD)) - return true; -#endif if (auto *N = dyn_cast(&MD)) return !N->isResolved(); - return isa(&MD); + return isa(&MD) || isa(&MD); } static DISubprogram *getLocalFunctionMetadata(Value *V) { diff --git a/llvm/lib/IR/TypeFinder.cpp b/llvm/lib/IR/TypeFinder.cpp index 904af7e737ccf..003155a4af487 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(M->getMetadata())) return incorporateValue(MDV->getValue()); + if (const auto *AL = dyn_cast(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(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 25981d8dccb11..5560c037aa3ee 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -483,6 +483,7 @@ class Verifier : public InstVisitor, 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(MD)) { @@ -1060,6 +1066,9 @@ void Verifier::visitMetadataAsValue(const MetadataAsValue &MDV, Function *F) { if (auto *V = dyn_cast(MD)) visitValueAsMetadata(*V, F); + + if (auto *AL = dyn_cast(MD)) + visitDIArgList(*AL, F); } static bool isType(const Metadata *MD) { return !MD || isa(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);