Skip to content

Commit f89129a

Browse files
authored
Add bit stride to DICompositeType (#131680)
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.
1 parent 584b24c commit f89129a

File tree

14 files changed

+146
-63
lines changed

14 files changed

+146
-63
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
@@ -5613,7 +5613,8 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
56135613
OPTIONAL(rank, MDSignedOrMDField, ); \
56145614
OPTIONAL(annotations, MDField, ); \
56155615
OPTIONAL(num_extra_inhabitants, MDUnsignedField, (0, UINT32_MAX)); \
5616-
OPTIONAL(specification, MDField, );
5616+
OPTIONAL(specification, MDField, ); \
5617+
OPTIONAL(bitStride, MDField, );
56175618
PARSE_MD_FIELDS();
56185619
#undef VISIT_MD_FIELDS
56195620

@@ -5636,7 +5637,8 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
56365637
specification.Val, num_extra_inhabitants.Val, flags.Val,
56375638
elements.Val, runtimeLang.Val, EnumKind, vtableHolder.Val,
56385639
templateParams.Val, discriminator.Val, dataLocation.Val,
5639-
associated.Val, allocated.Val, Rank, annotations.Val)) {
5640+
associated.Val, allocated.Val, Rank, annotations.Val,
5641+
bitStride.Val)) {
56405642
Result = CT;
56415643
return false;
56425644
}
@@ -5650,7 +5652,7 @@ bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) {
56505652
runtimeLang.Val, EnumKind, vtableHolder.Val, templateParams.Val,
56515653
identifier.Val, discriminator.Val, dataLocation.Val, associated.Val,
56525654
allocated.Val, Rank, annotations.Val, specification.Val,
5653-
num_extra_inhabitants.Val));
5655+
num_extra_inhabitants.Val, bitStride.Val));
56545656
return false;
56555657
}
56565658

llvm/lib/Bitcode/Reader/MetadataLoader.cpp

Lines changed: 12 additions & 9 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,6 +1703,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
17021703
if (Record.size() > 23) {
17031704
Specification = getMDOrNull(Record[23]);
17041705
}
1706+
if (Record.size() > 25)
1707+
BitStride = getMDOrNull(Record[25]);
17051708
}
17061709

17071710
if (Record.size() > 24 && Record[24] != dwarf::DW_APPLE_ENUM_KIND_invalid)
@@ -1714,17 +1717,17 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
17141717
SizeInBits, AlignInBits, OffsetInBits, Specification,
17151718
NumExtraInhabitants, Flags, Elements, RuntimeLang, EnumKind,
17161719
VTableHolder, TemplateParams, Discriminator, DataLocation, Associated,
1717-
Allocated, Rank, Annotations);
1720+
Allocated, Rank, Annotations, BitStride);
17181721

17191722
// Create a node if we didn't get a lazy ODR type.
17201723
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));
1724+
CT = GET_OR_DISTINCT(
1725+
DICompositeType,
1726+
(Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
1727+
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, EnumKind,
1728+
VTableHolder, TemplateParams, Identifier, Discriminator,
1729+
DataLocation, Associated, Allocated, Rank, Annotations,
1730+
Specification, NumExtraInhabitants, BitStride));
17281731
if (!IsNotUsedInTypeRef && Identifier)
17291732
MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));
17301733

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)