Skip to content

Commit 6e3e28c

Browse files
authored
Merge pull request #9455 from swiftlang/revert-9425-remove-spare-bits-debug
Revert "[DebugInfo] Remove spare bits mask from LLVM IR and DWARF"
2 parents 0657c77 + 96cc8ae commit 6e3e28c

File tree

16 files changed

+324
-81
lines changed

16 files changed

+324
-81
lines changed

lldb/source/Plugins/LanguageRuntime/Swift/ReflectionContext.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ struct DescriptorFinderForwarder : public swift::reflection::DescriptorFinder {
4545
return nullptr;
4646
}
4747

48+
std::unique_ptr<swift::reflection::MultiPayloadEnumDescriptorBase>
49+
getMultiPayloadEnumDescriptor(const swift::reflection::TypeRef *TR) override {
50+
if (!m_descriptor_finders.empty() && shouldConsultDescriptorFinder())
51+
return m_descriptor_finders.back()->getMultiPayloadEnumDescriptor(TR);
52+
return nullptr;
53+
}
54+
4855
void PushExternalDescriptorFinder(
4956
swift::reflection::DescriptorFinder *descriptor_finder) {
5057
m_descriptor_finders.push_back(descriptor_finder);

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserSwift.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ class DWARFASTParserSwift : public lldb_private::plugin::dwarf::DWARFASTParser,
8989
std::unique_ptr<swift::reflection::BuiltinTypeDescriptorBase>
9090
getBuiltinTypeDescriptor(const swift::reflection::TypeRef *TR) override;
9191

92+
/// Returns a builtin descriptor constructed from DWARF info.
93+
std::unique_ptr<swift::reflection::MultiPayloadEnumDescriptorBase>
94+
getMultiPayloadEnumDescriptor(const swift::reflection::TypeRef *TR) override;
95+
9296
private:
9397
/// Returns the canonical demangle tree of a die's type.
9498
NodePointer GetCanonicalDemangleTree(DWARFDIE &die);

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserSwiftDescriptorFinder.cpp

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,53 @@ class DWARFFieldDescriptorImpl : public swift::reflection::FieldDescriptorBase {
280280
return payload_fields;
281281
}
282282
};
283+
284+
class DWARFMultiPayloadEnumDescriptorImpl
285+
: public swift::reflection::MultiPayloadEnumDescriptorBase {
286+
ConstString m_mangled_name;
287+
DIERef m_die_ref;
288+
std::vector<uint8_t> m_spare_bits_mask;
289+
uint64_t m_byte_offset;
290+
291+
public:
292+
~DWARFMultiPayloadEnumDescriptorImpl() override = default;
293+
294+
DWARFMultiPayloadEnumDescriptorImpl(ConstString mangled_name, DIERef die_ref,
295+
std::vector<uint8_t> &&spare_bits_mask,
296+
uint64_t byte_offset)
297+
: swift::reflection::MultiPayloadEnumDescriptorBase(),
298+
m_mangled_name(mangled_name), m_die_ref(die_ref),
299+
m_spare_bits_mask(std::move(spare_bits_mask)),
300+
m_byte_offset(byte_offset) {}
301+
302+
llvm::StringRef getMangledTypeName() override {
303+
return m_mangled_name.GetStringRef();
304+
}
305+
306+
uint32_t getContentsSizeInWords() const override {
307+
return m_spare_bits_mask.size() / 4;
308+
}
309+
310+
size_t getSizeInBytes() const override { return m_spare_bits_mask.size(); }
311+
312+
uint32_t getFlags() const override { return usesPayloadSpareBits(); }
313+
314+
bool usesPayloadSpareBits() const override {
315+
return !m_spare_bits_mask.empty();
316+
}
317+
318+
uint32_t getPayloadSpareBitMaskByteOffset() const override {
319+
return m_byte_offset;
320+
}
321+
322+
uint32_t getPayloadSpareBitMaskByteCount() const override {
323+
return getSizeInBytes();
324+
}
325+
326+
const uint8_t *getPayloadSpareBits() const override {
327+
return m_spare_bits_mask.data();
328+
}
329+
};
283330
} // namespace
284331

285332
/// Constructs a builtin type descriptor from DWARF information.
@@ -327,6 +374,85 @@ DWARFASTParserSwift::getBuiltinTypeDescriptor(
327374
type.GetMangledTypeName());
328375
}
329376

377+
std::unique_ptr<swift::reflection::MultiPayloadEnumDescriptorBase>
378+
DWARFASTParserSwift::getMultiPayloadEnumDescriptor(
379+
const swift::reflection::TypeRef *TR) {
380+
assert(ModuleList::GetGlobalModuleListProperties()
381+
.GetSwiftEnableFullDwarfDebugging() !=
382+
lldb_private::AutoBool::False &&
383+
"Full DWARF debugging for Swift is disabled!");
384+
385+
auto pair = getTypeAndDie(m_swift_typesystem, TR);
386+
if (!pair)
387+
return nullptr;
388+
389+
auto [type, die] = *pair;
390+
if (!die)
391+
return nullptr;
392+
393+
auto kind = getFieldDescriptorKindForDie(type);
394+
if (!kind)
395+
return nullptr;
396+
397+
auto child_die = die.GetFirstChild();
398+
auto bit_offset =
399+
child_die.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_bit_offset, 0);
400+
401+
auto byte_offset = (bit_offset + 7) / 8;
402+
403+
const auto &attributes = child_die.GetAttributes();
404+
auto spare_bits_mask_idx =
405+
attributes.FindAttributeIndex(llvm::dwarf::DW_AT_APPLE_spare_bits_mask);
406+
if (spare_bits_mask_idx == UINT32_MAX)
407+
return nullptr;
408+
409+
DWARFFormValue form_value;
410+
attributes.ExtractFormValueAtIndex(spare_bits_mask_idx, form_value);
411+
412+
if (!form_value.IsValid()) {
413+
if (auto *log = GetLog(LLDBLog::Types)) {
414+
std::stringstream ss;
415+
TR->dump(ss);
416+
LLDB_LOG(log,
417+
"Could not produce MultiPayloadEnumTypeInfo for typeref: {0}",
418+
ss.str());
419+
}
420+
return nullptr;
421+
}
422+
// If there's a block data, this is a number bigger than 64 bits already
423+
// encoded as an array.
424+
if (form_value.BlockData()) {
425+
uint64_t block_length = form_value.Unsigned();
426+
std::vector<uint8_t> bytes(form_value.BlockData(),
427+
form_value.BlockData() + block_length);
428+
return std::make_unique<DWARFMultiPayloadEnumDescriptorImpl>(
429+
type.GetMangledTypeName(), *die.GetDIERef(),
430+
std::move(bytes), byte_offset);
431+
}
432+
433+
// If there is no block data, the spare bits mask is encoded as a single 64
434+
// bit number. Convert this to a byte array with only the amount of bytes
435+
// necessary to cover the whole number (see
436+
// MultiPayloadEnumDescriptorBuilder::layout on GenReflection.cpp for a
437+
// similar calculation when emitting this into metadata).
438+
llvm::APInt bits(64, form_value.Unsigned());
439+
auto bitsInMask = bits.getActiveBits();
440+
uint32_t bytesInMask = (bitsInMask + 7) / 8;
441+
auto wordsInMask = (bytesInMask + 3) / 4;
442+
bits = bits.zextOrTrunc(wordsInMask * 32);
443+
444+
std::vector<uint8_t> bytes;
445+
for (size_t i = 0; i < bytesInMask; ++i) {
446+
uint8_t byte = bits.extractBitsAsZExtValue(8, 0);
447+
bytes.push_back(byte);
448+
bits.lshrInPlace(8);
449+
}
450+
451+
return std::make_unique<DWARFMultiPayloadEnumDescriptorImpl>(
452+
type.GetMangledTypeName(), *die.GetDIERef(), std::move(bytes),
453+
byte_offset);
454+
}
455+
330456
namespace {
331457
DWARFDIE FindSuperClassDIE(DWARFDIE &die) {
332458
const auto inheritance_die_it =

llvm/include/llvm/BinaryFormat/Dwarf.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ HANDLE_DW_AT(0x3fee, APPLE_objc_direct, 0, APPLE)
636636
HANDLE_DW_AT(0x3fef, APPLE_sdk, 0, APPLE)
637637
HANDLE_DW_AT(0x3ff0, APPLE_origin, 0, APPLE)
638638
HANDLE_DW_AT(0x3ff1, APPLE_num_extra_inhabitants, 0, APPLE)
639+
HANDLE_DW_AT(0x3ff2, APPLE_spare_bits_mask, 0, APPLE)
639640

640641
// Attribute form encodings.
641642
HANDLE_DW_FORM(0x01, addr, 2, DWARF)

llvm/include/llvm/IR/DIBuilder.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,12 +533,17 @@ namespace llvm {
533533
/// \param Discriminator Discriminant member
534534
/// \param Elements Variant elements.
535535
/// \param UniqueIdentifier A unique identifier for the union.
536+
/// \param OffsetInBits The offset of the variant payload in the variant
537+
/// type.
538+
/// \param SpareBitMask A mask of spare bits of the payload, spare bits are
539+
/// bits that aren't used in any of the variant's cases.
536540
DICompositeType *
537541
createVariantPart(DIScope *Scope, StringRef Name, DIFile *File,
538542
unsigned LineNumber, uint64_t SizeInBits,
539543
uint32_t AlignInBits, DINode::DIFlags Flags,
540544
DIDerivedType *Discriminator, DINodeArray Elements,
541-
StringRef UniqueIdentifier = "");
545+
StringRef UniqueIdentifier = "",
546+
uint64_t OffsetInBits = 0, APInt SpareBitsMask = APInt());
542547

543548
/// Create debugging information for template
544549
/// type parameter.

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,15 +1172,16 @@ class DICompositeType : public DIType {
11721172
friend class MDNode;
11731173

11741174
unsigned RuntimeLang;
1175+
llvm::APInt SpareBitsMask;
11751176

11761177
DICompositeType(LLVMContext &C, StorageType Storage, unsigned Tag,
11771178
unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits,
11781179
uint32_t AlignInBits, uint64_t OffsetInBits,
1179-
uint32_t NumExtraInhabitants, DIFlags Flags,
1180-
ArrayRef<Metadata *> Ops)
1180+
uint32_t NumExtraInhabitants, APInt SpareBitsMask,
1181+
DIFlags Flags, ArrayRef<Metadata *> Ops)
11811182
: DIType(C, DICompositeTypeKind, Storage, Tag, Line, SizeInBits,
11821183
AlignInBits, OffsetInBits, NumExtraInhabitants, Flags, Ops),
1183-
RuntimeLang(RuntimeLang) {}
1184+
RuntimeLang(RuntimeLang), SpareBitsMask(SpareBitsMask) {}
11841185
~DICompositeType() = default;
11851186

11861187
/// Change fields in place.
@@ -1198,20 +1199,20 @@ class DICompositeType : public DIType {
11981199
getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, Metadata *File,
11991200
unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
12001201
uint32_t AlignInBits, uint64_t OffsetInBits, DIType *SpecificationOf,
1201-
uint32_t NumExtraInhabitants, DIFlags Flags, DINodeArray Elements,
1202-
unsigned RuntimeLang, DIType *VTableHolder,
1202+
uint32_t NumExtraInhabitants, APInt SpareBitsMask, DIFlags Flags,
1203+
DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
12031204
DITemplateParameterArray TemplateParams, StringRef Identifier,
12041205
DIDerivedType *Discriminator, Metadata *DataLocation,
12051206
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
12061207
DINodeArray Annotations, StorageType Storage,
12071208
bool ShouldCreate = true) {
1208-
return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
1209-
Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
1210-
Flags, Elements.get(), RuntimeLang, VTableHolder,
1211-
TemplateParams.get(),
1212-
getCanonicalMDString(Context, Identifier), Discriminator,
1213-
DataLocation, Associated, Allocated, Rank, Annotations.get(),
1214-
SpecificationOf, NumExtraInhabitants, Storage, ShouldCreate);
1209+
return getImpl(
1210+
Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
1211+
BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
1212+
RuntimeLang, VTableHolder, TemplateParams.get(),
1213+
getCanonicalMDString(Context, Identifier), Discriminator, DataLocation,
1214+
Associated, Allocated, Rank, Annotations.get(), SpecificationOf,
1215+
NumExtraInhabitants, SpareBitsMask, Storage, ShouldCreate);
12151216
}
12161217
static DICompositeType *
12171218
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
@@ -1222,8 +1223,8 @@ class DICompositeType : public DIType {
12221223
MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation,
12231224
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
12241225
Metadata *Annotations, Metadata *SpecificationOf,
1225-
uint32_t NumExtraInhabitants, StorageType Storage,
1226-
bool ShouldCreate = true);
1226+
uint32_t NumExtraInhabitants, APInt SpareBitsMask,
1227+
StorageType Storage, bool ShouldCreate = true);
12271228

12281229
TempDICompositeType cloneImpl() const {
12291230
return getTemporary(
@@ -1233,7 +1234,7 @@ class DICompositeType : public DIType {
12331234
getTemplateParams(), getIdentifier(), getDiscriminator(),
12341235
getRawDataLocation(), getRawAssociated(), getRawAllocated(),
12351236
getRawRank(), getAnnotations(), getSpecificationOf(),
1236-
getNumExtraInhabitants());
1237+
getNumExtraInhabitants(), getSpareBitsMask());
12371238
}
12381239

12391240
public:
@@ -1248,11 +1249,11 @@ class DICompositeType : public DIType {
12481249
Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
12491250
Metadata *Allocated = nullptr, Metadata *Rank = nullptr,
12501251
DINodeArray Annotations = nullptr, DIType *SpecificationOf = nullptr,
1251-
uint32_t NumExtraInhabitants = 0),
1252+
uint32_t NumExtraInhabitants = 0, APInt SpareBitsMask = APInt()),
12521253
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
1253-
OffsetInBits, SpecificationOf, NumExtraInhabitants, Flags, Elements,
1254-
RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator,
1255-
DataLocation, Associated, Allocated, Rank, Annotations))
1254+
OffsetInBits, SpecificationOf, NumExtraInhabitants, SpareBitsMask, Flags,
1255+
Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier,
1256+
Discriminator, DataLocation, Associated, Allocated, Rank, Annotations))
12561257
DEFINE_MDNODE_GET(
12571258
DICompositeType,
12581259
(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
@@ -1263,11 +1264,12 @@ class DICompositeType : public DIType {
12631264
Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
12641265
Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
12651266
Metadata *Rank = nullptr, Metadata *Annotations = nullptr,
1266-
Metadata *SpecificationOf = nullptr, uint32_t NumExtraInhabitants = 0),
1267+
Metadata *SpecificationOf = nullptr, uint32_t NumExtraInhabitants = 0,
1268+
APInt SpareBitsMask = APInt()),
12671269
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
12681270
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
12691271
Identifier, Discriminator, DataLocation, Associated, Allocated, Rank,
1270-
Annotations, SpecificationOf, NumExtraInhabitants))
1272+
Annotations, SpecificationOf, NumExtraInhabitants, SpareBitsMask))
12711273

12721274
TempDICompositeType clone() const { return cloneImpl(); }
12731275

@@ -1283,7 +1285,7 @@ class DICompositeType : public DIType {
12831285
MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
12841286
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
12851287
uint64_t OffsetInBits, Metadata *SpecificationOf,
1286-
uint32_t NumExtraInhabitants, DIFlags Flags,
1288+
uint32_t NumExtraInhabitants, APInt SpareBitsMask, DIFlags Flags,
12871289
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
12881290
Metadata *TemplateParams, Metadata *Discriminator,
12891291
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
@@ -1305,8 +1307,8 @@ class DICompositeType : public DIType {
13051307
MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
13061308
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
13071309
uint64_t OffsetInBits, Metadata *SpecificationOf,
1308-
uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements,
1309-
unsigned RuntimeLang, Metadata *VTableHolder,
1310+
uint32_t NumExtraInhabitants, APInt SpareBitsMask, DIFlags Flags,
1311+
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
13101312
Metadata *TemplateParams, Metadata *Discriminator,
13111313
Metadata *DataLocation, Metadata *Associated,
13121314
Metadata *Allocated, Metadata *Rank, Metadata *Annotations);
@@ -1323,6 +1325,7 @@ class DICompositeType : public DIType {
13231325
}
13241326
StringRef getIdentifier() const { return getStringOperand(7); }
13251327
unsigned getRuntimeLang() const { return RuntimeLang; }
1328+
const APInt &getSpareBitsMask() const { return SpareBitsMask; }
13261329

13271330
Metadata *getRawBaseType() const { return getOperand(3); }
13281331
Metadata *getRawElements() const { return getOperand(4); }

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5433,7 +5433,8 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
54335433
OPTIONAL(rank, MDSignedOrMDField, ); \
54345434
OPTIONAL(annotations, MDField, ); \
54355435
OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX)); \
5436-
OPTIONAL(specification_of, MDField, );
5436+
OPTIONAL(specification_of, MDField, ); \
5437+
OPTIONAL(spare_bits_mask, MDAPSIntField, );
54375438
PARSE_MD_FIELDS();
54385439
#undef VISIT_MD_FIELDS
54395440

@@ -5449,10 +5450,11 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
54495450
if (auto *CT = DICompositeType::buildODRType(
54505451
Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val,
54515452
scope.Val, baseType.Val, size.Val, align.Val, offset.Val,
5452-
specification_of.Val, num_extra_inhabitants.Val, flags.Val,
5453-
elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val,
5454-
discriminator.Val, dataLocation.Val, associated.Val, allocated.Val,
5455-
Rank, annotations.Val)) {
5453+
specification_of.Val, num_extra_inhabitants.Val,
5454+
spare_bits_mask.Val, flags.Val, elements.Val, runtimeLang.Val,
5455+
vtableHolder.Val, templateParams.Val, discriminator.Val,
5456+
dataLocation.Val, associated.Val, allocated.Val, Rank,
5457+
annotations.Val)) {
54565458
Result = CT;
54575459
return false;
54585460
}
@@ -5465,7 +5467,8 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
54655467
size.Val, align.Val, offset.Val, flags.Val, elements.Val,
54665468
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val,
54675469
discriminator.Val, dataLocation.Val, associated.Val, allocated.Val, Rank,
5468-
annotations.Val, specification_of.Val, num_extra_inhabitants.Val));
5470+
annotations.Val, specification_of.Val, num_extra_inhabitants.Val,
5471+
spare_bits_mask.Val));
54695472
return false;
54705473
}
54715474

0 commit comments

Comments
 (0)