diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index 025ad7f0e52..1da9f0704e3 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -1073,7 +1073,7 @@ class GenericDebugNode : public DebugNode { void recalculateHash(); static GenericDebugNode *getImpl(LLVMContext &Context, unsigned Tag, - MDString *Header, + StringRef Header, ArrayRef DwarfOps, StorageType Storage, bool ShouldCreate = true); @@ -1087,25 +1087,24 @@ class GenericDebugNode : public DebugNode { public: unsigned getHash() const { return SubclassData32; } - static GenericDebugNode *get(LLVMContext &Context, - unsigned Tag, - MDString *Header, + static GenericDebugNode *get(LLVMContext &Context, unsigned Tag, + StringRef Header, ArrayRef DwarfOps) { return getImpl(Context, Tag, Header, DwarfOps, Uniqued); } static GenericDebugNode *getIfExists(LLVMContext &Context, unsigned Tag, - MDString *Header, + StringRef Header, ArrayRef DwarfOps) { return getImpl(Context, Tag, Header, DwarfOps, Uniqued, /* ShouldCreate */ false); } static GenericDebugNode *getDistinct(LLVMContext &Context, unsigned Tag, - MDString *Header, + StringRef Header, ArrayRef DwarfOps) { return getImpl(Context, Tag, Header, DwarfOps, Distinct); } static TempGenericDebugNode getTemporary(LLVMContext &Context, unsigned Tag, - MDString *Header, + StringRef Header, ArrayRef DwarfOps) { return TempGenericDebugNode( getImpl(Context, Tag, Header, DwarfOps, Temporary)); @@ -1115,7 +1114,11 @@ public: TempGenericDebugNode clone() const { return cloneImpl(); } unsigned getTag() const { return SubclassData16; } - MDString *getHeader() const { return cast_or_null(getOperand(0)); } + StringRef getHeader() const { + if (auto *S = cast_or_null(getOperand(0))) + return S->getString(); + return StringRef(); + } op_iterator dwarf_op_begin() const { return op_begin() + 1; } op_iterator dwarf_op_end() const { return op_end(); } diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h index a009262f80e..12b150741dd 100644 --- a/lib/IR/LLVMContextImpl.h +++ b/lib/IR/LLVMContextImpl.h @@ -288,8 +288,8 @@ struct MDLocationInfo { struct GenericDebugNodeInfo { struct KeyTy : MDNodeOpsKey { unsigned Tag; - MDString *Header; - KeyTy(unsigned Tag, MDString *Header, ArrayRef DwarfOps) + StringRef Header; + KeyTy(unsigned Tag, StringRef Header, ArrayRef DwarfOps) : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {} KeyTy(GenericDebugNode *N) : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getHeader()) {} diff --git a/lib/IR/Metadata.cpp b/lib/IR/Metadata.cpp index e55d287e63a..d4393026d50 100644 --- a/lib/IR/Metadata.cpp +++ b/lib/IR/Metadata.cpp @@ -760,14 +760,10 @@ MDLocation *MDLocation::getImpl(LLVMContext &Context, unsigned Line, } GenericDebugNode *GenericDebugNode::getImpl(LLVMContext &Context, unsigned Tag, - MDString *Header, + StringRef Header, ArrayRef DwarfOps, StorageType Storage, bool ShouldCreate) { - // Canonicalize empty string to a nullptr. - if (Header && Header->getString().empty()) - Header = nullptr; - unsigned Hash = 0; if (Storage == Uniqued) { GenericDebugNodeInfo::KeyTy Key(Tag, Header, DwarfOps); @@ -780,7 +776,9 @@ GenericDebugNode *GenericDebugNode::getImpl(LLVMContext &Context, unsigned Tag, assert(ShouldCreate && "Expected non-uniqued nodes to always be created"); } - Metadata *PreOps[] = {Header}; + // Use a nullptr for empty headers. + Metadata *PreOps[] = {Header.empty() ? nullptr + : MDString::get(Context, Header)}; return storeImpl(new (DwarfOps.size() + 1) GenericDebugNode( Context, Storage, Hash, Tag, PreOps, DwarfOps), Storage, Context.pImpl->GenericDebugNodes); diff --git a/unittests/IR/MetadataTest.cpp b/unittests/IR/MetadataTest.cpp index 39692d6945c..98b0d73a3dd 100644 --- a/unittests/IR/MetadataTest.cpp +++ b/unittests/IR/MetadataTest.cpp @@ -575,14 +575,14 @@ TEST_F(MDLocationTest, getTemporary) { typedef MetadataTest GenericDebugNodeTest; TEST_F(GenericDebugNodeTest, get) { - auto *Header = MDString::get(Context, "header"); + StringRef Header = "header"; auto *Empty = MDNode::get(Context, None); Metadata *Ops1[] = {Empty}; auto *N = GenericDebugNode::get(Context, 15, Header, Ops1); EXPECT_EQ(15u, N->getTag()); EXPECT_EQ(2u, N->getNumOperands()); EXPECT_EQ(Header, N->getHeader()); - EXPECT_EQ(Header, N->getOperand(0)); + EXPECT_EQ(MDString::get(Context, Header), N->getOperand(0)); EXPECT_EQ(1u, N->getNumDwarfOperands()); EXPECT_EQ(Empty, N->getDwarfOperand(0)); EXPECT_EQ(Empty, N->getOperand(1)); @@ -609,10 +609,9 @@ TEST_F(GenericDebugNodeTest, get) { TEST_F(GenericDebugNodeTest, getEmptyHeader) { // Canonicalize !"" to null. - auto *Header = MDString::get(Context, ""); - EXPECT_NE(nullptr, Header); - auto *N = GenericDebugNode::get(Context, 15, Header, None); - EXPECT_EQ(nullptr, N->getHeader()); + auto *N = GenericDebugNode::get(Context, 15, StringRef(), None); + EXPECT_EQ(StringRef(), N->getHeader()); + EXPECT_EQ(nullptr, N->getOperand(0)); } typedef MetadataTest MetadataAsValueTest;