Skip to content

Commit 8e3d88f

Browse files
committed
[Debug Info] Create all member types up front
when creating the members of a struct, to avoid problems when the type graph changes due to type nodes being uniqued. It's not clear this can actually happen, but it helps ruling this out as a failure cause.
1 parent 371e812 commit 8e3d88f

File tree

1 file changed

+95
-57
lines changed

1 file changed

+95
-57
lines changed

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 95 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,8 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
476476

477477
/// Return the size reported by a type.
478478
static unsigned getSizeInBits(llvm::DIType *Ty) {
479+
if (!Ty)
480+
return 0;
479481
// Follow derived types until we reach a type that
480482
// reports back a size.
481483
while (isa<llvm::DIDerivedType>(Ty) && !Ty->getSizeInBits()) {
@@ -1103,20 +1105,17 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
11031105
BumpAllocatedString(CanonicalName)};
11041106
}
11051107

1106-
llvm::DIDerivedType *createMemberType(DebugTypeInfo DbgTy, StringRef Name,
1107-
unsigned &OffsetInBits,
1108-
llvm::DIScope *Scope,
1109-
llvm::DIFile *File,
1110-
llvm::DINode::DIFlags Flags) {
1111-
unsigned SizeOfByte = CI.getTargetInfo().getCharWidth();
1112-
auto *Ty = getOrCreateType(DbgTy);
1113-
auto SizeInBits = getSizeInBits(Ty);
1114-
auto *DITy = DBuilder.createMemberType(
1115-
Scope, Name, File, 0, SizeInBits, 0, OffsetInBits, Flags, Ty);
1108+
llvm::DIDerivedType *
1109+
createMemberType(llvm::DIType *DITy, StringRef Name, unsigned &OffsetInBits,
1110+
unsigned AlignInBits, llvm::DIScope *Scope,
1111+
llvm::DIFile *File, llvm::DINode::DIFlags Flags) {
1112+
auto SizeInBits = getSizeInBits(DITy);
1113+
llvm::DIDerivedType *DIMemberTy = DBuilder.createMemberType(
1114+
Scope, Name, File, 0, SizeInBits, 0, OffsetInBits, Flags, DITy);
11161115
OffsetInBits += SizeInBits;
1117-
OffsetInBits = llvm::alignTo(OffsetInBits,
1118-
SizeOfByte * DbgTy.getAlignment().getValue());
1119-
return DITy;
1116+
if (AlignInBits)
1117+
OffsetInBits = llvm::alignTo(OffsetInBits, AlignInBits);
1118+
return DIMemberTy;
11201119
}
11211120

11221121
/// Creates a temporary replaceable forward decl to protect against recursion.
@@ -1146,6 +1145,17 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
11461145
return FwdDecl;
11471146
}
11481147

1148+
using TrackingDIType = llvm::TypedTrackingMDRef<llvm::DIType>;
1149+
struct MemberDIType {
1150+
StringRef Name;
1151+
unsigned AlignInBits;
1152+
TrackingDIType DIType;
1153+
MemberDIType(StringRef Name, unsigned AlignInBits, llvm::DIType *DIType)
1154+
: Name(Name), AlignInBits(AlignInBits), DIType(DIType) {}
1155+
};
1156+
1157+
unsigned getByteSize() { return CI.getTargetInfo().getCharWidth(); }
1158+
11491159
llvm::DICompositeType *createStructType(
11501160
NominalOrBoundGenericNominalType *Type, NominalTypeDecl *Decl,
11511161
llvm::DIScope *Scope, llvm::DIFile *File, unsigned Line,
@@ -1156,28 +1166,36 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
11561166
Type, Scope, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
11571167
Name);
11581168
// Collect the members.
1159-
SmallVector<llvm::Metadata *, 16> Elements;
1160-
unsigned OffsetInBits = 0;
1169+
SmallVector<MemberDIType, 16> MemberTypes;
11611170
for (VarDecl *VD : Decl->getStoredProperties()) {
11621171
auto memberTy = Type->getTypeOfMember(VD);
11631172
if (auto DbgTy = CompletedDebugTypeInfo::getFromTypeInfo(
11641173
memberTy,
11651174
IGM.getTypeInfoForUnlowered(
11661175
IGM.getSILTypes().getAbstractionPattern(VD), memberTy),
11671176
IGM))
1168-
Elements.push_back(createMemberType(*DbgTy, VD->getName().str(),
1169-
OffsetInBits, Scope, File, Flags));
1177+
MemberTypes.emplace_back(VD->getName().str(),
1178+
getByteSize() *
1179+
DbgTy->getAlignment().getValue(),
1180+
getOrCreateType(*DbgTy));
11701181
else
11711182
// Without complete type info we can only create a forward decl.
11721183
return DBuilder.createForwardDecl(
11731184
llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, File, Line,
11741185
llvm::dwarf::DW_LANG_Swift, SizeInBits, 0);
11751186
}
11761187

1188+
SmallVector<llvm::Metadata *, 16> Members;
1189+
unsigned OffsetInBits = 0;
1190+
for (auto &Member : MemberTypes)
1191+
Members.push_back(createMemberType(Member.DIType, Member.Name,
1192+
OffsetInBits, Member.AlignInBits,
1193+
Scope, File, Flags));
1194+
11771195
llvm::DINodeArray BoundParams = collectGenericParams(Type);
11781196
llvm::DICompositeType *DITy = createStruct(
11791197
Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
1180-
DBuilder.getOrCreateArray(Elements), BoundParams, SpecificationOf);
1198+
DBuilder.getOrCreateArray(Members), BoundParams, SpecificationOf);
11811199
return DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
11821200
}
11831201

@@ -1203,24 +1221,29 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
12031221
DbgTy.getType(), Scope, File, Line, SizeInBits, AlignInBits, Flags,
12041222
UniqueID, Name);
12051223
// Collect the members.
1206-
SmallVector<llvm::Metadata *, 16> Elements;
1224+
SmallVector<MemberDIType, 16> MemberTypes;
12071225
for (VarDecl *VD : Decl->getStoredProperties()) {
1208-
auto memberTy =
1209-
UnsubstitutedType->getTypeOfMember(VD);
1226+
Type memberTy = UnsubstitutedType->getTypeOfMember(VD);
12101227
auto DbgTy = DebugTypeInfo::getFromTypeInfo(
12111228
memberTy,
12121229
IGM.getTypeInfoForUnlowered(
12131230
IGM.getSILTypes().getAbstractionPattern(VD), memberTy),
12141231
IGM);
1232+
MemberTypes.emplace_back(VD->getName().str(),
1233+
getByteSize() * DbgTy.getAlignment().getValue(),
1234+
getOrCreateType(DbgTy));
1235+
}
1236+
SmallVector<llvm::Metadata *, 16> Members;
1237+
for (auto &Member : MemberTypes) {
12151238
unsigned OffsetInBits = 0;
1216-
llvm::DIType *DITy = createMemberType(DbgTy, VD->getName().str(),
1217-
OffsetInBits, Scope, File, Flags);
1218-
Elements.push_back(DITy);
1239+
Members.push_back(createMemberType(Member.DIType, Member.Name,
1240+
OffsetInBits, Member.AlignInBits,
1241+
Scope, File, Flags));
12191242
}
12201243

12211244
llvm::DICompositeType *DITy = DBuilder.createStructType(
12221245
Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, DerivedFrom,
1223-
DBuilder.getOrCreateArray(Elements), RuntimeLang, nullptr, UniqueID);
1246+
DBuilder.getOrCreateArray(Members), RuntimeLang, nullptr, UniqueID);
12241247
return DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
12251248
}
12261249

@@ -1410,7 +1433,8 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
14101433
auto FwdDecl = createTemporaryReplaceableForwardDecl(
14111434
DbgTy.getType(), Scope, File, Line, SizeInBits, AlignInBits, Flags,
14121435
MangledName, Name);
1413-
SmallVector<llvm::Metadata *, 16> Elements;
1436+
1437+
SmallVector<MemberDIType, 16> MemberTypes;
14141438
for (auto *ElemDecl : Decl->getAllElements()) {
14151439
std::optional<CompletedDebugTypeInfo> ElemDbgTy;
14161440
if (auto PayloadTy = ElemDecl->getPayloadInterfaceType()) {
@@ -1429,23 +1453,27 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
14291453
llvm::dwarf::DW_TAG_structure_type, Name, Scope, File, Line,
14301454
llvm::dwarf::DW_LANG_Swift, SizeInBits, 0, MangledName);
14311455
}
1432-
unsigned Offset = 0;
1433-
auto MTy =
1434-
createMemberType(*ElemDbgTy, ElemDecl->getBaseIdentifier().str(),
1435-
Offset, Scope, File, Flags);
1436-
Elements.push_back(MTy);
1456+
MemberTypes.emplace_back(ElemDecl->getBaseIdentifier().str(),
1457+
getByteSize() *
1458+
ElemDbgTy->getAlignment().getValue(),
1459+
TrackingDIType(getOrCreateType(*ElemDbgTy)));
14371460
} else {
14381461
// A variant with no payload.
1439-
auto MTy = DBuilder.createMemberType(
1440-
Scope, ElemDecl->getBaseIdentifier().str(), File, 0, 0, 0, 0, Flags,
1441-
nullptr);
1442-
Elements.push_back(MTy);
1462+
MemberTypes.emplace_back(ElemDecl->getBaseIdentifier().str(), 0,
1463+
nullptr);
14431464
}
14441465
}
1466+
SmallVector<llvm::Metadata *, 16> Members;
1467+
for (auto &Member : MemberTypes) {
1468+
unsigned Offset = 0;
1469+
Members.push_back(createMemberType(Member.DIType, Member.Name, Offset,
1470+
Member.AlignInBits, Scope, File,
1471+
Flags));
1472+
}
14451473

14461474
auto VPTy = DBuilder.createVariantPart(
14471475
Scope, {}, File, Line, SizeInBits, AlignInBits, Flags, nullptr,
1448-
DBuilder.getOrCreateArray(Elements), /*UniqueIdentifier=*/"");
1476+
DBuilder.getOrCreateArray(Members), /*UniqueIdentifier=*/"");
14491477

14501478
llvm::DICompositeType *DITy = DBuilder.createStructType(
14511479
Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, nullptr,
@@ -1474,31 +1502,35 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
14741502
DbgTy.getType(), Scope, File, Line, SizeInBits, AlignInBits, Flags,
14751503
MangledName, Name);
14761504

1477-
SmallVector<llvm::Metadata *, 16> Elements;
1505+
SmallVector<MemberDIType, 16> MemberTypes;
14781506
for (auto *ElemDecl : Decl->getAllElements()) {
14791507
std::optional<DebugTypeInfo> ElemDbgTy;
14801508
if (auto PayloadTy = ElemDecl->getPayloadInterfaceType()) {
14811509
// A variant case which carries a payload.
14821510
PayloadTy = ElemDecl->getParentEnum()->mapTypeIntoContext(PayloadTy);
14831511
ElemDbgTy = DebugTypeInfo::getFromTypeInfo(
14841512
PayloadTy, IGM.getTypeInfoForUnlowered(PayloadTy), IGM);
1485-
unsigned Offset = 0;
1486-
auto MTy =
1487-
createMemberType(*ElemDbgTy, ElemDecl->getBaseIdentifier().str(),
1488-
Offset, Scope, File, Flags);
1489-
Elements.push_back(MTy);
1513+
MemberTypes.emplace_back(ElemDecl->getBaseIdentifier().str(),
1514+
getByteSize() *
1515+
ElemDbgTy->getAlignment().getValue(),
1516+
TrackingDIType(getOrCreateType(*ElemDbgTy)));
14901517
} else {
14911518
// A variant with no payload.
1492-
auto MTy = DBuilder.createMemberType(
1493-
Scope, ElemDecl->getBaseIdentifier().str(), File, 0, 0, 0, 0, Flags,
1494-
nullptr);
1495-
Elements.push_back(MTy);
1519+
MemberTypes.emplace_back(ElemDecl->getBaseIdentifier().str(), 0,
1520+
nullptr);
14961521
}
14971522
}
1523+
SmallVector<llvm::Metadata *, 16> Members;
1524+
for (auto &Member : MemberTypes) {
1525+
unsigned Offset = 0;
1526+
Members.push_back(createMemberType(Member.DIType, Member.Name, Offset,
1527+
Member.AlignInBits, Scope, File,
1528+
Flags));
1529+
}
14981530

14991531
auto VPTy = DBuilder.createVariantPart(Scope, {}, File, Line, SizeInBits,
15001532
AlignInBits, Flags, nullptr,
1501-
DBuilder.getOrCreateArray(Elements));
1533+
DBuilder.getOrCreateArray(Members));
15021534

15031535
llvm::DICompositeType *DITy = DBuilder.createStructType(
15041536
Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, nullptr,
@@ -1721,31 +1753,37 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
17211753
unsigned SizeInBits, unsigned AlignInBits,
17221754
llvm::DINode::DIFlags Flags,
17231755
StringRef MangledName) {
1756+
auto FwdDecl = createTemporaryReplaceableForwardDecl(
1757+
DbgTy.getType(), Scope, MainFile, 0, SizeInBits, AlignInBits, Flags,
1758+
MangledName, MangledName);
1759+
17241760
TypeBase *BaseTy = DbgTy.getType();
17251761
auto *TupleTy = BaseTy->castTo<TupleType>();
17261762

1727-
SmallVector<llvm::Metadata *, 16> Elements;
1728-
unsigned OffsetInBits = 0;
1763+
SmallVector<MemberDIType, 16> MemberTypes;
17291764
auto genericSig = IGM.getCurGenericContext();
17301765
for (auto ElemTy : TupleTy->getElementTypes()) {
17311766
auto &elemTI = IGM.getTypeInfoForUnlowered(
17321767
AbstractionPattern(genericSig, ElemTy->getCanonicalType()), ElemTy);
17331768
auto DbgTy =
17341769
DebugTypeInfo::getFromTypeInfo(ElemTy, elemTI, IGM);
1735-
Elements.push_back(
1736-
createMemberType(DbgTy, "", OffsetInBits, Scope, MainFile, Flags));
1770+
MemberTypes.emplace_back("",
1771+
getByteSize() * DbgTy.getAlignment().getValue(),
1772+
getOrCreateType(DbgTy));
17371773
}
1774+
SmallVector<llvm::Metadata *, 16> Members;
1775+
unsigned OffsetInBits = 0;
1776+
for (auto &Member : MemberTypes)
1777+
Members.emplace_back(createMemberType(Member.DIType, Member.Name,
1778+
OffsetInBits, Member.AlignInBits,
1779+
Scope, MainFile, Flags));
17381780
// FIXME: assert that SizeInBits == OffsetInBits.
17391781

1740-
auto FwdDecl = createTemporaryReplaceableForwardDecl(
1741-
DbgTy.getType(), Scope, MainFile, 0, SizeInBits, AlignInBits, Flags,
1742-
MangledName, MangledName);
1743-
17441782
llvm::DICompositeType *DITy = DBuilder.createStructType(
17451783
Scope, MangledName, MainFile, 0, SizeInBits, AlignInBits, Flags,
17461784
nullptr, // DerivedFrom
1747-
DBuilder.getOrCreateArray(Elements), llvm::dwarf::DW_LANG_Swift,
1748-
nullptr, MangledName);
1785+
DBuilder.getOrCreateArray(Members), llvm::dwarf::DW_LANG_Swift, nullptr,
1786+
MangledName);
17491787

17501788
return DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
17511789
}

0 commit comments

Comments
 (0)