Skip to content

Commit d8955fa

Browse files
committed
Add bit stride to DICompositeType
In Ada, an array can be packed and the elements can take less space than their natural object size. For example, for this type: type Packed_Array is array (4 .. 8) of Boolean; pragma pack (Packed_Array); ... each element of the array occupies a single bit, even though the "natural" size for a Boolean in memory is a byte. In DWARF, this is represented by putting a DW_AT_bit_stride onto the array type itself. This patch adds a bit stride to DICompositeType so that gnat-llvm can emit DWARF for these sorts of arrays. This also fixes a bug in MetadataLoader.cpp, introduced in llvm#124752. I don't know how to write a separate test case for that, but I believe the new array-bitstride.ll will fail if that fix is backed out.
1 parent 737a0ae commit d8955fa

File tree

14 files changed

+149
-65
lines changed

14 files changed

+149
-65
lines changed

llvm/docs/LangRef.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6336,7 +6336,10 @@ array is currently associated. The optional ``allocated`` is a
63366336
DIExpression that describes whether the allocatable array is currently
63376337
allocated. The optional ``rank`` is a DIExpression that describes the
63386338
rank (number of dimensions) of fortran assumed rank array (rank is
6339-
known at runtime).
6339+
known at runtime). The optional ``bitStride`` is an unsigned constant
6340+
that describes the number of bits occupied by an element of the array;
6341+
this is only needed if it differs from the element type's natural
6342+
size, and is normally used for packed arrays.
63406343

63416344
For ``DW_TAG_enumeration_type``, the ``elements:`` should be :ref:`enumerator
63426345
descriptors <DIEnumerator>`, each representing the definition of an enumeration

llvm/include/llvm/IR/DIBuilder.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,13 +609,15 @@ namespace llvm {
609609
/// \param Rank The rank attribute of a descriptor-based
610610
/// Fortran array, either a DIExpression* or
611611
/// a DIVariable*.
612+
/// \param BitStride The bit size of an element of the array.
612613
DICompositeType *createArrayType(
613614
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
614615
uint64_t Size, uint32_t AlignInBits, DIType *Ty, DINodeArray Subscripts,
615616
PointerUnion<DIExpression *, DIVariable *> DataLocation = nullptr,
616617
PointerUnion<DIExpression *, DIVariable *> Associated = nullptr,
617618
PointerUnion<DIExpression *, DIVariable *> Allocated = nullptr,
618-
PointerUnion<DIExpression *, DIVariable *> Rank = nullptr);
619+
PointerUnion<DIExpression *, DIVariable *> Rank = nullptr,
620+
Metadata *BitStride = nullptr);
619621

620622
/// Create debugging information entry for a vector type.
621623
/// \param Size Array size.

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,15 +1302,15 @@ class DICompositeType : public DIType {
13021302
DIType *VTableHolder, DITemplateParameterArray TemplateParams,
13031303
StringRef Identifier, DIDerivedType *Discriminator,
13041304
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
1305-
Metadata *Rank, DINodeArray Annotations, StorageType Storage,
1306-
bool ShouldCreate = true) {
1307-
return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
1308-
Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
1309-
Flags, Elements.get(), RuntimeLang, EnumKind, VTableHolder,
1310-
TemplateParams.get(),
1311-
getCanonicalMDString(Context, Identifier), Discriminator,
1312-
DataLocation, Associated, Allocated, Rank, Annotations.get(),
1313-
Specification, NumExtraInhabitants, Storage, ShouldCreate);
1305+
Metadata *Rank, DINodeArray Annotations, Metadata *BitStride,
1306+
StorageType Storage, bool ShouldCreate = true) {
1307+
return getImpl(
1308+
Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
1309+
BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
1310+
RuntimeLang, EnumKind, VTableHolder, TemplateParams.get(),
1311+
getCanonicalMDString(Context, Identifier), Discriminator, DataLocation,
1312+
Associated, Allocated, Rank, Annotations.get(), Specification,
1313+
NumExtraInhabitants, BitStride, Storage, ShouldCreate);
13141314
}
13151315
static DICompositeType *
13161316
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
@@ -1322,7 +1322,7 @@ class DICompositeType : public DIType {
13221322
Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
13231323
Metadata *Allocated, Metadata *Rank, Metadata *Annotations,
13241324
Metadata *Specification, uint32_t NumExtraInhabitants,
1325-
StorageType Storage, bool ShouldCreate = true);
1325+
Metadata *BitStride, StorageType Storage, bool ShouldCreate = true);
13261326

13271327
TempDICompositeType cloneImpl() const {
13281328
return getTemporary(
@@ -1332,7 +1332,7 @@ class DICompositeType : public DIType {
13321332
getVTableHolder(), getTemplateParams(), getIdentifier(),
13331333
getDiscriminator(), getRawDataLocation(), getRawAssociated(),
13341334
getRawAllocated(), getRawRank(), getAnnotations(), getSpecification(),
1335-
getNumExtraInhabitants());
1335+
getNumExtraInhabitants(), getRawBitStride());
13361336
}
13371337

13381338
public:
@@ -1348,11 +1348,12 @@ class DICompositeType : public DIType {
13481348
Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
13491349
Metadata *Allocated = nullptr, Metadata *Rank = nullptr,
13501350
DINodeArray Annotations = nullptr, DIType *Specification = nullptr,
1351-
uint32_t NumExtraInhabitants = 0),
1351+
uint32_t NumExtraInhabitants = 0, Metadata *BitStride = nullptr),
13521352
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
13531353
OffsetInBits, Specification, NumExtraInhabitants, Flags, Elements,
13541354
RuntimeLang, EnumKind, VTableHolder, TemplateParams, Identifier,
1355-
Discriminator, DataLocation, Associated, Allocated, Rank, Annotations))
1355+
Discriminator, DataLocation, Associated, Allocated, Rank, Annotations,
1356+
BitStride))
13561357
DEFINE_MDNODE_GET(
13571358
DICompositeType,
13581359
(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
@@ -1364,11 +1365,13 @@ class DICompositeType : public DIType {
13641365
Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
13651366
Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
13661367
Metadata *Rank = nullptr, Metadata *Annotations = nullptr,
1367-
Metadata *Specification = nullptr, uint32_t NumExtraInhabitants = 0),
1368+
Metadata *Specification = nullptr, uint32_t NumExtraInhabitants = 0,
1369+
Metadata *BitStride = nullptr),
13681370
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
13691371
OffsetInBits, Flags, Elements, RuntimeLang, EnumKind, VTableHolder,
13701372
TemplateParams, Identifier, Discriminator, DataLocation, Associated,
1371-
Allocated, Rank, Annotations, Specification, NumExtraInhabitants))
1373+
Allocated, Rank, Annotations, Specification, NumExtraInhabitants,
1374+
BitStride))
13721375

13731376
TempDICompositeType clone() const { return cloneImpl(); }
13741377

@@ -1389,7 +1392,7 @@ class DICompositeType : public DIType {
13891392
Metadata *VTableHolder, Metadata *TemplateParams,
13901393
Metadata *Discriminator, Metadata *DataLocation,
13911394
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
1392-
Metadata *Annotations);
1395+
Metadata *Annotations, Metadata *BitStride);
13931396
static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
13941397
MDString &Identifier);
13951398

@@ -1412,7 +1415,7 @@ class DICompositeType : public DIType {
14121415
Metadata *VTableHolder, Metadata *TemplateParams,
14131416
Metadata *Discriminator, Metadata *DataLocation,
14141417
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
1415-
Metadata *Annotations);
1418+
Metadata *Annotations, Metadata *BitStride);
14161419

14171420
DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
14181421
DINodeArray getElements() const {
@@ -1477,6 +1480,14 @@ class DICompositeType : public DIType {
14771480
DIType *getSpecification() const {
14781481
return cast_or_null<DIType>(getRawSpecification());
14791482
}
1483+
1484+
Metadata *getRawBitStride() const { return getOperand(15); }
1485+
ConstantInt *getBitStrideConst() const {
1486+
if (auto *MD = dyn_cast_or_null<ConstantAsMetadata>(getRawBitStride()))
1487+
return dyn_cast_or_null<ConstantInt>(MD->getValue());
1488+
return nullptr;
1489+
}
1490+
14801491
/// Replace operands.
14811492
///
14821493
/// If this \a isUniqued() and not \a isResolved(), on a uniquing collision

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5612,7 +5612,8 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
56125612
OPTIONAL(rank, MDSignedOrMDField, ); \
56135613
OPTIONAL(annotations, MDField, ); \
56145614
OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX)); \
5615-
OPTIONAL(specification, MDField, );
5615+
OPTIONAL(specification, MDField, ); \
5616+
OPTIONAL(bitStride, MDField, );
56165617
PARSE_MD_FIELDS();
56175618
#undef VISIT_MD_FIELDS
56185619

@@ -5635,7 +5636,8 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
56355636
specification.Val, num_extra_inhabitants.Val, flags.Val,
56365637
elements.Val, runtimeLang.Val, EnumKind, vtableHolder.Val,
56375638
templateParams.Val, discriminator.Val, dataLocation.Val,
5638-
associated.Val, allocated.Val, Rank, annotations.Val)) {
5639+
associated.Val, allocated.Val, Rank, annotations.Val,
5640+
bitStride.Val)) {
56395641
Result = CT;
56405642
return false;
56415643
}
@@ -5649,7 +5651,7 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
56495651
runtimeLang.Val, EnumKind, vtableHolder.Val, templateParams.Val,
56505652
identifier.Val, discriminator.Val, dataLocation.Val, associated.Val,
56515653
allocated.Val, Rank, annotations.Val, specification.Val,
5652-
num_extra_inhabitants.Val));
5654+
num_extra_inhabitants.Val, bitStride.Val));
56535655
return false;
56545656
}
56555657

llvm/lib/Bitcode/Reader/MetadataLoader.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,7 +1618,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
16181618
break;
16191619
}
16201620
case bitc::METADATA_COMPOSITE_TYPE: {
1621-
if (Record.size() < 16 || Record.size() > 25)
1621+
if (Record.size() < 16 || Record.size() > 26)
16221622
return error("Invalid record");
16231623

16241624
// If we have a UUID and this is not a forward declaration, lookup the
@@ -1651,6 +1651,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
16511651
Metadata *Rank = nullptr;
16521652
Metadata *Annotations = nullptr;
16531653
Metadata *Specification = nullptr;
1654+
Metadata *BitStride = nullptr;
16541655
auto *Identifier = getMDString(Record[15]);
16551656
// If this module is being parsed so that it can be ThinLTO imported
16561657
// into another module, composite types only need to be imported as
@@ -1702,10 +1703,13 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
17021703
if (Record.size() > 23) {
17031704
Specification = getMDOrNull(Record[23]);
17041705
}
1706+
// FIXME
1707+
if (Record.size() > 25)
1708+
BitStride = getMDOrNull(Record[25]);
17051709
}
17061710

1707-
if (Record.size() > 25 && Record[25] != dwarf::DW_APPLE_ENUM_KIND_invalid)
1708-
EnumKind = Record[25];
1711+
if (Record.size() > 24 && Record[24] != dwarf::DW_APPLE_ENUM_KIND_invalid)
1712+
EnumKind = Record[24];
17091713

17101714
DICompositeType *CT = nullptr;
17111715
if (Identifier)
@@ -1714,17 +1718,17 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
17141718
SizeInBits, AlignInBits, OffsetInBits, Specification,
17151719
NumExtraInhabitants, Flags, Elements, RuntimeLang, EnumKind,
17161720
VTableHolder, TemplateParams, Discriminator, DataLocation, Associated,
1717-
Allocated, Rank, Annotations);
1721+
Allocated, Rank, Annotations, BitStride);
17181722

17191723
// Create a node if we didn't get a lazy ODR type.
17201724
if (!CT)
1721-
CT = GET_OR_DISTINCT(DICompositeType,
1722-
(Context, Tag, Name, File, Line, Scope, BaseType,
1723-
SizeInBits, AlignInBits, OffsetInBits, Flags,
1724-
Elements, RuntimeLang, EnumKind, VTableHolder,
1725-
TemplateParams, Identifier, Discriminator,
1726-
DataLocation, Associated, Allocated, Rank,
1727-
Annotations, Specification, NumExtraInhabitants));
1725+
CT = GET_OR_DISTINCT(
1726+
DICompositeType,
1727+
(Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
1728+
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, EnumKind,
1729+
VTableHolder, TemplateParams, Identifier, Discriminator,
1730+
DataLocation, Associated, Allocated, Rank, Annotations,
1731+
Specification, NumExtraInhabitants, BitStride));
17281732
if (!IsNotUsedInTypeRef && Identifier)
17291733
MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));
17301734

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,6 +1990,7 @@ void ModuleBitcodeWriter::writeDICompositeType(
19901990
Record.push_back(VE.getMetadataOrNullID(N->getRawSpecification()));
19911991
Record.push_back(
19921992
N->getEnumKind().value_or(dwarf::DW_APPLE_ENUM_KIND_invalid));
1993+
Record.push_back(VE.getMetadataOrNullID(N->getRawBitStride()));
19931994

19941995
Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev);
19951996
Record.clear();

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,6 +1663,10 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
16631663
addBlock(Buffer, dwarf::DW_AT_rank, DwarfExpr.finalize());
16641664
}
16651665

1666+
if (auto *BitStride = CTy->getBitStrideConst()) {
1667+
addUInt(Buffer, dwarf::DW_AT_bit_stride, {}, BitStride->getZExtValue());
1668+
}
1669+
16661670
// Emit the element type.
16671671
addType(Buffer, CTy->getBaseType());
16681672

llvm/lib/IR/AsmWriter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2308,6 +2308,7 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
23082308
Printer.printDwarfEnum("enumKind", *EnumKind, dwarf::EnumKindString,
23092309
/*ShouldSkipZero=*/false);
23102310

2311+
Printer.printMetadata("bitStride", N->getRawBitStride());
23112312
Out << ")";
23122313
}
23132314

llvm/lib/IR/DIBuilder.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ DICompositeType *DIBuilder::createArrayType(
611611
PointerUnion<DIExpression *, DIVariable *> DL,
612612
PointerUnion<DIExpression *, DIVariable *> AS,
613613
PointerUnion<DIExpression *, DIVariable *> AL,
614-
PointerUnion<DIExpression *, DIVariable *> RK) {
614+
PointerUnion<DIExpression *, DIVariable *> RK, Metadata *BitStride) {
615615
auto *R = DICompositeType::get(
616616
VMContext, dwarf::DW_TAG_array_type, Name, File, LineNumber,
617617
getNonCompileUnitScope(Scope), Ty, Size, AlignInBits, 0, DINode::FlagZero,
@@ -623,7 +623,8 @@ DICompositeType *DIBuilder::createArrayType(
623623
isa<DIExpression *>(AL) ? (Metadata *)cast<DIExpression *>(AL)
624624
: (Metadata *)cast<DIVariable *>(AL),
625625
isa<DIExpression *>(RK) ? (Metadata *)cast<DIExpression *>(RK)
626-
: (Metadata *)cast<DIVariable *>(RK));
626+
: (Metadata *)cast<DIVariable *>(RK),
627+
nullptr, nullptr, 0, BitStride);
627628
trackIfUnresolved(R);
628629
return R;
629630
}

llvm/lib/IR/DebugInfoMetadata.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -813,8 +813,8 @@ DICompositeType *DICompositeType::getImpl(
813813
Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier,
814814
Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
815815
Metadata *Allocated, Metadata *Rank, Metadata *Annotations,
816-
Metadata *Specification, uint32_t NumExtraInhabitants, StorageType Storage,
817-
bool ShouldCreate) {
816+
Metadata *Specification, uint32_t NumExtraInhabitants, Metadata *BitStride,
817+
StorageType Storage, bool ShouldCreate) {
818818
assert(isCanonical(Name) && "Expected canonical MDString");
819819

820820
// Keep this in sync with buildODRType.
@@ -823,11 +823,11 @@ DICompositeType *DICompositeType::getImpl(
823823
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
824824
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
825825
Identifier, Discriminator, DataLocation, Associated, Allocated, Rank,
826-
Annotations, Specification, NumExtraInhabitants));
826+
Annotations, Specification, NumExtraInhabitants, BitStride));
827827
Metadata *Ops[] = {File, Scope, Name, BaseType,
828828
Elements, VTableHolder, TemplateParams, Identifier,
829829
Discriminator, DataLocation, Associated, Allocated,
830-
Rank, Annotations, Specification};
830+
Rank, Annotations, Specification, BitStride};
831831
DEFINE_GETIMPL_STORE(DICompositeType,
832832
(Tag, Line, RuntimeLang, SizeInBits, AlignInBits,
833833
OffsetInBits, NumExtraInhabitants, EnumKind, Flags),
@@ -842,7 +842,7 @@ DICompositeType *DICompositeType::buildODRType(
842842
Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
843843
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
844844
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
845-
Metadata *Rank, Metadata *Annotations) {
845+
Metadata *Rank, Metadata *Annotations, Metadata *BitStride) {
846846
assert(!Identifier.getString().empty() && "Expected valid identifier");
847847
if (!Context.isODRUniquingDebugTypes())
848848
return nullptr;
@@ -853,7 +853,7 @@ DICompositeType *DICompositeType::buildODRType(
853853
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
854854
EnumKind, VTableHolder, TemplateParams, &Identifier,
855855
Discriminator, DataLocation, Associated, Allocated, Rank,
856-
Annotations, Specification, NumExtraInhabitants);
856+
Annotations, Specification, NumExtraInhabitants, BitStride);
857857
if (CT->getTag() != Tag)
858858
return nullptr;
859859

@@ -868,7 +868,7 @@ DICompositeType *DICompositeType::buildODRType(
868868
Metadata *Ops[] = {File, Scope, Name, BaseType,
869869
Elements, VTableHolder, TemplateParams, &Identifier,
870870
Discriminator, DataLocation, Associated, Allocated,
871-
Rank, Annotations, Specification};
871+
Rank, Annotations, Specification, BitStride};
872872
assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&
873873
"Mismatched number of operands");
874874
for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)
@@ -885,7 +885,7 @@ DICompositeType *DICompositeType::getODRType(
885885
Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
886886
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
887887
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
888-
Metadata *Rank, Metadata *Annotations) {
888+
Metadata *Rank, Metadata *Annotations, Metadata *BitStride) {
889889
assert(!Identifier.getString().empty() && "Expected valid identifier");
890890
if (!Context.isODRUniquingDebugTypes())
891891
return nullptr;
@@ -896,7 +896,7 @@ DICompositeType *DICompositeType::getODRType(
896896
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, EnumKind,
897897
VTableHolder, TemplateParams, &Identifier, Discriminator, DataLocation,
898898
Associated, Allocated, Rank, Annotations, Specification,
899-
NumExtraInhabitants);
899+
NumExtraInhabitants, BitStride);
900900
} else {
901901
if (CT->getTag() != Tag)
902902
return nullptr;

0 commit comments

Comments
 (0)