Skip to content

Commit f259695

Browse files
committed
Revert "Debug Info: Retreive the layout information of exploded values from the"
This reverts commit 7e489db.
1 parent 7e489db commit f259695

File tree

3 files changed

+127
-104
lines changed

3 files changed

+127
-104
lines changed

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 124 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,74 @@ llvm::DIFile *IRGenDebugInfo::getFile(llvm::DIScope *Scope) {
885885
return cast<llvm::DIFile>(Scope);
886886
}
887887

888+
/// Return the storage size of an explosion value.
889+
static uint64_t getSizeFromExplosionValue(const clang::TargetInfo &TI,
890+
llvm::Value *V) {
891+
llvm::Type *Ty = V->getType();
892+
if (unsigned PrimitiveSize = Ty->getPrimitiveSizeInBits())
893+
return PrimitiveSize;
894+
else if (Ty->isPointerTy())
895+
return TI.getPointerWidth(0);
896+
else
897+
llvm_unreachable("unhandled type of explosion value");
898+
}
899+
900+
/// A generator that recursively returns the size of each element of a
901+
/// composite type.
902+
class ElementSizes {
903+
const TrackingDIRefMap &DIRefMap;
904+
llvm::SmallPtrSetImpl<const llvm::DIType *> &IndirectEnums;
905+
llvm::SmallVector<const llvm::DIType *, 12> Stack;
906+
public:
907+
ElementSizes(const llvm::DIType *DITy, const TrackingDIRefMap &DIRefMap,
908+
llvm::SmallPtrSetImpl<const llvm::DIType *> &IndirectEnums)
909+
: DIRefMap(DIRefMap), IndirectEnums(IndirectEnums), Stack(1, DITy) {}
910+
911+
struct SizeAlign {
912+
uint64_t SizeInBits, AlignInBits;
913+
};
914+
915+
struct SizeAlign getNext() {
916+
if (Stack.empty())
917+
return {0, 0};
918+
919+
auto *Cur = Stack.pop_back_val();
920+
if (isa<llvm::DICompositeType>(Cur) &&
921+
Cur->getTag() != llvm::dwarf::DW_TAG_subroutine_type) {
922+
auto *CTy = cast<llvm::DICompositeType>(Cur);
923+
auto Elts = CTy->getElements();
924+
unsigned N = Cur->getTag() == llvm::dwarf::DW_TAG_union_type
925+
? std::min(1U, Elts.size()) // For unions, pick any one.
926+
: Elts.size();
927+
928+
if (N) {
929+
// Push all elements in reverse order.
930+
// FIXME: With a little more state we don't need to actually
931+
// store them on the Stack.
932+
for (unsigned I = N; I > 0; --I)
933+
Stack.push_back(cast<llvm::DIType>(Elts[I - 1]));
934+
return getNext();
935+
}
936+
}
937+
switch (Cur->getTag()) {
938+
case llvm::dwarf::DW_TAG_member:
939+
// FIXME: Correctly handle the explosion value for enum types
940+
// with indirect members.
941+
if (IndirectEnums.count(Cur))
942+
return {0, 0};
943+
[[clang::fallthrough]];
944+
case llvm::dwarf::DW_TAG_typedef: {
945+
// Replace top of stack.
946+
auto *DTy = cast<llvm::DIDerivedType>(Cur);
947+
Stack.push_back(DTy->getBaseType().resolve(DIRefMap));
948+
return getNext();
949+
}
950+
default:
951+
return {Cur->getSizeInBits(), Cur->getAlignInBits()};
952+
}
953+
}
954+
};
955+
888956
static Size
889957
getStorageSize(const llvm::DataLayout &DL, ArrayRef<llvm::Value *> Storage) {
890958
unsigned size = 0;
@@ -944,16 +1012,13 @@ void IRGenDebugInfo::emitVariableDeclaration(
9441012
Optimized, Flags);
9451013

9461014
// Insert a debug intrinsic into the current block.
1015+
unsigned OffsetInBits = 0;
9471016
auto *BB = Builder.GetInsertBlock();
9481017
bool IsPiece = Storage.size() > 1;
9491018
uint64_t SizeOfByte = CI.getTargetInfo().getCharWidth();
9501019
unsigned VarSizeInBits = getSizeInBits(Var, DIRefMap);
951-
952-
// Running variables for the current/previous piece.
953-
unsigned SizeInBits = 0;
954-
unsigned AlignInBits = SizeOfByte;
955-
unsigned OffsetInBits = 0;
956-
1020+
ElementSizes EltSizes(DITy, DIRefMap, IndirectEnumCases);
1021+
auto Dim = EltSizes.getNext();
9571022
for (llvm::Value *Piece : Storage) {
9581023
SmallVector<uint64_t, 3> Operands;
9591024
if (Indirection)
@@ -965,22 +1030,32 @@ void IRGenDebugInfo::emitVariableDeclaration(
9651030
Piece = llvm::ConstantInt::get(llvm::Type::getInt64Ty(M.getContext()), 0);
9661031

9671032
if (IsPiece) {
968-
// Advance the offset and align it for the next piece.
969-
OffsetInBits += llvm::alignTo(SizeInBits, AlignInBits);
970-
SizeInBits = IGM.DataLayout.getTypeSizeInBits(Piece->getType());
971-
AlignInBits = IGM.DataLayout.getABITypeAlignment(Piece->getType());
972-
if (!AlignInBits)
973-
AlignInBits = SizeOfByte;
974-
975-
// Sanity checks.
976-
assert(SizeInBits && "zero-sized piece");
977-
assert(SizeInBits < VarSizeInBits && "piece covers entire var");
978-
assert(OffsetInBits+SizeInBits <= VarSizeInBits && "pars > totum");
979-
980-
// Add the piece DWARF expression.
1033+
// Try to get the size from the type if possible.
1034+
auto StorageSize = getSizeFromExplosionValue(CI.getTargetInfo(), Piece);
1035+
assert((Dim.SizeInBits != 0 || StorageSize != 0) &&
1036+
"zero-sized variable with nonzero storage size");
1037+
1038+
// FIXME: Occasionally we miss out that the Storage is actually a
1039+
// refcount wrapper. Silently skip these for now.
1040+
if (OffsetInBits+Dim.SizeInBits > VarSizeInBits)
1041+
break;
1042+
if (OffsetInBits == 0 && Dim.SizeInBits == VarSizeInBits)
1043+
break;
1044+
if (Dim.SizeInBits == 0)
1045+
break;
1046+
1047+
assert(Dim.SizeInBits < VarSizeInBits
1048+
&& "piece covers entire var");
1049+
assert(OffsetInBits+Dim.SizeInBits <= VarSizeInBits && "pars > totum");
9811050
Operands.push_back(llvm::dwarf::DW_OP_bit_piece);
9821051
Operands.push_back(OffsetInBits);
983-
Operands.push_back(SizeInBits);
1052+
Operands.push_back(Dim.SizeInBits);
1053+
1054+
auto Size = Dim.SizeInBits;
1055+
Dim = EltSizes.getNext();
1056+
OffsetInBits +=
1057+
llvm::alignTo(Size, Dim.AlignInBits ? Dim.AlignInBits
1058+
: SizeOfByte);
9841059
}
9851060
emitDbgIntrinsic(BB, Piece, Var, DBuilder.createExpression(Operands), Line,
9861061
Loc.Column, Scope, DS);
@@ -1259,46 +1334,14 @@ llvm::DIType *IRGenDebugInfo::createPointerSizedStruct(
12591334
unsigned PtrAlign = CI.getTargetInfo().getPointerAlign(0);
12601335
auto PtrTy = DBuilder.createPointerType(PointeeTy, PtrSize, PtrAlign);
12611336
llvm::Metadata *Elements[] = {
1262-
DBuilder.createMemberType(Scope, "ptr", File, 0,
1337+
DBuilder.createMemberType(Scope, "pointer", File, 0,
12631338
PtrSize, PtrAlign, 0, Flags, PtrTy)
12641339
};
12651340
return DBuilder.createStructType(
12661341
Scope, Name, File, Line, PtrSize, PtrAlign, Flags,
1267-
/* DerivedFrom */ nullptr, DBuilder.getOrCreateArray(Elements),
1268-
llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);
1269-
}
1270-
1271-
/// Create a 2*pointer-sized struct with a mangled name and a single
1272-
/// member of PointeeTy.
1273-
llvm::DIType *IRGenDebugInfo::createDoublePointerSizedStruct(
1274-
llvm::DIScope *Scope, StringRef Name, llvm::DIType *PointeeTy,
1275-
llvm::DIFile *File, unsigned Line, unsigned Flags, StringRef MangledName) {
1276-
unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
1277-
unsigned PtrAlign = CI.getTargetInfo().getPointerAlign(0);
1278-
llvm::Metadata *Elements[] = {
1279-
DBuilder.createMemberType(
1280-
Scope, "ptr", File, 0, PtrSize, PtrAlign, 0, Flags,
1281-
DBuilder.createPointerType(PointeeTy, PtrSize, PtrAlign)),
1282-
DBuilder.createMemberType(
1283-
Scope, "_", File, 0, PtrSize, PtrAlign, 0, Flags,
1284-
DBuilder.createPointerType(nullptr, PtrSize, PtrAlign))};
1285-
return DBuilder.createStructType(
1286-
Scope, Name, File, Line, 2*PtrSize, PtrAlign, Flags,
1287-
/* DerivedFrom */ nullptr, DBuilder.getOrCreateArray(Elements),
1288-
llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);
1289-
}
1290-
1291-
/// Create an opaque struct with a mangled name.
1292-
llvm::DIType *
1293-
IRGenDebugInfo::createOpaqueStruct(llvm::DIScope *Scope, StringRef Name,
1294-
llvm::DIFile *File, unsigned Line,
1295-
unsigned SizeInBits, unsigned AlignInBits,
1296-
unsigned Flags, StringRef MangledName) {
1297-
return DBuilder.createStructType(
1298-
Scope, Name, File, Line, SizeInBits, AlignInBits, Flags,
1299-
/* DerivedFrom */ nullptr,
1300-
DBuilder.getOrCreateArray(ArrayRef<llvm::Metadata *>()),
1301-
llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);
1342+
nullptr, // DerivedFrom
1343+
DBuilder.getOrCreateArray(Elements), llvm::dwarf::DW_LANG_Swift,
1344+
nullptr, MangledName);
13021345
}
13031346

13041347
/// Construct a DIType from a DebugTypeInfo object.
@@ -1454,7 +1497,6 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
14541497
}
14551498
Scope = getOrCreateModule(ModuleName, TheCU, ModuleName, ModulePath);
14561499
}
1457-
assert(SizeInBits == CI.getTargetInfo().getPointerWidth(0));
14581500
return createPointerSizedStruct(Scope, Decl->getNameStr(),
14591501
getOrCreateFile(L.Filename), L.Line, Flags,
14601502
MangledName);
@@ -1466,9 +1508,9 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
14661508
// FIXME: (LLVM branch) This should probably be a DW_TAG_interface_type.
14671509
auto L = getDebugLoc(SM, Decl);
14681510
auto File = getOrCreateFile(L.Filename);
1469-
return createOpaqueStruct(Scope, Decl ? Decl->getNameStr() : MangledName,
1470-
File, L.Line, SizeInBits, AlignInBits, Flags,
1471-
MangledName);
1511+
return createPointerSizedStruct(Scope,
1512+
Decl ? Decl->getNameStr() : MangledName,
1513+
File, L.Line, Flags, MangledName);
14721514
}
14731515

14741516
case TypeKind::ProtocolComposition: {
@@ -1478,16 +1520,15 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
14781520

14791521
// FIXME: emit types
14801522
// auto ProtocolCompositionTy = BaseTy->castTo<ProtocolCompositionType>();
1481-
return createOpaqueStruct(Scope, Decl ? Decl->getNameStr() : MangledName,
1482-
File, L.Line, SizeInBits, AlignInBits, Flags,
1483-
MangledName);
1523+
return createPointerSizedStruct(Scope,
1524+
Decl ? Decl->getNameStr() : MangledName,
1525+
File, L.Line, Flags, MangledName);
14841526
}
14851527

14861528
case TypeKind::UnboundGeneric: {
14871529
auto *UnboundTy = BaseTy->castTo<UnboundGenericType>();
14881530
auto *Decl = UnboundTy->getDecl();
14891531
auto L = getDebugLoc(SM, Decl);
1490-
assert(SizeInBits == CI.getTargetInfo().getPointerWidth(0));
14911532
return createPointerSizedStruct(Scope,
14921533
Decl ? Decl->getNameStr() : MangledName,
14931534
File, L.Line, Flags, MangledName);
@@ -1497,9 +1538,9 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
14971538
auto *StructTy = BaseTy->castTo<BoundGenericStructType>();
14981539
auto *Decl = StructTy->getDecl();
14991540
auto L = getDebugLoc(SM, Decl);
1500-
return createOpaqueStruct(Scope, Decl ? Decl->getNameStr() : MangledName,
1501-
File, L.Line, SizeInBits, AlignInBits, Flags,
1502-
MangledName);
1541+
return createPointerSizedStruct(Scope,
1542+
Decl ? Decl->getNameStr() : MangledName,
1543+
File, L.Line, Flags, MangledName);
15031544
}
15041545

15051546
case TypeKind::BoundGenericClass: {
@@ -1508,7 +1549,6 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
15081549
auto L = getDebugLoc(SM, Decl);
15091550
// TODO: We may want to peek at Decl->isObjC() and set this
15101551
// attribute accordingly.
1511-
assert(SizeInBits == CI.getTargetInfo().getPointerWidth(0));
15121552
return createPointerSizedStruct(Scope,
15131553
Decl ? Decl->getNameStr() : MangledName,
15141554
File, L.Line, Flags, MangledName);
@@ -1600,49 +1640,39 @@ llvm::DIType *IRGenDebugInfo::createType(DebugTypeInfo DbgTy,
16001640
case TypeKind::Function:
16011641
case TypeKind::PolymorphicFunction:
16021642
case TypeKind::GenericFunction: {
1603-
auto FwdDecl = llvm::TempDINode(DBuilder.createReplaceableCompositeType(
1643+
auto FwdDecl = llvm::TempDINode(
1644+
DBuilder.createReplaceableCompositeType(
16041645
llvm::dwarf::DW_TAG_subroutine_type, MangledName, Scope, File, 0,
1605-
llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
1606-
MangledName));
1607-
1646+
llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
1647+
MangledName));
1648+
16081649
auto TH = llvm::TrackingMDNodeRef(FwdDecl.get());
16091650
DITypeCache[DbgTy.getType()] = TH;
16101651

1611-
CanSILFunctionType FunTy;
1652+
CanSILFunctionType FunctionTy;
16121653
if (auto *SILFnTy = dyn_cast<SILFunctionType>(BaseTy))
1613-
FunTy = CanSILFunctionType(SILFnTy);
1654+
FunctionTy = CanSILFunctionType(SILFnTy);
16141655
// FIXME: Handling of generic parameters in SIL type lowering is in flux.
16151656
// DebugInfo doesn't appear to care about the generic context, so just
16161657
// throw it away before lowering.
16171658
else if (isa<GenericFunctionType>(BaseTy) ||
16181659
isa<PolymorphicFunctionType>(BaseTy)) {
16191660
auto *fTy = cast<AnyFunctionType>(BaseTy);
16201661
auto *nongenericTy = FunctionType::get(fTy->getInput(), fTy->getResult(),
1621-
fTy->getExtInfo());
1662+
fTy->getExtInfo());
16221663

1623-
FunTy = IGM.SILMod->Types.getLoweredType(nongenericTy)
1624-
.castTo<SILFunctionType>();
1664+
FunctionTy = IGM.SILMod->Types.getLoweredType(nongenericTy)
1665+
.castTo<SILFunctionType>();
16251666
} else
1626-
FunTy =
1667+
FunctionTy =
16271668
IGM.SILMod->Types.getLoweredType(BaseTy).castTo<SILFunctionType>();
1628-
auto Params = createParameterTypes(FunTy, DbgTy.getDeclContext());
1669+
auto Params = createParameterTypes(FunctionTy, DbgTy.getDeclContext());
16291670

1671+
// Functions are actually stored as a Pointer or a FunctionPairTy:
1672+
// { i8*, %swift.refcounted* }
16301673
auto FnTy = DBuilder.createSubroutineType(Params, Flags);
1631-
llvm::DIType *DITy;
1632-
if (FunTy->getRepresentation() == SILFunctionType::Representation::Thick) {
1633-
if (SizeInBits == 2 * CI.getTargetInfo().getPointerWidth(0))
1634-
// This is a FunctionPairTy: { i8*, %swift.refcounted* }.
1635-
DITy = createDoublePointerSizedStruct(Scope, MangledName, FnTy,
1636-
MainFile, 0, Flags, MangledName);
1637-
else
1638-
// This is a generic function as noted above.
1639-
DITy = createOpaqueStruct(Scope, MangledName, MainFile, 0, SizeInBits,
1640-
AlignInBits, Flags, MangledName);
1641-
} else {
1642-
assert(SizeInBits == CI.getTargetInfo().getPointerWidth(0));
1643-
DITy = createPointerSizedStruct(Scope, MangledName, FnTy, MainFile, 0,
1644-
Flags, MangledName);
1645-
}
1674+
auto DITy = createPointerSizedStruct(Scope, MangledName, FnTy,
1675+
MainFile, 0, Flags, MangledName);
16461676
DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
16471677
return DITy;
16481678
}

lib/IRGen/IRGenDebugInfo.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -264,13 +264,6 @@ class IRGenDebugInfo {
264264
llvm::DIType *PointeeTy,
265265
llvm::DIFile *File, unsigned Line,
266266
unsigned Flags, StringRef MangledName);
267-
llvm::DIType *createDoublePointerSizedStruct(
268-
llvm::DIScope *Scope, StringRef Name, llvm::DIType *PointeeTy,
269-
llvm::DIFile *File, unsigned Line, unsigned Flags, StringRef MangledName);
270-
llvm::DIType *createOpaqueStruct(llvm::DIScope *Scope, StringRef Name,
271-
llvm::DIFile *File, unsigned Line,
272-
unsigned SizeInBits, unsigned AlignInBits,
273-
unsigned Flags, StringRef MangledName);
274267
uint64_t getSizeOfBasicType(DebugTypeInfo DbgTy);
275268
TypeAliasDecl *getMetadataType();
276269
};

test/DebugInfo/fnptr.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ func main() -> Int64 {
1313
// CHECK-DAG: !DILocalVariable(name: "bar_function_pointer",{{.*}} line: [[@LINE+1]],{{.*}} type: !"[[BARPT:[^,]+]]"
1414
var bar_function_pointer = bar
1515
// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "[[BARPT]]",{{.*}} elements: ![[BARMEMBERS:[0-9]+]]
16-
// CHECK-DAG: ![[BARMEMBERS]] = !{![[BARMEMBER:.*]], {{.*}}}
16+
// CHECK-DAG: ![[BARMEMBERS]] = !{![[BARMEMBER:.*]]}
1717
// CHECK-DAG: ![[BARMEMBER]] = !DIDerivedType(tag: DW_TAG_member,{{.*}} baseType: ![[BARPTR:[0-9]+]]
1818
// CHECK-DAG: ![[BARPTR]] = !DIDerivedType(tag: DW_TAG_pointer_type,{{.*}} baseType: ![[BART:[0-9]+]]
1919
// CHECK-DAG: ![[BART]] = !DISubroutineType(types: ![[BARARGS:[0-9]+]])
@@ -22,7 +22,7 @@ func main() -> Int64 {
2222

2323
// CHECK-DAG: !DILocalVariable(name: "baz_function_pointer",{{.*}} type: !"[[BAZPT:[^,]+]]"
2424
// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "[[BAZPT]]",{{.*}} elements: ![[BAZMEMBERS:[0-9]+]]
25-
// CHECK-DAG: ![[BAZMEMBERS]] = !{![[BAZMEMBER:.*]], {{.*}}}
25+
// CHECK-DAG: ![[BAZMEMBERS]] = !{![[BAZMEMBER:.*]]}
2626
// CHECK-DAG: ![[BAZMEMBER]] = !DIDerivedType(tag: DW_TAG_member,{{.*}} baseType: ![[BAZPTR:[0-9]+]]
2727
// CHECK-DAG: ![[BAZPTR]] = !DIDerivedType(tag: DW_TAG_pointer_type,{{.*}} baseType: ![[BAZT:[0-9]+]]
2828
// CHECK-DAG: ![[BAZT]] = !DISubroutineType(types: ![[BAZARGS:.*]])
@@ -32,7 +32,7 @@ func main() -> Int64 {
3232

3333
// CHECK-DAG: !DILocalVariable(name: "barz_function_pointer",{{.*}} type: !"[[BARZPT:[^,]+]]"
3434
// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "[[BARZPT]]",{{.*}} elements: ![[BARZMEMBERS:[0-9]+]]
35-
// CHECK-DAG: ![[BARZMEMBERS]] = !{![[BARZMEMBER:.*]], {{.*}}}
35+
// CHECK-DAG: ![[BARZMEMBERS]] = !{![[BARZMEMBER:.*]]}
3636
// CHECK-DAG: ![[BARZMEMBER]] = !DIDerivedType(tag: DW_TAG_member,{{.*}} baseType: ![[BARZPTR:[0-9]+]]
3737
// CHECK-DAG: ![[BARZPTR]] = !DIDerivedType(tag: DW_TAG_pointer_type,{{.*}} baseType: ![[BARZT:[0-9]+]]
3838
// CHECK-DAG: ![[BARZT]] = !DISubroutineType(types: ![[BARZARGS:.*]])

0 commit comments

Comments
 (0)