Skip to content

[DebugInfo] Move type size information to CompletedDebugTypeInfo #72158

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions include/swift/SIL/SILDebugInfoExpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,16 +296,6 @@ class SILDebugInfoExpression {
return Elements.size() &&
Elements[0].getAsOperator() == SILDIExprOperator::Dereference;
}

/// Return true if this DIExpression has a fragment (at the end)
bool hasFragment() const {
return (Elements.size() >= 2 &&
Elements[Elements.size() - 2].getAsOperator() ==
SILDIExprOperator::Fragment) ||
(Elements.size() >= 3 &&
Elements[Elements.size() - 3].getAsOperator() ==
SILDIExprOperator::TupleFragment);
}
};

/// Returns the hashcode for the di expr element.
Expand Down
73 changes: 39 additions & 34 deletions lib/IRGen/DebugTypeInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,13 @@ using namespace swift;
using namespace irgen;

DebugTypeInfo::DebugTypeInfo(swift::Type Ty, llvm::Type *FragmentStorageTy,
std::optional<Size::int_type> SizeInBits,
Alignment Align, bool HasDefaultAlignment,
bool IsMetadata, bool SizeIsFragmentSize,
bool IsFixedBuffer,
bool IsMetadata, bool IsFixedBuffer,
std::optional<uint32_t> NumExtraInhabitants)
: Type(Ty.getPointer()), FragmentStorageType(FragmentStorageTy),
SizeInBits(SizeInBits), NumExtraInhabitants(NumExtraInhabitants),
NumExtraInhabitants(NumExtraInhabitants),
Align(Align), DefaultAlignment(HasDefaultAlignment),
IsMetadataType(IsMetadata), SizeIsFragmentSize(SizeIsFragmentSize),
IsFixedBuffer(IsFixedBuffer) {
IsMetadataType(IsMetadata), IsFixedBuffer(IsFixedBuffer) {
assert(Align.getValue() != 0);
}

Expand All @@ -50,32 +47,23 @@ static bool hasDefaultAlignment(swift::Type Ty) {
}

DebugTypeInfo DebugTypeInfo::getFromTypeInfo(swift::Type Ty, const TypeInfo &TI,
IRGenModule &IGM,
bool IsFragmentTypeInfo) {
std::optional<Size::int_type> SizeInBits;
IRGenModule &IGM) {
llvm::Type *StorageType = TI.getStorageType();
std::optional<uint32_t> NumExtraInhabitants;
if (StorageType->isSized())
SizeInBits = IGM.DataLayout.getTypeSizeInBits(StorageType);
else if (TI.isFixedSize()) {
const FixedTypeInfo &FixTy = *cast<const FixedTypeInfo>(&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,
return DebugTypeInfo(Ty.getPointer(), StorageType,
TI.getBestKnownAlignment(), ::hasDefaultAlignment(Ty),
false, IsFragmentTypeInfo, false, NumExtraInhabitants);
/* IsMetadataType = */ false,
/* IsFixedBuffer = */ false, NumExtraInhabitants);
}

DebugTypeInfo DebugTypeInfo::getLocalVariable(VarDecl *Decl, swift::Type Ty,
const TypeInfo &Info,
IRGenModule &IGM,
bool IsFragmentTypeInfo) {
IRGenModule &IGM) {

auto DeclType = Decl->getInterfaceType();
auto RealType = Ty;
Expand All @@ -89,14 +77,15 @@ DebugTypeInfo DebugTypeInfo::getLocalVariable(VarDecl *Decl, swift::Type Ty,
// the type hasn't been mucked with by an optimization pass.
auto *Type = Sugared->isEqual(RealType) ? DeclType.getPointer()
: RealType.getPointer();
return getFromTypeInfo(Type, Info, IGM, IsFragmentTypeInfo);
return getFromTypeInfo(Type, Info, IGM);
}

DebugTypeInfo DebugTypeInfo::getGlobalMetadata(swift::Type Ty,
llvm::Type *StorageTy, Size size,
Alignment align) {
DebugTypeInfo DbgTy(Ty.getPointer(), StorageTy, size.getValue() * 8, align,
true, false, false);
DebugTypeInfo DbgTy(Ty.getPointer(), StorageTy, align,
/* HasDefaultAlignment = */ true,
/* IsMetadataType = */ false);
assert(StorageTy && "StorageType is a nullptr");
assert(!DbgTy.isContextArchetype() &&
"type metadata cannot contain an archetype");
Expand All @@ -106,8 +95,9 @@ DebugTypeInfo DebugTypeInfo::getGlobalMetadata(swift::Type Ty,
DebugTypeInfo DebugTypeInfo::getTypeMetadata(swift::Type Ty,
llvm::Type *StorageTy, Size size,
Alignment align) {
DebugTypeInfo DbgTy(Ty.getPointer(), StorageTy, size.getValue() * 8, align,
true, true, false);
DebugTypeInfo DbgTy(Ty.getPointer(), StorageTy, align,
/* HasDefaultAlignment = */ true,
/* IsMetadataType = */ true);
assert(StorageTy && "StorageType is a nullptr");
assert(!DbgTy.isContextArchetype() &&
"type metadata cannot contain an archetype");
Expand All @@ -132,7 +122,7 @@ DebugTypeInfo DebugTypeInfo::getGlobal(SILGlobalVariable *GV,
Type = DeclType.getPointer();
}
auto &TI = IGM.getTypeInfoForUnlowered(Type);
DebugTypeInfo DbgTy = getFromTypeInfo(Type, TI, IGM, false);
DebugTypeInfo DbgTy = getFromTypeInfo(Type, TI, IGM);
assert(FragmentStorageType && "FragmentStorageType is a nullptr");
assert(!DbgTy.isContextArchetype() &&
"type of global variable cannot be an archetype");
Expand All @@ -152,8 +142,9 @@ DebugTypeInfo::getGlobalFixedBuffer(SILGlobalVariable *GV,
if (DeclType->isEqual(LowTy))
Type = DeclType.getPointer();
}
DebugTypeInfo DbgTy(Type, FragmentStorageType, SizeInBytes.getValue() * 8,
Align, ::hasDefaultAlignment(Type), false, false, true);
DebugTypeInfo DbgTy(Type, FragmentStorageType,
Align, ::hasDefaultAlignment(Type),
/* IsMetadataType = */ false, /* IsFixedBuffer = */ true);
assert(FragmentStorageType && "FragmentStorageType is a nullptr");
assert(!DbgTy.isContextArchetype() &&
"type of global variable cannot be an archetype");
Expand All @@ -164,8 +155,9 @@ DebugTypeInfo DebugTypeInfo::getObjCClass(ClassDecl *theClass,
llvm::Type *FragmentStorageType,
Size SizeInBytes, Alignment align) {
DebugTypeInfo DbgTy(theClass->getInterfaceType().getPointer(),
FragmentStorageType, SizeInBytes.getValue() * 8, align,
true, false, false);
FragmentStorageType, align,
/* HasDefaultAlignment = */ true,
/* IsMetadataType = */ false);
assert(FragmentStorageType && "FragmentStorageType is a nullptr");
assert(!DbgTy.isContextArchetype() &&
"type of objc class cannot be an archetype");
Expand All @@ -175,13 +167,12 @@ DebugTypeInfo DebugTypeInfo::getObjCClass(ClassDecl *theClass,
DebugTypeInfo DebugTypeInfo::getErrorResult(swift::Type Ty,
IRGenModule &IGM) {
auto &TI = IGM.getTypeInfoForUnlowered(Ty);
DebugTypeInfo DbgTy = getFromTypeInfo(Ty, TI, IGM, false);
DebugTypeInfo DbgTy = getFromTypeInfo(Ty, TI, IGM);
return DbgTy;
}

bool DebugTypeInfo::operator==(DebugTypeInfo T) const {
return getType() == T.getType() &&
SizeInBits == T.SizeInBits &&
Align == T.Align;
}

Expand All @@ -204,8 +195,6 @@ TypeDecl *DebugTypeInfo::getDecl() const {
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void DebugTypeInfo::dump() const {
llvm::errs() << "[";
if (SizeInBits)
llvm::errs() << "SizeInBits " << *SizeInBits << " ";
llvm::errs() << "Alignment " << Align.getValue() << "] ";
if (auto *Type = getType())
Type->dump(llvm::errs());
Expand All @@ -217,3 +206,19 @@ LLVM_DUMP_METHOD void DebugTypeInfo::dump() const {
llvm::errs() << "forward-declared\n";
}
#endif

std::optional<CompletedDebugTypeInfo>
CompletedDebugTypeInfo::getFromTypeInfo(swift::Type Ty, const TypeInfo &Info, IRGenModule &IGM) {
auto *StorageType = IGM.getStorageTypeForUnlowered(Ty);
std::optional<uint64_t> SizeInBits;
if (StorageType->isSized())
SizeInBits = IGM.DataLayout.getTypeSizeInBits(StorageType);
else if (Info.isFixedSize()) {
const FixedTypeInfo &FixTy = *cast<const FixedTypeInfo>(&Info);
Size::int_type Size = FixTy.getFixedSize().getValue() * 8;
SizeInBits = Size;
}

return CompletedDebugTypeInfo::get(
DebugTypeInfo::getFromTypeInfo(Ty, Info, IGM), SizeInBits);
}
45 changes: 16 additions & 29 deletions lib/IRGen/DebugTypeInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,27 +44,23 @@ class DebugTypeInfo {
/// Needed to determine the size of basic types and to determine
/// the storage type for undefined variables.
llvm::Type *FragmentStorageType = nullptr;
std::optional<Size::int_type> SizeInBits;
std::optional<uint32_t> NumExtraInhabitants;
Alignment Align;
bool DefaultAlignment = true;
bool IsMetadataType = false;
bool SizeIsFragmentSize = false;
bool IsFixedBuffer = false;

public:
DebugTypeInfo() = default;
DebugTypeInfo(swift::Type Ty, llvm::Type *StorageTy = nullptr,
std::optional<Size::int_type> SizeInBits = {},
Alignment AlignInBytes = Alignment(1),
bool HasDefaultAlignment = true, bool IsMetadataType = false,
bool IsFragmentTypeInfo = false, bool IsFixedBuffer = false,
bool IsFixedBuffer = false,
std::optional<uint32_t> NumExtraInhabitants = {});

/// Create type for a local variable.
static DebugTypeInfo getLocalVariable(VarDecl *Decl, swift::Type Ty,
const TypeInfo &Info, IRGenModule &IGM,
bool IsFragmentTypeInfo);
const TypeInfo &Info, IRGenModule &IGM);
/// Create type for global type metadata.
static DebugTypeInfo getGlobalMetadata(swift::Type Ty, llvm::Type *StorageTy,
Size size, Alignment align);
Expand All @@ -77,8 +73,7 @@ class DebugTypeInfo {

/// Create a standalone type from a TypeInfo object.
static DebugTypeInfo getFromTypeInfo(swift::Type Ty, const TypeInfo &Info,
IRGenModule &IGM,
bool IsFragmentTypeInfo);
IRGenModule &IGM);
/// Global variables.
static DebugTypeInfo getGlobal(SILGlobalVariable *GV,
llvm::Type *StorageType, IRGenModule &IGM);
Expand All @@ -105,21 +100,12 @@ class DebugTypeInfo {
return false;
}

llvm::Type *getFragmentStorageType() const {
if (SizeInBits && *SizeInBits == 0)
assert(FragmentStorageType && "only defined types may have a size");
return FragmentStorageType;
}
std::optional<Size::int_type> getTypeSizeInBits() const {
return SizeIsFragmentSize ? std::nullopt : SizeInBits;
}
std::optional<Size::int_type> getRawSizeInBits() const { return SizeInBits; }
llvm::Type *getFragmentStorageType() const { return FragmentStorageType; }
Alignment getAlignment() const { return Align; }
bool isNull() const { return Type == nullptr; }
bool isForwardDecl() const { return FragmentStorageType == nullptr; }
bool isMetadataType() const { return IsMetadataType; }
bool hasDefaultAlignment() const { return DefaultAlignment; }
bool isSizeFragmentSize() const { return SizeIsFragmentSize; }
bool isFixedBuffer() const { return IsFixedBuffer; }
std::optional<uint32_t> getNumExtraInhabitants() const {
return NumExtraInhabitants;
Expand All @@ -134,22 +120,23 @@ class DebugTypeInfo {

/// A DebugTypeInfo with a defined size (that may be 0).
class CompletedDebugTypeInfo : public DebugTypeInfo {
CompletedDebugTypeInfo(DebugTypeInfo DbgTy) : DebugTypeInfo(DbgTy) {}
Size::int_type SizeInBits;

CompletedDebugTypeInfo(DebugTypeInfo DbgTy, Size::int_type SizeInBits)
: DebugTypeInfo(DbgTy), SizeInBits(SizeInBits) {}

public:
static std::optional<CompletedDebugTypeInfo> get(DebugTypeInfo DbgTy) {
if (!DbgTy.getRawSizeInBits() || DbgTy.isSizeFragmentSize())
static std::optional<CompletedDebugTypeInfo>
get(DebugTypeInfo DbgTy, std::optional<Size::int_type> SizeInBits) {
if (!SizeInBits)
return {};
return CompletedDebugTypeInfo(DbgTy);
return CompletedDebugTypeInfo(DbgTy, *SizeInBits);
}

static std::optional<CompletedDebugTypeInfo>
getFromTypeInfo(swift::Type Ty, const TypeInfo &Info, IRGenModule &IGM) {
return CompletedDebugTypeInfo::get(
DebugTypeInfo::getFromTypeInfo(Ty, Info, IGM, /*IsFragment*/ false));
}
getFromTypeInfo(swift::Type Ty, const TypeInfo &Info, IRGenModule &IGM);

Size::int_type getSizeInBits() const { return *SizeInBits; }
Size::int_type getSizeInBits() const { return SizeInBits; }
};

}
Expand All @@ -164,8 +151,8 @@ template <> struct DenseMapInfo<swift::irgen::DebugTypeInfo> {
}
static swift::irgen::DebugTypeInfo getTombstoneKey() {
return swift::irgen::DebugTypeInfo(
llvm::DenseMapInfo<swift::TypeBase *>::getTombstoneKey(), nullptr, 0,
swift::irgen::Alignment(), false, false, false);
llvm::DenseMapInfo<swift::TypeBase *>::getTombstoneKey(), nullptr,
swift::irgen::Alignment(), /* HasDefaultAlignment = */ false);
}
static unsigned getHashValue(swift::irgen::DebugTypeInfo Val) {
return DenseMapInfo<swift::CanType>::getHashValue(Val.getType());
Expand Down
Loading