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`.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227848 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith 2015-02-02 20:01:03 +00:00
parent 21b88f5f90
commit 2a11d59014
2 changed files with 30 additions and 8 deletions

View File

@ -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<Metadata *> 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<Metadata *> DwarfOps,
StorageType Storage,
bool ShouldCreate = true);
TempGenericDebugNode cloneImpl() const {
@ -158,6 +173,9 @@ public:
DEFINE_MDNODE_GET(GenericDebugNode, (unsigned Tag, StringRef Header,
ArrayRef<Metadata *> DwarfOps),
(Tag, Header, DwarfOps))
DEFINE_MDNODE_GET(GenericDebugNode, (unsigned Tag, MDString *Header,
ArrayRef<Metadata *> DwarfOps),
(Tag, Header, DwarfOps))
/// \brief Return a (temporary) clone of this.
TempGenericDebugNode clone() const { return cloneImpl(); }

View File

@ -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<Metadata *> 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);