DebugInfo: Remove MDString-based type references

Eliminate DITypeIdentifierMap and make DITypeRef a thin wrapper around
DIType*.  It is no longer legal to refer to a DICompositeType by its
'identifier:', and DIBuilder no longer retains all types with an
'identifier:' automatically.

Aside from the bitcode upgrade, this is mainly removing logic to resolve
an MDString-based reference to an actualy DIType.  The commits leading
up to this have made the implicit type map in DICompileUnit's
'retainedTypes:' field superfluous.

This does not remove DITypeRef, DIScopeRef, DINodeRef, and
DITypeRefArray, or stop using them in DI-related metadata.  Although as
of this commit they aren't serving a useful purpose, there are patchces
under review to reuse them for CodeView support.

The tests in LLVM were updated with deref-typerefs.sh, which is attached
to the thread "[RFC] Lazy-loading of debug info metadata":

  http://lists.llvm.org/pipermail/llvm-dev/2016-April/098318.html

llvm-svn: 267296
This commit is contained in:
Duncan P. N. Exon Smith
2016-04-23 21:08:00 +00:00
parent dc88bd6e1f
commit a59d3e5af8
77 changed files with 730 additions and 826 deletions

View File

@@ -114,6 +114,14 @@ class BitcodeReaderMetadataList {
/// move) on resize, and TrackingMDRef is very expensive to copy.
SmallVector<TrackingMDRef, 1> MetadataPtrs;
/// Structures for resolving old type refs.
struct {
SmallDenseMap<MDString *, TempMDTuple, 1> Unknown;
SmallDenseMap<MDString *, DICompositeType *, 1> Final;
SmallDenseMap<MDString *, DICompositeType *, 1> FwdDecls;
std::vector<std::pair<TrackingMDRef, TempMDTuple>> Arrays;
} OldTypeRefs;
LLVMContext &Context;
public:
BitcodeReaderMetadataList(LLVMContext &C)
@@ -159,6 +167,18 @@ public:
void assignValue(Metadata *MD, unsigned Idx);
void tryToResolveCycles();
bool hasFwdRefs() const { return AnyFwdRefs; }
/// Upgrade a type that had an MDString reference.
void addTypeRef(MDString &UUID, DICompositeType &CT);
/// Upgrade a type that had an MDString reference.
Metadata *upgradeTypeRef(Metadata *MaybeUUID);
/// Upgrade a type ref array that may have MDString references.
Metadata *upgradeTypeRefArray(Metadata *MaybeTuple);
private:
Metadata *resolveTypeRefArray(Metadata *MaybeTuple);
};
class BitcodeReader : public GVMaterializer {
@@ -1118,14 +1138,34 @@ MDNode *BitcodeReaderMetadataList::getMDNodeFwdRefOrNull(unsigned Idx) {
}
void BitcodeReaderMetadataList::tryToResolveCycles() {
if (!AnyFwdRefs)
// Nothing to do.
return;
if (NumFwdRefs)
// Still forward references... can't resolve cycles.
return;
// Give up on finding a full definition for any forward decls that remain.
for (const auto &Ref : OldTypeRefs.FwdDecls)
OldTypeRefs.Final.insert(Ref);
OldTypeRefs.FwdDecls.clear();
// Upgrade from old type ref arrays. In strange cases, this could add to
// OldTypeRefs.Unknown.
for (const auto &Array : OldTypeRefs.Arrays)
Array.second->replaceAllUsesWith(resolveTypeRefArray(Array.first.get()));
// Replace old string-based type refs with the resolved node, if possible.
// If we haven't seen the node, leave it to the verifier to complain about
// the invalid string reference.
for (const auto &Ref : OldTypeRefs.Unknown)
if (DICompositeType *CT = OldTypeRefs.Final.lookup(Ref.first))
Ref.second->replaceAllUsesWith(CT);
else
Ref.second->replaceAllUsesWith(Ref.first);
OldTypeRefs.Unknown.clear();
if (!AnyFwdRefs)
// Nothing to do.
return;
// Resolve any cycles.
for (unsigned I = MinFwdRef, E = MaxFwdRef + 1; I != E; ++I) {
auto &MD = MetadataPtrs[I];
@@ -1141,6 +1181,60 @@ void BitcodeReaderMetadataList::tryToResolveCycles() {
AnyFwdRefs = false;
}
void BitcodeReaderMetadataList::addTypeRef(MDString &UUID,
DICompositeType &CT) {
assert(CT.getRawIdentifier() == &UUID && "Mismatched UUID");
if (CT.isForwardDecl())
OldTypeRefs.FwdDecls.insert(std::make_pair(&UUID, &CT));
else
OldTypeRefs.Final.insert(std::make_pair(&UUID, &CT));
}
Metadata *BitcodeReaderMetadataList::upgradeTypeRef(Metadata *MaybeUUID) {
auto *UUID = dyn_cast_or_null<MDString>(MaybeUUID);
if (LLVM_LIKELY(!UUID))
return MaybeUUID;
if (auto *CT = OldTypeRefs.Final.lookup(UUID))
return CT;
auto &Ref = OldTypeRefs.Unknown[UUID];
if (!Ref)
Ref = MDNode::getTemporary(Context, None);
return Ref.get();
}
Metadata *BitcodeReaderMetadataList::upgradeTypeRefArray(Metadata *MaybeTuple) {
auto *Tuple = dyn_cast_or_null<MDTuple>(MaybeTuple);
if (!Tuple || Tuple->isDistinct())
return MaybeTuple;
// Look through the array immediately if possible.
if (!Tuple->isTemporary())
return resolveTypeRefArray(Tuple);
// Create and return a placeholder to use for now. Eventually
// resolveTypeRefArrays() will be resolve this forward reference.
OldTypeRefs.Arrays.emplace_back(
std::piecewise_construct, std::make_tuple(Tuple),
std::make_tuple(MDTuple::getTemporary(Context, None)));
return OldTypeRefs.Arrays.back().second.get();
}
Metadata *BitcodeReaderMetadataList::resolveTypeRefArray(Metadata *MaybeTuple) {
auto *Tuple = dyn_cast_or_null<MDTuple>(MaybeTuple);
if (!Tuple || Tuple->isDistinct())
return MaybeTuple;
// Look through the DITypeRefArray, upgrading each DITypeRef.
SmallVector<Metadata *, 32> Ops;
Ops.reserve(Tuple->getNumOperands());
for (Metadata *MD : Tuple->operands())
Ops.push_back(upgradeTypeRef(MD));
return MDTuple::get(Context, Ops);
}
Type *BitcodeReader::getTypeByID(unsigned ID) {
// The type table size is always specified correctly.
if (ID >= TypeList.size())
@@ -2021,6 +2115,11 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
return cast_or_null<MDString>(getMDOrNull(ID));
};
// Support for old type refs.
auto getDITypeRefOrNull = [&](unsigned ID) {
return MetadataList.upgradeTypeRef(getMDOrNull(ID));
};
#define GET_OR_DISTINCT(CLASS, ARGS) \
(IsDistinct ? CLASS::getDistinct ARGS : CLASS::get ARGS)
@@ -2234,9 +2333,9 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
GET_OR_DISTINCT(DIDerivedType,
(Context, Record[1], getMDString(Record[2]),
getMDOrNull(Record[3]), Record[4],
getMDOrNull(Record[5]), getMDOrNull(Record[6]),
Record[7], Record[8], Record[9], Record[10],
getMDOrNull(Record[11]))),
getDITypeRefOrNull(Record[5]),
getDITypeRefOrNull(Record[6]), Record[7], Record[8],
Record[9], Record[10], getMDOrNull(Record[11]))),
NextMetadataNo++);
break;
}
@@ -2246,20 +2345,21 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
// If we have a UUID and this is not a forward declaration, lookup the
// mapping.
IsDistinct = Record[0];
IsDistinct = Record[0] & 0x1;
bool IsNotUsedInTypeRef = Record[0] >= 2;
unsigned Tag = Record[1];
MDString *Name = getMDString(Record[2]);
Metadata *File = getMDOrNull(Record[3]);
unsigned Line = Record[4];
Metadata *Scope = getMDOrNull(Record[5]);
Metadata *BaseType = getMDOrNull(Record[6]);
Metadata *Scope = getDITypeRefOrNull(Record[5]);
Metadata *BaseType = getDITypeRefOrNull(Record[6]);
uint64_t SizeInBits = Record[7];
uint64_t AlignInBits = Record[8];
uint64_t OffsetInBits = Record[9];
unsigned Flags = Record[10];
Metadata *Elements = getMDOrNull(Record[11]);
unsigned RuntimeLang = Record[12];
Metadata *VTableHolder = getMDOrNull(Record[13]);
Metadata *VTableHolder = getDITypeRefOrNull(Record[13]);
Metadata *TemplateParams = getMDOrNull(Record[14]);
auto *Identifier = getMDString(Record[15]);
DICompositeType *CT = nullptr;
@@ -2276,6 +2376,8 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
SizeInBits, AlignInBits, OffsetInBits, Flags,
Elements, RuntimeLang, VTableHolder,
TemplateParams, Identifier));
if (!IsNotUsedInTypeRef && Identifier)
MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));
MetadataList.assignValue(CT, NextMetadataNo++);
break;
@@ -2284,10 +2386,14 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
if (Record.size() != 3)
return error("Invalid record");
IsDistinct = Record[0];
IsDistinct = Record[0] & 0x1;
bool IsOldTypeRefArray = Record[0] < 2;
Metadata *Types = getMDOrNull(Record[2]);
if (LLVM_UNLIKELY(IsOldTypeRefArray))
Types = MetadataList.upgradeTypeRefArray(Types);
MetadataList.assignValue(
GET_OR_DISTINCT(DISubroutineType,
(Context, Record[1], getMDOrNull(Record[2]))),
GET_OR_DISTINCT(DISubroutineType, (Context, Record[1], Types)),
NextMetadataNo++);
break;
}
@@ -2354,10 +2460,10 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
bool HasCU = Offset && !HasFn;
DISubprogram *SP = GET_OR_DISTINCT(
DISubprogram,
(Context, getMDOrNull(Record[1]), getMDString(Record[2]),
(Context, getDITypeRefOrNull(Record[1]), getMDString(Record[2]),
getMDString(Record[3]), getMDOrNull(Record[4]), Record[5],
getMDOrNull(Record[6]), Record[7], Record[8], Record[9],
getMDOrNull(Record[10]), Record[11], Record[12], Record[13],
getDITypeRefOrNull(Record[10]), Record[11], Record[12], Record[13],
Record[14], HasCU ? CUorFn : nullptr,
getMDOrNull(Record[15 + Offset]), getMDOrNull(Record[16 + Offset]),
getMDOrNull(Record[17 + Offset])));
@@ -2444,7 +2550,7 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
IsDistinct = Record[0];
MetadataList.assignValue(GET_OR_DISTINCT(DITemplateTypeParameter,
(Context, getMDString(Record[1]),
getMDOrNull(Record[2]))),
getDITypeRefOrNull(Record[2]))),
NextMetadataNo++);
break;
}
@@ -2456,7 +2562,8 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
MetadataList.assignValue(
GET_OR_DISTINCT(DITemplateValueParameter,
(Context, Record[1], getMDString(Record[2]),
getMDOrNull(Record[3]), getMDOrNull(Record[4]))),
getDITypeRefOrNull(Record[3]),
getMDOrNull(Record[4]))),
NextMetadataNo++);
break;
}
@@ -2470,7 +2577,7 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
(Context, getMDOrNull(Record[1]),
getMDString(Record[2]), getMDString(Record[3]),
getMDOrNull(Record[4]), Record[5],
getMDOrNull(Record[6]), Record[7], Record[8],
getDITypeRefOrNull(Record[6]), Record[7], Record[8],
getMDOrNull(Record[9]), getMDOrNull(Record[10]))),
NextMetadataNo++);
break;
@@ -2489,8 +2596,8 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
(Context, getMDOrNull(Record[1 + HasTag]),
getMDString(Record[2 + HasTag]),
getMDOrNull(Record[3 + HasTag]), Record[4 + HasTag],
getMDOrNull(Record[5 + HasTag]), Record[6 + HasTag],
Record[7 + HasTag])),
getDITypeRefOrNull(Record[5 + HasTag]),
Record[6 + HasTag], Record[7 + HasTag])),
NextMetadataNo++);
break;
}
@@ -2515,7 +2622,7 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
(Context, getMDString(Record[1]),
getMDOrNull(Record[2]), Record[3],
getMDString(Record[4]), getMDString(Record[5]),
Record[6], getMDOrNull(Record[7]))),
Record[6], getDITypeRefOrNull(Record[7]))),
NextMetadataNo++);
break;
}
@@ -2527,7 +2634,7 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
MetadataList.assignValue(
GET_OR_DISTINCT(DIImportedEntity,
(Context, Record[1], getMDOrNull(Record[2]),
getMDOrNull(Record[3]), Record[4],
getDITypeRefOrNull(Record[3]), Record[4],
getMDString(Record[5]))),
NextMetadataNo++);
break;