summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-04-23 21:08:00 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-04-23 21:08:00 +0000
commita59d3e5af889662139b8b08f2175f12567491441 (patch)
treec91b05e3c724401c8bf6bcbf8ff3bdfd80450ef3 /llvm/lib/Bitcode/Reader/BitcodeReader.cpp
parentdc88bd6e1fc483d6927604e6b2dc58f9d4d06316 (diff)
downloadbcm5719-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.cpp153
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;
OpenPOWER on IntegriCloud