diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2016-04-23 21:08:00 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2016-04-23 21:08:00 +0000 |
commit | a59d3e5af889662139b8b08f2175f12567491441 (patch) | |
tree | c91b05e3c724401c8bf6bcbf8ff3bdfd80450ef3 /llvm/lib/Bitcode/Reader/BitcodeReader.cpp | |
parent | dc88bd6e1fc483d6927604e6b2dc58f9d4d06316 (diff) | |
download | bcm5719-llvm-a59d3e5af889662139b8b08f2175f12567491441.tar.gz bcm5719-llvm-a59d3e5af889662139b8b08f2175f12567491441.zip |
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
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 153 |
1 files changed, 130 insertions, 23 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 734d317234b..ecd05c245d7 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -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; |