Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit e69c459

Browse files
author
Victor Leschuk
committed
DebugInfo: preparation to implement DW_AT_alignment
- Add alignment attribute to DIVariable family - Modify bitcode format to match new DIVariable representation - Update tests to match these changes (also add bitcode upgrade test) - Expect that frontend passes non-zero align value only when it is not default (was forcibly aligned by alignas()/_Alignas()/__atribute__(aligned()) Differential Revision: https://reviews.llvm.org/D25073 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@284678 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 1c2f240 commit e69c459

22 files changed

+329
-188
lines changed

include/llvm/IR/DIBuilder.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,9 @@ namespace llvm {
120120
/// type.
121121
/// \param Name Type name.
122122
/// \param SizeInBits Size of the type.
123-
/// \param AlignInBits Type alignment.
124123
/// \param Encoding DWARF encoding code, e.g. dwarf::DW_ATE_float.
125124
DIBasicType *createBasicType(StringRef Name, uint64_t SizeInBits,
126-
uint32_t AlignInBits, unsigned Encoding);
125+
unsigned Encoding);
127126

128127
/// Create debugging information entry for a qualified
129128
/// type, e.g. 'const int'.
@@ -209,7 +208,7 @@ namespace llvm {
209208
/// \param Ty Parent type.
210209
DIDerivedType *createBitFieldMemberType(
211210
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo,
212-
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
211+
uint64_t SizeInBits, uint64_t OffsetInBits,
213212
uint64_t StorageOffsetInBits, DINode::DIFlags Flags, DIType *Ty);
214213

215214
/// Create debugging information entry for a
@@ -221,10 +220,12 @@ namespace llvm {
221220
/// \param Ty Type of the static member.
222221
/// \param Flags Flags to encode member attribute, e.g. private.
223222
/// \param Val Const initializer of the member.
223+
/// \param AlignInBits Member alignment.
224224
DIDerivedType *createStaticMemberType(DIScope *Scope, StringRef Name,
225225
DIFile *File, unsigned LineNo,
226226
DIType *Ty, DINode::DIFlags Flags,
227-
llvm::Constant *Val);
227+
llvm::Constant *Val,
228+
uint32_t AlignInBits = 0);
228229

229230
/// Create debugging information entry for Objective-C
230231
/// instance variable.
@@ -458,19 +459,22 @@ namespace llvm {
458459
/// \param Expr The location of the global relative to the attached
459460
/// GlobalVariable.
460461
/// \param Decl Reference to the corresponding declaration.
462+
/// \param AlignInBits Variable alignment(or 0 if no alignment attr was
463+
/// specified)
461464
DIGlobalVariable *createGlobalVariable(DIScope *Context, StringRef Name,
462465
StringRef LinkageName, DIFile *File,
463466
unsigned LineNo, DIType *Ty,
464467
bool isLocalToUnit,
465468
DIExpression *Expr = nullptr,
466-
MDNode *Decl = nullptr);
469+
MDNode *Decl = nullptr,
470+
uint32_t AlignInBits = 0);
467471

468472
/// Identical to createGlobalVariable
469473
/// except that the resulting DbgNode is temporary and meant to be RAUWed.
470474
DIGlobalVariable *createTempGlobalVariableFwdDecl(
471475
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
472476
unsigned LineNo, DIType *Ty, bool isLocalToUnit, DIExpression *Expr,
473-
MDNode *Decl = nullptr);
477+
MDNode *Decl = nullptr, uint32_t AlignInBits = 0);
474478

475479
/// Create a new descriptor for an auto variable. This is a local variable
476480
/// that is not a subprogram parameter.
@@ -483,7 +487,8 @@ namespace llvm {
483487
DILocalVariable *
484488
createAutoVariable(DIScope *Scope, StringRef Name, DIFile *File,
485489
unsigned LineNo, DIType *Ty, bool AlwaysPreserve = false,
486-
DINode::DIFlags Flags = DINode::FlagZero);
490+
DINode::DIFlags Flags = DINode::FlagZero,
491+
uint32_t AlignInBits = 0);
487492

488493
/// Create a new descriptor for a parameter variable.
489494
///

include/llvm/IR/DebugInfoMetadata.h

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,8 @@ class DIType : public DIScope {
549549

550550
unsigned getLine() const { return Line; }
551551
uint64_t getSizeInBits() const { return SizeInBits; }
552-
uint64_t getAlignInBits() const { return AlignInBits; }
552+
uint32_t getAlignInBits() const { return AlignInBits; }
553+
uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
553554
uint64_t getOffsetInBits() const { return OffsetInBits; }
554555
DIFlags getFlags() const { return Flags; }
555556

@@ -1826,11 +1827,13 @@ class DITemplateValueParameter : public DITemplateParameter {
18261827
/// \brief Base class for variables.
18271828
class DIVariable : public DINode {
18281829
unsigned Line;
1830+
uint64_t AlignInBits;
18291831

18301832
protected:
18311833
DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Line,
1832-
ArrayRef<Metadata *> Ops)
1833-
: DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line) {}
1834+
ArrayRef<Metadata *> Ops, uint64_t AlignInBits = 0)
1835+
: DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line),
1836+
AlignInBits(AlignInBits) {}
18341837
~DIVariable() = default;
18351838

18361839
public:
@@ -1839,6 +1842,8 @@ class DIVariable : public DINode {
18391842
StringRef getName() const { return getStringOperand(1); }
18401843
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
18411844
DITypeRef getType() const { return DITypeRef(getRawType()); }
1845+
uint64_t getAlignInBits() const { return AlignInBits; }
1846+
uint64_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
18421847

18431848
StringRef getFilename() const {
18441849
if (auto *F = getFile())
@@ -2026,52 +2031,58 @@ class DIGlobalVariable : public DIVariable {
20262031
bool IsDefinition;
20272032

20282033
DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
2029-
bool IsLocalToUnit, bool IsDefinition,
2034+
bool IsLocalToUnit, bool IsDefinition, uint64_t AlignInBits,
20302035
ArrayRef<Metadata *> Ops)
2031-
: DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops),
2036+
: DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits),
20322037
IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
20332038
~DIGlobalVariable() = default;
20342039

20352040
static DIGlobalVariable *
20362041
getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
20372042
StringRef LinkageName, DIFile *File, unsigned Line, DITypeRef Type,
20382043
bool IsLocalToUnit, bool IsDefinition, DIExpression *Expr,
2039-
DIDerivedType *StaticDataMemberDeclaration, StorageType Storage,
2040-
bool ShouldCreate = true) {
2044+
DIDerivedType *StaticDataMemberDeclaration, uint64_t AlignInBits,
2045+
StorageType Storage, bool ShouldCreate = true) {
20412046
return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
20422047
getCanonicalMDString(Context, LinkageName), File, Line, Type,
20432048
IsLocalToUnit, IsDefinition, Expr,
2044-
StaticDataMemberDeclaration, Storage, ShouldCreate);
2049+
StaticDataMemberDeclaration, AlignInBits, Storage,
2050+
ShouldCreate);
20452051
}
20462052
static DIGlobalVariable *
20472053
getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
20482054
MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
20492055
bool IsLocalToUnit, bool IsDefinition, Metadata *Expr,
2050-
Metadata *StaticDataMemberDeclaration, StorageType Storage,
2051-
bool ShouldCreate = true);
2056+
Metadata *StaticDataMemberDeclaration, uint64_t AlignInBits,
2057+
StorageType Storage, bool ShouldCreate = true);
20522058

20532059
TempDIGlobalVariable cloneImpl() const {
20542060
return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
20552061
getFile(), getLine(), getType(), isLocalToUnit(),
20562062
isDefinition(), getExpr(),
2057-
getStaticDataMemberDeclaration());
2063+
getStaticDataMemberDeclaration(), getAlignInBits());
20582064
}
20592065

20602066
public:
20612067
DEFINE_MDNODE_GET(DIGlobalVariable,
20622068
(DIScope * Scope, StringRef Name, StringRef LinkageName,
20632069
DIFile *File, unsigned Line, DITypeRef Type,
2064-
bool IsLocalToUnit, bool IsDefinition, DIExpression *Expr,
2065-
DIDerivedType *StaticDataMemberDeclaration),
2070+
bool IsLocalToUnit, bool IsDefinition,
2071+
DIExpression *Expr,
2072+
DIDerivedType *StaticDataMemberDeclaration,
2073+
uint64_t AlignInBits),
20662074
(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
2067-
IsDefinition, Expr, StaticDataMemberDeclaration))
2075+
IsDefinition, Expr, StaticDataMemberDeclaration,
2076+
AlignInBits))
20682077
DEFINE_MDNODE_GET(DIGlobalVariable,
20692078
(Metadata * Scope, MDString *Name, MDString *LinkageName,
20702079
Metadata *File, unsigned Line, Metadata *Type,
2071-
bool IsLocalToUnit, bool IsDefinition, Metadata *Expr,
2072-
Metadata *StaticDataMemberDeclaration),
2080+
bool IsLocalToUnit, bool IsDefinition,
2081+
Metadata *Expr, Metadata *StaticDataMemberDeclaration,
2082+
uint64_t AlignInBits),
20732083
(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
2074-
IsDefinition, Expr, StaticDataMemberDeclaration))
2084+
IsDefinition, Expr, StaticDataMemberDeclaration,
2085+
AlignInBits))
20752086

20762087
TempDIGlobalVariable clone() const { return cloneImpl(); }
20772088

@@ -2109,43 +2120,45 @@ class DILocalVariable : public DIVariable {
21092120
DIFlags Flags;
21102121

21112122
DILocalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
2112-
unsigned Arg, DIFlags Flags, ArrayRef<Metadata *> Ops)
2113-
: DIVariable(C, DILocalVariableKind, Storage, Line, Ops), Arg(Arg),
2114-
Flags(Flags) {
2123+
unsigned Arg, DIFlags Flags, uint64_t AlignInBits,
2124+
ArrayRef<Metadata *> Ops)
2125+
: DIVariable(C, DILocalVariableKind, Storage, Line, Ops, AlignInBits),
2126+
Arg(Arg), Flags(Flags) {
21152127
assert(Arg < (1 << 16) && "DILocalVariable: Arg out of range");
21162128
}
21172129
~DILocalVariable() = default;
21182130

21192131
static DILocalVariable *getImpl(LLVMContext &Context, DIScope *Scope,
21202132
StringRef Name, DIFile *File, unsigned Line,
21212133
DITypeRef Type, unsigned Arg, DIFlags Flags,
2122-
StorageType Storage,
2134+
uint64_t AlignInBits, StorageType Storage,
21232135
bool ShouldCreate = true) {
21242136
return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File,
2125-
Line, Type, Arg, Flags, Storage, ShouldCreate);
2137+
Line, Type, Arg, Flags, AlignInBits, Storage, ShouldCreate);
21262138
}
21272139
static DILocalVariable *getImpl(LLVMContext &Context, Metadata *Scope,
21282140
MDString *Name, Metadata *File, unsigned Line,
21292141
Metadata *Type, unsigned Arg, DIFlags Flags,
2130-
StorageType Storage,
2142+
uint64_t AlignInBits, StorageType Storage,
21312143
bool ShouldCreate = true);
21322144

21332145
TempDILocalVariable cloneImpl() const {
21342146
return getTemporary(getContext(), getScope(), getName(), getFile(),
2135-
getLine(), getType(), getArg(), getFlags());
2147+
getLine(), getType(), getArg(), getFlags(),
2148+
getAlignInBits());
21362149
}
21372150

21382151
public:
21392152
DEFINE_MDNODE_GET(DILocalVariable,
21402153
(DILocalScope * Scope, StringRef Name, DIFile *File,
21412154
unsigned Line, DITypeRef Type, unsigned Arg,
2142-
DIFlags Flags),
2143-
(Scope, Name, File, Line, Type, Arg, Flags))
2155+
DIFlags Flags, uint64_t AlignInBits),
2156+
(Scope, Name, File, Line, Type, Arg, Flags, AlignInBits))
21442157
DEFINE_MDNODE_GET(DILocalVariable,
21452158
(Metadata * Scope, MDString *Name, Metadata *File,
21462159
unsigned Line, Metadata *Type, unsigned Arg,
2147-
DIFlags Flags),
2148-
(Scope, Name, File, Line, Type, Arg, Flags))
2160+
DIFlags Flags, uint64_t AlignInBits),
2161+
(Scope, Name, File, Line, Type, Arg, Flags, AlignInBits))
21492162

21502163
TempDILocalVariable clone() const { return cloneImpl(); }
21512164

lib/AsmParser/LLParser.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4186,7 +4186,7 @@ bool LLParser::ParseDITemplateValueParameter(MDNode *&Result, bool IsDistinct) {
41864186
/// ::= !DIGlobalVariable(scope: !0, name: "foo", linkageName: "foo",
41874187
/// file: !1, line: 7, type: !2, isLocal: false,
41884188
/// isDefinition: true, variable: i32* @foo,
4189-
/// declaration: !3)
4189+
/// declaration: !3, align: 8)
41904190
bool LLParser::ParseDIGlobalVariable(MDNode *&Result, bool IsDistinct) {
41914191
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
41924192
REQUIRED(name, MDStringField, (/* AllowEmpty */ false)); \
@@ -4198,22 +4198,26 @@ bool LLParser::ParseDIGlobalVariable(MDNode *&Result, bool IsDistinct) {
41984198
OPTIONAL(isLocal, MDBoolField, ); \
41994199
OPTIONAL(isDefinition, MDBoolField, (true)); \
42004200
OPTIONAL(expr, MDField, ); \
4201-
OPTIONAL(declaration, MDField, );
4201+
OPTIONAL(declaration, MDField, ); \
4202+
OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));
42024203
PARSE_MD_FIELDS();
42034204
#undef VISIT_MD_FIELDS
42044205

42054206
Result = GET_OR_DISTINCT(DIGlobalVariable,
42064207
(Context, scope.Val, name.Val, linkageName.Val,
42074208
file.Val, line.Val, type.Val, isLocal.Val,
4208-
isDefinition.Val, expr.Val, declaration.Val));
4209+
isDefinition.Val, expr.Val, declaration.Val,
4210+
align.Val));
42094211
return false;
42104212
}
42114213

42124214
/// ParseDILocalVariable:
42134215
/// ::= !DILocalVariable(arg: 7, scope: !0, name: "foo",
4214-
/// file: !1, line: 7, type: !2, arg: 2, flags: 7)
4216+
/// file: !1, line: 7, type: !2, arg: 2, flags: 7,
4217+
/// align: 8)
42154218
/// ::= !DILocalVariable(scope: !0, name: "foo",
4216-
/// file: !1, line: 7, type: !2, arg: 2, flags: 7)
4219+
/// file: !1, line: 7, type: !2, arg: 2, flags: 7,
4220+
/// align: 8)
42174221
bool LLParser::ParseDILocalVariable(MDNode *&Result, bool IsDistinct) {
42184222
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
42194223
REQUIRED(scope, MDField, (/* AllowNull */ false)); \
@@ -4222,13 +4226,14 @@ bool LLParser::ParseDILocalVariable(MDNode *&Result, bool IsDistinct) {
42224226
OPTIONAL(file, MDField, ); \
42234227
OPTIONAL(line, LineField, ); \
42244228
OPTIONAL(type, MDField, ); \
4225-
OPTIONAL(flags, DIFlagField, );
4229+
OPTIONAL(flags, DIFlagField, ); \
4230+
OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));
42264231
PARSE_MD_FIELDS();
42274232
#undef VISIT_MD_FIELDS
42284233

42294234
Result = GET_OR_DISTINCT(DILocalVariable,
42304235
(Context, scope.Val, name.Val, file.Val, line.Val,
4231-
type.Val, arg.Val, flags.Val));
4236+
type.Val, arg.Val, flags.Val, align.Val));
42324237
return false;
42334238
}
42344239

lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2734,14 +2734,15 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
27342734
break;
27352735
}
27362736
case bitc::METADATA_GLOBAL_VAR: {
2737-
if (Record.size() != 11)
2737+
if (Record.size() < 11 || Record.size() > 12)
27382738
return error("Invalid record");
27392739

27402740
IsDistinct = Record[0];
27412741

27422742
// Upgrade old metadata, which stored a global variable reference or a
27432743
// ConstantInt here.
27442744
Metadata *Expr = getMDOrNull(Record[9]);
2745+
uint64_t AlignInBits = (Record.size() > 11) ? Record[11] : 0;
27452746
GlobalVariable *Attach = nullptr;
27462747
if (auto *CMD = dyn_cast_or_null<ConstantAsMetadata>(Expr)) {
27472748
if (auto *GV = dyn_cast<GlobalVariable>(CMD->getValue())) {
@@ -2761,7 +2762,7 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
27612762
(Context, getMDOrNull(Record[1]), getMDString(Record[2]),
27622763
getMDString(Record[3]), getMDOrNull(Record[4]), Record[5],
27632764
getDITypeRefOrNull(Record[6]), Record[7], Record[8], Expr,
2764-
getMDOrNull(Record[10])));
2765+
getMDOrNull(Record[10]), AlignInBits));
27652766
MetadataList.assignValue(DGV, NextMetadataNo++);
27662767

27672768
if (Attach)
@@ -2774,18 +2775,21 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
27742775
if (Record.size() < 8 || Record.size() > 10)
27752776
return error("Invalid record");
27762777

2778+
IsDistinct = Record[0] & 1;
2779+
bool HasAlignment = Record[0] & 2;
27772780
// 2nd field used to be an artificial tag, either DW_TAG_auto_variable or
2778-
// DW_TAG_arg_variable.
2779-
IsDistinct = Record[0];
2780-
bool HasTag = Record.size() > 8;
2781+
// DW_TAG_arg_variable, if we have alignment flag encoded it means, that
2782+
// this is newer version of record which doesn't have artifical tag.
2783+
bool HasTag = !HasAlignment && Record.size() > 8;
27812784
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[7 + HasTag]);
2785+
uint64_t AlignInBits = HasAlignment ? Record[8 + HasTag] : 0;
27822786
MetadataList.assignValue(
27832787
GET_OR_DISTINCT(DILocalVariable,
27842788
(Context, getMDOrNull(Record[1 + HasTag]),
27852789
getMDString(Record[2 + HasTag]),
27862790
getMDOrNull(Record[3 + HasTag]), Record[4 + HasTag],
27872791
getDITypeRefOrNull(Record[5 + HasTag]),
2788-
Record[6 + HasTag], Flags)),
2792+
Record[6 + HasTag], Flags, AlignInBits)),
27892793
NextMetadataNo++);
27902794
break;
27912795
}

lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1712,6 +1712,7 @@ void ModuleBitcodeWriter::writeDIGlobalVariable(
17121712
Record.push_back(N->isDefinition());
17131713
Record.push_back(VE.getMetadataOrNullID(N->getRawExpr()));
17141714
Record.push_back(VE.getMetadataOrNullID(N->getStaticDataMemberDeclaration()));
1715+
Record.push_back(N->getAlignInBits());
17151716

17161717
Stream.EmitRecord(bitc::METADATA_GLOBAL_VAR, Record, Abbrev);
17171718
Record.clear();
@@ -1720,14 +1721,29 @@ void ModuleBitcodeWriter::writeDIGlobalVariable(
17201721
void ModuleBitcodeWriter::writeDILocalVariable(
17211722
const DILocalVariable *N, SmallVectorImpl<uint64_t> &Record,
17221723
unsigned Abbrev) {
1723-
Record.push_back(N->isDistinct());
1724+
// In order to support all possible bitcode formats in BitcodeReader we need
1725+
// to distiguish the following cases:
1726+
// 1) Record has no artificial tag (Record[1]),
1727+
// has no obsolete inlinedAt field (Record[9]).
1728+
// In this case Record size will be 8, HasAlignment flag is false.
1729+
// 2) Record has artificial tag (Record[1]),
1730+
// has no obsolete inlignedAt field (Record[9]).
1731+
// In this case Record size will be 9, HasAlignment flag is false.
1732+
// 3) Record has both artificial tag (Record[1]) and
1733+
// obsolete inlignedAt field (Record[9]).
1734+
// In this case Record size will be 10, HasAlignment flag is false.
1735+
// 4) Record has neither artificial tag, nor inlignedAt field, but
1736+
// HasAlignment flag is true and Record[8] contains alignment value.
1737+
const uint64_t HasAlignmentFlag = 1 << 1;
1738+
Record.push_back(N->isDistinct() | HasAlignmentFlag);
17241739
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
17251740
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
17261741
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
17271742
Record.push_back(N->getLine());
17281743
Record.push_back(VE.getMetadataOrNullID(N->getType()));
17291744
Record.push_back(N->getArg());
17301745
Record.push_back(N->getFlags());
1746+
Record.push_back(N->getAlignInBits());
17311747

17321748
Stream.EmitRecord(bitc::METADATA_LOCAL_VAR, Record, Abbrev);
17331749
Record.clear();

0 commit comments

Comments
 (0)