563 changes: 306 additions & 257 deletions llvm/include/llvm/IR/DebugInfoMetadata.h

Large diffs are not rendered by default.

79 changes: 73 additions & 6 deletions llvm/include/llvm/IR/Metadata.def
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,39 @@
//
// Macros for running through all types of metadata.
//
// Definitions for terms used to describe metadata include:
//
// * BRANCH: refers to an "abstract" metadata kind, which exists only in the
// C++ class hierarchy. These cannot appear directly in IR/bitcode.
// * LEAF: refers to a "concrete" metadata kind. These can appear directly in
// IR/bitcode.
// * SPECIALIZED: refers to non-MDTuple MDNodes, i.e. those that use the
// syntax "!CLASS(...)" in IR.
// * UNIQUABLE: refers to nodes which can use uniqued, distinct, or temporary
// storage without any restrictions.
// * UNIQUED: refers to nodes which must use uniqued or temporary storage.
// * DISTINCT: refers to nodes which must use distinct or temporary storage.
//
// In LLVM IR, UNIQUABLE and DISTINCT nodes must be referred to by MDNode ID,
// as in `!0`, whereas UNIQUED nodes canonically appear inline at each use, as
// in `DIExpression(...)`. This is because `distinct` nodes maintain their
// identity irrespective of contents, making the inline syntax ambiguous in
// some cases.
//
// Note: UNIQUABLE, UNIQUED, and DISTINCT are mutually exclusive. For example,
// code which intends to consider all nodes which can use uniqued storage must
// consider both UNIQUABLE and UNIQUED nodes.
//
//===----------------------------------------------------------------------===//

#if !(defined HANDLE_METADATA || defined HANDLE_METADATA_LEAF || \
defined HANDLE_METADATA_BRANCH || defined HANDLE_MDNODE_LEAF || \
defined HANDLE_MDNODE_LEAF_UNIQUABLE || defined HANDLE_MDNODE_BRANCH || \
defined HANDLE_MDNODE_LEAF_UNIQUABLE || \
defined HANDLE_MDNODE_LEAF_UNIQUED || \
defined HANDLE_MDNODE_LEAF_DISTINCT || defined HANDLE_MDNODE_BRANCH || \
defined HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE || \
defined HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUED || \
defined HANDLE_SPECIALIZED_MDNODE_LEAF_DISTINCT || \
defined HANDLE_SPECIALIZED_MDNODE_LEAF || \
defined HANDLE_SPECIALIZED_MDNODE_BRANCH)
#error "Missing macro definition of HANDLE_METADATA*"
Expand All @@ -34,7 +61,7 @@
#define HANDLE_METADATA_BRANCH(CLASS) HANDLE_METADATA(CLASS)
#endif

// Handler for specialized and uniquable leaf nodes under MDNode. Defers to
// Handler for specialized and uniquable leaf nodes under MDNode. Defers to
// HANDLE_MDNODE_LEAF_UNIQUABLE if it's defined, otherwise to
// HANDLE_SPECIALIZED_MDNODE_LEAF.
#ifndef HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE
Expand All @@ -47,11 +74,47 @@
#endif
#endif

// Handler for leaf nodes under MDNode.
// Handler for specialized and always-uniqued leaf nodes under MDNode. Defers to
// HANDLE_MDNODE_LEAF_UNIQUED if it's defined, otherwise to
// HANDLE_SPECIALIZED_MDNODE_LEAF.
#ifndef HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUED
#ifdef HANDLE_MDNODE_LEAF_UNIQUED
#define HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUED(CLASS) \
HANDLE_MDNODE_LEAF_UNIQUED(CLASS)
#else
#define HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUED(CLASS) \
HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS)
#endif
#endif

// Handler for specialized and always-distinct leaf nodes under MDNode. Defers
// to HANDLE_MDNODE_LEAF_DISTINCT if it's defined, otherwise to
// HANDLE_SPECIALIZED_MDNODE_LEAF.
#ifndef HANDLE_SPECIALIZED_MDNODE_LEAF_DISTINCT
#ifdef HANDLE_MDNODE_LEAF_DISTINCT
#define HANDLE_SPECIALIZED_MDNODE_LEAF_DISTINCT(CLASS) \
HANDLE_MDNODE_LEAF_DISTINCT(CLASS)
#else
#define HANDLE_SPECIALIZED_MDNODE_LEAF_DISTINCT(CLASS) \
HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS)
#endif
#endif

// Handler for uniquable leaf nodes under MDNode.
#ifndef HANDLE_MDNODE_LEAF_UNIQUABLE
#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) HANDLE_MDNODE_LEAF(CLASS)
#endif

// Handler for uniqued leaf nodes under MDNode.
#ifndef HANDLE_MDNODE_LEAF_UNIQUED
#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) HANDLE_MDNODE_LEAF(CLASS)
#endif

// Handler for distinct leaf nodes under MDNode.
#ifndef HANDLE_MDNODE_LEAF_DISTINCT
#define HANDLE_MDNODE_LEAF_DISTINCT(CLASS) HANDLE_MDNODE_LEAF(CLASS)
#endif

// Handler for leaf nodes under MDNode.
#ifndef HANDLE_MDNODE_LEAF
#define HANDLE_MDNODE_LEAF(CLASS) HANDLE_METADATA_LEAF(CLASS)
Expand Down Expand Up @@ -80,7 +143,7 @@ HANDLE_METADATA_LEAF(DistinctMDOperandPlaceholder)
HANDLE_MDNODE_BRANCH(MDNode)
HANDLE_MDNODE_LEAF_UNIQUABLE(MDTuple)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILocation)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIExpression)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUED(DIExpression)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIGlobalVariableExpression)
HANDLE_SPECIALIZED_MDNODE_BRANCH(DINode)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(GenericDINode)
Expand All @@ -93,7 +156,7 @@ HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIDerivedType)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DICompositeType)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DISubroutineType)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIFile)
HANDLE_SPECIALIZED_MDNODE_LEAF(DICompileUnit)
HANDLE_SPECIALIZED_MDNODE_LEAF_DISTINCT(DICompileUnit)
HANDLE_SPECIALIZED_MDNODE_BRANCH(DILocalScope)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DISubprogram)
HANDLE_SPECIALIZED_MDNODE_BRANCH(DILexicalBlockBase)
Expand All @@ -114,7 +177,7 @@ 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_UNIQUED(DIArgList)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIStringType)
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIGenericSubrange)

Expand All @@ -123,7 +186,11 @@ HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIGenericSubrange)
#undef HANDLE_METADATA_BRANCH
#undef HANDLE_MDNODE_LEAF
#undef HANDLE_MDNODE_LEAF_UNIQUABLE
#undef HANDLE_MDNODE_LEAF_UNIQUED
#undef HANDLE_MDNODE_LEAF_DISTINCT
#undef HANDLE_MDNODE_BRANCH
#undef HANDLE_SPECIALIZED_MDNODE_LEAF
#undef HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE
#undef HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUED
#undef HANDLE_SPECIALIZED_MDNODE_LEAF_DISTINCT
#undef HANDLE_SPECIALIZED_MDNODE_BRANCH
75 changes: 45 additions & 30 deletions llvm/lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -742,27 +742,29 @@ bool LLParser::parseNamedMetadata() {
return true;

NamedMDNode *NMD = M->getOrInsertNamedMetadata(Name);
if (Lex.getKind() != lltok::rbrace)
do {
MDNode *N = nullptr;
// parse DIExpressions inline as a special case. They are still MDNodes,
// so they can still appear in named metadata. Remove this logic if they
// become plain Metadata.
if (Lex.getKind() == lltok::MetadataVar &&
Lex.getStrVal() == "DIExpression") {
if (parseDIExpression(N, /*IsDistinct=*/false))
return true;
// DIArgLists should only appear inline in a function, as they may
// contain LocalAsMetadata arguments which require a function context.
} else if (Lex.getKind() == lltok::MetadataVar &&
Lex.getStrVal() == "DIArgList") {
return tokError("found DIArgList outside of function");
} else if (parseToken(lltok::exclaim, "Expected '!' here") ||
parseMDNodeID(N)) {
return true;
}
NMD->addOperand(N);
} while (EatIfPresent(lltok::comma));

if (Lex.getKind() == lltok::rbrace) {
Lex.Lex();
return false;
}

do {
MDNode *N = nullptr;
// Parse uniqued MDNodes inline as a special case.
#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) \
if (Lex.getKind() == lltok::MetadataVar && Lex.getStrVal() == #CLASS) { \
if (parse##CLASS(N, /*IsDistinct=*/false)) \
return true; \
NMD->addOperand(N); \
continue; \
}
#include "llvm/IR/Metadata.def"
// Parse all other MDNodes as an MDNodeID.
if (parseToken(lltok::exclaim, "Expected '!' here") || parseMDNodeID(N)) {
return true;
}
NMD->addOperand(N);
} while (EatIfPresent(lltok::comma));

return parseToken(lltok::rbrace, "expected end of metadata node");
}
Expand All @@ -782,9 +784,10 @@ bool LLParser::parseStandaloneMetadata() {
if (Lex.getKind() == lltok::Type)
return tokError("unexpected type in metadata definition");

auto DistinctLoc = Lex.getLoc();
bool IsDistinct = EatIfPresent(lltok::kw_distinct);
if (Lex.getKind() == lltok::MetadataVar) {
if (parseSpecializedMDNode(Init, IsDistinct))
if (parseSpecializedMDNode(Init, IsDistinct, DistinctLoc))
return true;
} else if (parseToken(lltok::exclaim, "Expected '!' here") ||
parseMDTuple(Init, IsDistinct))
Expand Down Expand Up @@ -4332,12 +4335,25 @@ bool LLParser::parseMDField(StringRef Name, FieldTy &Result) {
return parseMDField(Loc, Name, Result);
}

bool LLParser::parseSpecializedMDNode(MDNode *&N, bool IsDistinct) {
bool LLParser::parseSpecializedMDNode(MDNode *&N, bool IsDistinct,
LocTy DistinctLoc) {
assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");

#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) \
#define HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(CLASS) \
if (Lex.getStrVal() == #CLASS) \
return parse##CLASS(N, IsDistinct);
#define HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUED(CLASS) \
if (Lex.getStrVal() == #CLASS) { \
if (IsDistinct) \
return error(DistinctLoc, "'distinct' not allowed for !" #CLASS); \
return parse##CLASS(N, IsDistinct); \
}
#define HANDLE_SPECIALIZED_MDNODE_LEAF_DISTINCT(CLASS) \
if (Lex.getStrVal() == #CLASS) { \
if (!IsDistinct) \
return error(DistinctLoc, "missing 'distinct', required for !" #CLASS); \
return parse##CLASS(N, IsDistinct); \
}
#include "llvm/IR/Metadata.def"

return tokError("expected metadata type");
Expand Down Expand Up @@ -4683,9 +4699,6 @@ bool LLParser::parseDIFile(MDNode *&Result, bool IsDistinct) {
/// globals: !4, imports: !5, macros: !6, dwoId: 0x0abcd,
/// sysroot: "/", sdk: "MacOSX.sdk")
bool LLParser::parseDICompileUnit(MDNode *&Result, bool IsDistinct) {
if (!IsDistinct)
return Lex.Error("missing 'distinct', required for !DICompileUnit");

#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(language, DwarfLangField, ); \
REQUIRED(file, MDField, (/* AllowNull */ false)); \
Expand Down Expand Up @@ -5009,6 +5022,7 @@ bool LLParser::parseDILabel(MDNode *&Result, bool IsDistinct) {
/// parseDIExpression:
/// ::= !DIExpression(0, 7, -1)
bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) {
assert(!IsDistinct && "DIExpression must not be distinct");
assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
Lex.Lex();

Expand Down Expand Up @@ -5050,17 +5064,18 @@ bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) {
if (parseToken(lltok::rparen, "expected ')' here"))
return true;

Result = GET_OR_DISTINCT(DIExpression, (Context, Elements));
Result = DIExpression::get(Context, Elements);
return false;
}

bool LLParser::parseDIArgList(MDNode *&Result, bool IsDistinct) {
return parseDIArgList(Result, IsDistinct, nullptr);
return tokError("!DIArgList cannot appear outside of a function");
}
/// ParseDIArgList:
/// ::= !DIArgList(i32 7, i64 %0)
bool LLParser::parseDIArgList(MDNode *&Result, bool IsDistinct,
PerFunctionState *PFS) {
assert(!IsDistinct && "DIArgList must not be distinct");
assert(PFS && "Expected valid function state");
assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
Lex.Lex();
Expand All @@ -5080,7 +5095,7 @@ bool LLParser::parseDIArgList(MDNode *&Result, bool IsDistinct,
if (parseToken(lltok::rparen, "expected ')' here"))
return true;

Result = GET_OR_DISTINCT(DIArgList, (Context, Args));
Result = DIArgList::get(Context, Args);
return false;
}

Expand Down
13 changes: 9 additions & 4 deletions llvm/lib/Bitcode/Reader/MetadataLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ class MetadataLoader::MetadataLoaderImpl {
}

/// Upgrade the expression from previous versions.
Error upgradeDIExpression(uint64_t FromVersion,
Error upgradeDIExpression(uint64_t FromVersion, bool &IsDistinct,
MutableArrayRef<uint64_t> &Expr,
SmallVectorImpl<uint64_t> &Buffer) {
auto N = Expr.size();
Expand Down Expand Up @@ -628,6 +628,9 @@ class MetadataLoader::MetadataLoaderImpl {
LLVM_FALLTHROUGH;
}
case 3:
IsDistinct = false;
LLVM_FALLTHROUGH;
case 4:
// Up-to-date!
break;
}
Expand Down Expand Up @@ -2002,11 +2005,13 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
auto Elts = MutableArrayRef<uint64_t>(Record).slice(1);

SmallVector<uint64_t, 6> Buffer;
if (Error Err = upgradeDIExpression(Version, Elts, Buffer))
if (Error Err = upgradeDIExpression(Version, IsDistinct, Elts, Buffer))
return Err;

MetadataList.assignValue(
GET_OR_DISTINCT(DIExpression, (Context, Elts)), NextMetadataNo);
if (IsDistinct)
return error("Invalid record");

MetadataList.assignValue(DIExpression::get(Context, Elts), NextMetadataNo);
NextMetadataNo++;
break;
}
Expand Down
17 changes: 15 additions & 2 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1766,7 +1766,6 @@ void ModuleBitcodeWriter::writeDIFile(const DIFile *N,
void ModuleBitcodeWriter::writeDICompileUnit(const DICompileUnit *N,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
assert(N->isDistinct() && "Expected distinct compile units");
Record.push_back(/* IsDistinct */ true);
Record.push_back(N->getSourceLanguage());
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
Expand Down Expand Up @@ -2020,7 +2019,7 @@ void ModuleBitcodeWriter::writeDIExpression(const DIExpression *N,
SmallVectorImpl<uint64_t> &Record,
unsigned Abbrev) {
Record.reserve(N->getElements().size() + 1);
const uint64_t Version = 3 << 1;
const uint64_t Version = 4 << 1;
Record.push_back((uint64_t)N->isDistinct() | Version);
Record.append(N->elements_begin(), N->elements_end());

Expand Down Expand Up @@ -2166,6 +2165,20 @@ void ModuleBitcodeWriter::writeMetadataRecords(
if (const MDNode *N = dyn_cast<MDNode>(MD)) {
assert(N->isResolved() && "Expected forward references to be resolved");

#ifndef NDEBUG
switch (N->getMetadataID()) {
#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) \
case Metadata::CLASS##Kind: \
assert(!N->isDistinct() && "Expected non-distinct " #CLASS); \
break;
#define HANDLE_MDNODE_LEAF_DISTINCT(CLASS) \
case Metadata::CLASS##Kind: \
assert(N->isDistinct() && "Expected distinct " #CLASS); \
break;
#include "llvm/IR/Metadata.def"
}
#endif

switch (N->getMetadataID()) {
default:
llvm_unreachable("Invalid MDNode subclass");
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/CodeGen/MIRParser/MIParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,7 @@ bool MIParser::parseStandaloneMDNode(MDNode *&Node) {
if (parseMDNode(Node))
return true;
} else if (Token.is(MIToken::md_diexpr)) {
// FIXME: This should be driven off of the UNIQUED property in Metadata.def
if (parseDIExpression(Node))
return true;
} else if (Token.is(MIToken::md_dilocation)) {
Expand Down Expand Up @@ -2327,6 +2328,7 @@ bool MIParser::parseMetadataOperand(MachineOperand &Dest) {
if (parseMDNode(Node))
return true;
} else if (Token.is(MIToken::md_diexpr)) {
// FIXME: This should be driven off of the UNIQUED property in Metadata.def
if (parseDIExpression(Node))
return true;
}
Expand Down
54 changes: 29 additions & 25 deletions llvm/lib/IR/AsmWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1236,10 +1236,11 @@ 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 uniqued nodes. We just print them inline everywhere.
#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) \
if (isa<CLASS>(N)) \
return;
#include "llvm/IR/Metadata.def"

unsigned DestSlot = mdnNext;
if (!mdnMap.insert(std::make_pair(N, DestSlot)).second)
Expand Down Expand Up @@ -2332,10 +2333,7 @@ static void writeDIExpression(raw_ostream &Out, const DIExpression *N,
}

static void writeDIArgList(raw_ostream &Out, const DIArgList *N,
AsmWriterContext &WriterCtx,
bool FromValue = false) {
assert(FromValue &&
"Unexpected DIArgList metadata outside of value argument");
AsmWriterContext &WriterCtx) {
Out << "!DIArgList(";
FieldSeparator FS;
MDFieldPrinter Printer(Out, WriterCtx);
Expand Down Expand Up @@ -2486,16 +2484,16 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
AsmWriterContext &WriterCtx,
bool FromValue) {
// Write DIExpressions and DIArgLists inline when used as a value. Improves
// readability of debug info intrinsics.
if (const DIExpression *Expr = dyn_cast<DIExpression>(MD)) {
writeDIExpression(Out, Expr, WriterCtx);
return;
}
if (const DIArgList *ArgList = dyn_cast<DIArgList>(MD)) {
writeDIArgList(Out, ArgList, WriterCtx, FromValue);
return;
assert((FromValue || !(isa<LocalAsMetadata>(MD) || isa<DIArgList>(MD))) &&
"Unexpected function-local metadata outside of value argument");

// Write uniqued MDNodes inline when used as a value.
#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) \
if (const CLASS *N = dyn_cast<CLASS>(MD)) { \
write##CLASS(Out, N, WriterCtx); \
return; \
}
#include "llvm/IR/Metadata.def"

if (const MDNode *N = dyn_cast<MDNode>(MD)) {
std::unique_ptr<SlotTracker> MachineStorage;
Expand Down Expand Up @@ -2527,9 +2525,6 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,

auto *V = cast<ValueAsMetadata>(MD);
assert(WriterCtx.TypePrinter && "TypePrinter required for metadata values");
assert((FromValue || !isa<LocalAsMetadata>(V)) &&
"Unexpected function-local metadata outside of value argument");

WriterCtx.TypePrinter->print(V->getValue()->getType(), Out);
Out << ' ';
WriteAsOperandInternal(Out, V->getValue(), WriterCtx);
Expand Down Expand Up @@ -3416,15 +3411,17 @@ void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) {
if (i)
Out << ", ";

// Write DIExpressions inline.
// Write UNIQUED nodes 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;
}
#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) \
if (auto *N = dyn_cast<CLASS>(Op)) { \
write##CLASS(Out, N, AsmWriterContext::getEmpty()); \
continue; \
}
#include "llvm/IR/Metadata.def"

int Slot = Machine.getMetadataSlot(Op);
if (Slot == -1)
Expand Down Expand Up @@ -4773,8 +4770,15 @@ 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) {
return;
}
// Uniqued MDNodes are always treated as if OnlyAsOperand, as they are
// printed inline.
#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) \
if (isa<CLASS>(MD)) \
return;
#include "llvm/IR/Metadata.def"

OS << " = ";
WriteMDNodeBodyInternal(OS, N, *WriterCtx);
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/IR/DebugInfoMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,7 @@ DILabel *DILabel::getImpl(LLVMContext &Context, Metadata *Scope,
DIExpression *DIExpression::getImpl(LLVMContext &Context,
ArrayRef<uint64_t> Elements,
StorageType Storage, bool ShouldCreate) {
assert(Storage != Distinct && "DIExpression cannot be distinct");
DEFINE_GETIMPL_LOOKUP(DIExpression, (Elements));
DEFINE_GETIMPL_STORE_NO_OPS(DIExpression, (Elements));
}
Expand Down Expand Up @@ -1641,6 +1642,7 @@ DIMacroFile *DIMacroFile::getImpl(LLVMContext &Context, unsigned MIType,
DIArgList *DIArgList::getImpl(LLVMContext &Context,
ArrayRef<ValueAsMetadata *> Args,
StorageType Storage, bool ShouldCreate) {
assert(Storage != Distinct && "DIArgList cannot be distinct");
DEFINE_GETIMPL_LOOKUP(DIArgList, (Args));
DEFINE_GETIMPL_STORE_NO_OPS(DIArgList, (Args));
}
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/IR/LLVMContextImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ LLVMContextImpl::~LLVMContextImpl() {
#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
for (auto *I : CLASS##s) \
I->dropAllReferences();
#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS)
#include "llvm/IR/Metadata.def"

// Also drop references that come from the Value bridges.
Expand All @@ -79,6 +80,7 @@ LLVMContextImpl::~LLVMContextImpl() {
#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
for (CLASS * I : CLASS##s) \
delete I;
#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS)
#include "llvm/IR/Metadata.def"

// Free the constants.
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/IR/LLVMContextImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1398,6 +1398,7 @@ class LLVMContextImpl {

#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
DenseSet<CLASS *, CLASS##Info> CLASS##s;
#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS)
#include "llvm/IR/Metadata.def"

// Optional map for looking up composite types by identifier.
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/IR/Metadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,7 @@ MDNode *MDNode::replaceWithPermanentImpl() {
#define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \
case CLASS##Kind: \
break;
#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS)
#include "llvm/IR/Metadata.def"
}

Expand Down Expand Up @@ -812,6 +813,7 @@ MDNode *MDNode::uniquify() {
dispatchRecalculateHash(SubclassThis, ShouldRecalculateHash); \
return uniquifyImpl(SubclassThis, getContext().pImpl->CLASS##s); \
}
#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS)
#include "llvm/IR/Metadata.def"
}
}
Expand All @@ -824,6 +826,7 @@ void MDNode::eraseFromStore() {
case CLASS##Kind: \
getContext().pImpl->CLASS##s.erase(cast<CLASS>(this)); \
break;
#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS)
#include "llvm/IR/Metadata.def"
}
}
Expand Down
4 changes: 4 additions & 0 deletions llvm/test/Assembler/invalid-diarglist-outside-function.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s

; CHECK: <stdin>:[[@LINE+1]]:6: error: !DIArgList cannot appear outside of a function
!0 = !DIArgList()
4 changes: 4 additions & 0 deletions llvm/test/Assembler/invalid-diexpression-distinct.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s

; CHECK: <stdin>:[[@LINE+1]]:6: error: 'distinct' not allowed for !DIExpression
!0 = distinct !DIExpression()
16 changes: 16 additions & 0 deletions llvm/test/Bitcode/DIExpression-is-distinct-upgrade.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
; RUN: llvm-dis -o - %s.bc | FileCheck %s

!llvm.dbg.cu = !{!1}
!llvm.module.flags = !{!8, !9}

!0 = distinct !DIGlobalVariable(name: "g", scope: !1, file: !2, line: 1, type: !5, isLocal: false, isDefinition: true)
!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, globals: !4)
!2 = !DIFile(filename: "a.c", directory: "/")
!3 = !{}
!4 = !{!7}
!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
; CHECK: expr: !DIExpression()
!6 = distinct !DIExpression()
!7 = !DIGlobalVariableExpression(var: !0, expr: !6)
!8 = !{i32 2, !"Dwarf Version", i32 4}
!9 = !{i32 2, !"Debug Info Version", i32 3}
Binary file not shown.