From 9146fc8fd67cabc68a612908d909db7339f1e6c7 Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Mon, 2 Feb 2015 20:01:03 +0000 Subject: [PATCH] IR: Allow GenericDebugNode construction from MDString Allow `GenericDebugNode` construction directly from `MDString`, rather than requiring `StringRef`s. I've refactored the `StringRef` constructors to use these. There's no real functionality change here, except for exposing the lower-level API. The purpose of this is to simplify construction of string operands when reading bitcode. It's unnecessarily indirect to parse an `MDString` ID, lookup the `MDString` in the bitcode reader list, get the `StringRef` out of that, and then have `GenericDebugNode::getImpl()` use `MDString::get()` to acquire the original `MDString`. Instead, this allows the bitcode reader to directly pass in the `MDString`. llvm-svn: 227848 --- llvm/include/llvm/IR/DebugInfoMetadata.h | 18 ++++++++++++++++++ llvm/lib/IR/DebugInfoMetadata.cpp | 20 ++++++++++++-------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index 96d35cc..0439e7f 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -111,6 +111,12 @@ protected: return StringRef(); } + static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) { + if (S.empty()) + return nullptr; + return MDString::get(Context, S); + } + public: unsigned getTag() const { return SubclassData16; } @@ -144,6 +150,15 @@ class GenericDebugNode : public DebugNode { StringRef Header, ArrayRef DwarfOps, StorageType Storage, + bool ShouldCreate = true) { + return getImpl(Context, Tag, getCanonicalMDString(Context, Header), + DwarfOps, Storage, ShouldCreate); + } + + static GenericDebugNode *getImpl(LLVMContext &Context, unsigned Tag, + MDString *Header, + ArrayRef DwarfOps, + StorageType Storage, bool ShouldCreate = true); TempGenericDebugNode cloneImpl() const { @@ -158,6 +173,9 @@ public: DEFINE_MDNODE_GET(GenericDebugNode, (unsigned Tag, StringRef Header, ArrayRef DwarfOps), (Tag, Header, DwarfOps)) + DEFINE_MDNODE_GET(GenericDebugNode, (unsigned Tag, MDString *Header, + ArrayRef DwarfOps), + (Tag, Header, DwarfOps)) /// \brief Return a (temporary) clone of this. TempGenericDebugNode clone() const { return cloneImpl(); } diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 66dcc8e..21a95f9 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -71,21 +71,24 @@ MDLocation *MDLocation::getImpl(LLVMContext &Context, unsigned Line, Storage, Context.pImpl->MDLocations); } -/// \brief Get the MDString, or nullptr if the string is empty. -static MDString *getCanonicalMDString(LLVMContext &Context, StringRef S) { - if (S.empty()) - return nullptr; - return MDString::get(Context, S); +static StringRef getString(const MDString *S) { + if (S) + return S->getString(); + return StringRef(); +} + +static bool isCanonical(const MDString *S) { + return !S || !S->getString().empty(); } GenericDebugNode *GenericDebugNode::getImpl(LLVMContext &Context, unsigned Tag, - StringRef Header, + MDString *Header, ArrayRef DwarfOps, StorageType Storage, bool ShouldCreate) { unsigned Hash = 0; if (Storage == Uniqued) { - GenericDebugNodeInfo::KeyTy Key(Tag, Header, DwarfOps); + GenericDebugNodeInfo::KeyTy Key(Tag, getString(Header), DwarfOps); if (auto *N = getUniqued(Context.pImpl->GenericDebugNodes, Key)) return N; if (!ShouldCreate) @@ -96,7 +99,8 @@ GenericDebugNode *GenericDebugNode::getImpl(LLVMContext &Context, unsigned Tag, } // Use a nullptr for empty headers. - Metadata *PreOps[] = {getCanonicalMDString(Context, Header)}; + assert(isCanonical(Header) && "Expected canonical MDString"); + Metadata *PreOps[] = {Header}; return storeImpl(new (DwarfOps.size() + 1) GenericDebugNode( Context, Storage, Hash, Tag, PreOps, DwarfOps), Storage, Context.pImpl->GenericDebugNodes); -- 2.7.4