Emit extra inhabitants in debug info for basic types

To support debugging embedded Swift, we will need to store information
that previously we searched in metadata. Extra inhabitants is one of
those.
This commit is contained in:
Augusto Noronha
2023-10-20 11:13:34 -07:00
parent 9aa17720c3
commit 75e45bd024
4 changed files with 31 additions and 9 deletions

View File

@@ -29,11 +29,13 @@ DebugTypeInfo::DebugTypeInfo(swift::Type Ty, llvm::Type *FragmentStorageTy,
llvm::Optional<Size::int_type> SizeInBits,
Alignment Align, bool HasDefaultAlignment,
bool IsMetadata, bool SizeIsFragmentSize,
bool IsFixedBuffer)
bool IsFixedBuffer,
std::optional<uint32_t> NumExtraInhabitants)
: Type(Ty.getPointer()), FragmentStorageType(FragmentStorageTy),
SizeInBits(SizeInBits), Align(Align),
DefaultAlignment(HasDefaultAlignment), IsMetadataType(IsMetadata),
SizeIsFragmentSize(SizeIsFragmentSize), IsFixedBuffer(IsFixedBuffer) {
SizeInBits(SizeInBits), NumExtraInhabitants(NumExtraInhabitants),
Align(Align), DefaultAlignment(HasDefaultAlignment),
IsMetadataType(IsMetadata), SizeIsFragmentSize(SizeIsFragmentSize),
IsFixedBuffer(IsFixedBuffer) {
assert(Align.getValue() != 0);
}
@@ -52,6 +54,7 @@ DebugTypeInfo DebugTypeInfo::getFromTypeInfo(swift::Type Ty, const TypeInfo &TI,
bool IsFragmentTypeInfo) {
llvm::Optional<Size::int_type> SizeInBits;
llvm::Type *StorageType = TI.getStorageType();
std::optional<uint32_t> NumExtraInhabitants;
if (StorageType->isSized())
SizeInBits = IGM.DataLayout.getTypeSizeInBits(StorageType);
else if (TI.isFixedSize()) {
@@ -59,10 +62,14 @@ DebugTypeInfo DebugTypeInfo::getFromTypeInfo(swift::Type Ty, const TypeInfo &TI,
Size::int_type Size = FixTy.getFixedSize().getValue() * 8;
SizeInBits = Size;
}
if (TI.isFixedSize()) {
const FixedTypeInfo &FixTy = *cast<const FixedTypeInfo>(&TI);
NumExtraInhabitants = FixTy.getFixedExtraInhabitantCount(IGM);
}
assert(TI.getStorageType() && "StorageType is a nullptr");
return DebugTypeInfo(Ty.getPointer(), StorageType, SizeInBits,
TI.getBestKnownAlignment(), ::hasDefaultAlignment(Ty),
false, IsFragmentTypeInfo);
false, IsFragmentTypeInfo, false, NumExtraInhabitants);
}
DebugTypeInfo DebugTypeInfo::getLocalVariable(VarDecl *Decl, swift::Type Ty,

View File

@@ -45,6 +45,7 @@ protected:
/// the storage type for undefined variables.
llvm::Type *FragmentStorageType = nullptr;
llvm::Optional<Size::int_type> SizeInBits;
std::optional<uint32_t> NumExtraInhabitants;
Alignment Align;
bool DefaultAlignment = true;
bool IsMetadataType = false;
@@ -57,7 +58,8 @@ public:
llvm::Optional<Size::int_type> SizeInBits = {},
Alignment AlignInBytes = Alignment(1),
bool HasDefaultAlignment = true, bool IsMetadataType = false,
bool IsFragmentTypeInfo = false, bool IsFixedBuffer = false);
bool IsFragmentTypeInfo = false, bool IsFixedBuffer = false,
std::optional<uint32_t> NumExtraInhabitants = {});
/// Create type for a local variable.
static DebugTypeInfo getLocalVariable(VarDecl *Decl, swift::Type Ty,
@@ -119,6 +121,9 @@ public:
bool hasDefaultAlignment() const { return DefaultAlignment; }
bool isSizeFragmentSize() const { return SizeIsFragmentSize; }
bool isFixedBuffer() const { return IsFixedBuffer; }
std::optional<uint32_t> getNumExtraInhabitants() const {
return NumExtraInhabitants;
}
bool operator==(DebugTypeInfo T) const;
bool operator!=(DebugTypeInfo T) const;

View File

@@ -1363,6 +1363,7 @@ private:
? 0
: DbgTy.getAlignment().getValue() * SizeOfByte;
unsigned Encoding = 0;
uint32_t NumExtraInhabitants = 0;
llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
TypeBase *BaseTy = DbgTy.getType();
@@ -1386,6 +1387,8 @@ private:
Encoding = llvm::dwarf::DW_ATE_unsigned;
if (auto CompletedDbgTy = CompletedDebugTypeInfo::get(DbgTy))
SizeInBits = getSizeOfBasicType(*CompletedDbgTy);
if (auto DbgTyNumExtraInhabitants = DbgTy.getNumExtraInhabitants())
NumExtraInhabitants = *DbgTyNumExtraInhabitants;
break;
}
@@ -1393,6 +1396,8 @@ private:
Encoding = llvm::dwarf::DW_ATE_unsigned; // ?
if (auto CompletedDbgTy = CompletedDebugTypeInfo::get(DbgTy))
SizeInBits = getSizeOfBasicType(*CompletedDbgTy);
if (auto DbgTyNumExtraInhabitants = DbgTy.getNumExtraInhabitants())
NumExtraInhabitants = *DbgTyNumExtraInhabitants;
break;
}
@@ -1401,6 +1406,8 @@ private:
// Assuming that the bitwidth and FloatTy->getFPKind() are identical.
SizeInBits = FloatTy->getBitWidth();
Encoding = llvm::dwarf::DW_ATE_float;
if (auto DbgTyNumExtraInhabitants = DbgTy.getNumExtraInhabitants())
NumExtraInhabitants = *DbgTyNumExtraInhabitants;
break;
}
@@ -1726,7 +1733,8 @@ private:
DebugTypeInfo AliasedDbgTy(
AliasedTy, DbgTy.getFragmentStorageType(), DbgTy.getRawSizeInBits(),
DbgTy.getAlignment(), DbgTy.hasDefaultAlignment(), false,
DbgTy.isSizeFragmentSize(), DbgTy.isFixedBuffer());
DbgTy.isSizeFragmentSize(), DbgTy.isFixedBuffer(),
DbgTy.getNumExtraInhabitants());
return DBuilder.createTypedef(getOrCreateType(AliasedDbgTy), MangledName,
File, 0, Scope);
}
@@ -1774,7 +1782,9 @@ private:
DbgTy.getType()->dump(llvm::dbgs()); llvm::dbgs() << "\n");
MangledName = "<unknown>";
}
return DBuilder.createBasicType(MangledName, SizeInBits, Encoding);
return DBuilder.createBasicType(MangledName, SizeInBits, Encoding,
llvm::DINode::FlagZero,
NumExtraInhabitants);
}
/// Determine if there exists a name mangling for the given type.

View File

@@ -5,7 +5,7 @@
func markUsed<T>(_ t: T) {}
// Int1 uses 1 bit, but is aligned at 8 bits.
// CHECK: !DIBasicType(name: "$sBi1_D", size: 1, encoding: DW_ATE_unsigned)
// CHECK: !DIBasicType(name: "$sBi1_D", size: 1, encoding: DW_ATE_unsigned, num_extra_inhabitants: 254)
// Bool has a fixed layout with a storage size of 1 byte and 7 "spare" bits.
// CHECK_G: !DICompositeType(tag: DW_TAG_structure_type, name: "Bool",
// CHECK_G-SAME: size: 8