Skip to content

Commit 3bef1e0

Browse files
committed
[mlir:LLVM] Add attribute/op definitions for debug info
This adds a subset of the necessary metadata for defining debug info in the LLVM dialect. It doesn't import everything, but just enough to start actually generating LLVM debug info the expected way. Export/Import to LLVMIR will be added in a followup. Differential Revision: https://reviews.llvm.org/D136542
1 parent c8496d2 commit 3bef1e0

File tree

8 files changed

+648
-2
lines changed

8 files changed

+648
-2
lines changed

mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td

Lines changed: 281 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@
1212
include "mlir/IR/AttrTypeBase.td"
1313
include "mlir/Dialect/LLVMIR/LLVMEnums.td"
1414
include "mlir/Dialect/LLVMIR/LLVMOpBase.td"
15+
include "mlir/IR/SubElementInterfaces.td"
1516

1617
// All of the attributes will extend this class.
17-
class LLVM_Attr<string name, string attrMnemonic>
18-
: AttrDef<LLVM_Dialect, name, /*traits=*/[]> {
18+
class LLVM_Attr<string name, string attrMnemonic,
19+
list<Trait> traits = [],
20+
string baseCppClass = "::mlir::Attribute">
21+
: AttrDef<LLVM_Dialect, name, traits, baseCppClass> {
1922
let mnemonic = attrMnemonic;
2023
}
2124

@@ -81,4 +84,280 @@ def LoopOptionsAttr : LLVM_Attr<"LoopOptions", "loopopts"> {
8184
let skipDefaultBuilders = 1;
8285
}
8386

87+
//===----------------------------------------------------------------------===//
88+
// DebugInfo Attributes
89+
//===----------------------------------------------------------------------===//
90+
91+
class LLVM_DIParameter<string summary, string underlyingType, string parseName,
92+
string printName = parseName>
93+
: AttrOrTypeParameter<underlyingType, "debug info " # summary> {
94+
let parser = [{ [&]() -> FailureOr<unsigned> {
95+
SMLoc tagLoc = $_parser.getCurrentLocation();
96+
StringRef name;
97+
if ($_parser.parseKeyword(&name))
98+
return failure();
99+
100+
if (unsigned tag = llvm::dwarf::get}] # parseName # [{(name))
101+
return tag;
102+
return $_parser.emitError(tagLoc)
103+
<< "invalid debug info }] # summary # [{ name: " << name;
104+
}() }];
105+
let printer = "$_printer << llvm::dwarf::" # printName # "String($_self)";
106+
}
107+
108+
def LLVM_DICallingConventionParameter : LLVM_DIParameter<
109+
"calling convention", "unsigned", "CallingConvention", "Convention"
110+
>;
111+
112+
def LLVM_DIEncodingParameter : LLVM_DIParameter<
113+
"encoding", "unsigned", "AttributeEncoding"
114+
>;
115+
116+
def LLVM_DILanguageParameter : LLVM_DIParameter<
117+
"language", "unsigned", "Language"
118+
>;
119+
120+
def LLVM_DITagParameter : LLVM_DIParameter<
121+
"tag", "unsigned", "Tag"
122+
>;
123+
124+
//===----------------------------------------------------------------------===//
125+
// DIBasicTypeAttr
126+
//===----------------------------------------------------------------------===//
127+
128+
def LLVM_DIBasicTypeAttr : LLVM_Attr<"DIBasicType", "di_basic_type",
129+
/*traits=*/[], "DITypeAttr"> {
130+
let parameters = (ins
131+
LLVM_DITagParameter:$tag,
132+
"StringAttr":$name,
133+
"uint64_t":$sizeInBits,
134+
LLVM_DIEncodingParameter:$encoding
135+
);
136+
137+
let builders = [
138+
TypeBuilder<(ins
139+
"unsigned":$tag, "const Twine &":$name, "uint64_t":$sizeInBits,
140+
"unsigned":$encoding
141+
), [{
142+
return $_get($_ctxt, tag, StringAttr::get($_ctxt, name), sizeInBits,
143+
encoding);
144+
}]>
145+
];
146+
let assemblyFormat = "`<` struct(params) `>`";
147+
}
148+
149+
//===----------------------------------------------------------------------===//
150+
// DICompileUnitAttr
151+
//===----------------------------------------------------------------------===//
152+
153+
def LLVM_DICompileUnitAttr : LLVM_Attr<"DICompileUnit", "di_compile_unit", [
154+
DeclareAttrInterfaceMethods<SubElementAttrInterface>
155+
], "DIScopeAttr"> {
156+
let parameters = (ins
157+
LLVM_DILanguageParameter:$sourceLanguage,
158+
"DIFileAttr":$file,
159+
"StringAttr":$producer,
160+
"bool":$isOptimized,
161+
"DIEmissionKind":$emissionKind
162+
);
163+
let assemblyFormat = "`<` struct(params) `>`";
164+
}
165+
166+
//===----------------------------------------------------------------------===//
167+
// DICompositeTypeAttr
168+
//===----------------------------------------------------------------------===//
169+
170+
def LLVM_DICompositeTypeAttr : LLVM_Attr<"DICompositeType", "di_composite_type", [
171+
DeclareAttrInterfaceMethods<SubElementAttrInterface>
172+
], "DITypeAttr"> {
173+
let parameters = (ins
174+
LLVM_DITagParameter:$tag,
175+
"StringAttr":$name,
176+
OptionalParameter<"DIFileAttr">:$file,
177+
"uint32_t":$line,
178+
OptionalParameter<"DIScopeAttr">:$scope,
179+
"uint64_t":$sizeInBits,
180+
"uint64_t":$alignInBits,
181+
OptionalArrayRefParameter<"DINodeAttr">:$elements
182+
);
183+
let assemblyFormat = "`<` struct(params) `>`";
184+
}
185+
186+
//===----------------------------------------------------------------------===//
187+
// DIDerivedTypeAttr
188+
//===----------------------------------------------------------------------===//
189+
190+
def LLVM_DIDerivedTypeAttr : LLVM_Attr<"DIDerivedType", "di_derived_type", [
191+
DeclareAttrInterfaceMethods<SubElementAttrInterface>
192+
], "DITypeAttr"> {
193+
let parameters = (ins
194+
LLVM_DITagParameter:$tag,
195+
"StringAttr":$name,
196+
"DITypeAttr":$baseType,
197+
"uint64_t":$sizeInBits,
198+
"uint32_t":$alignInBits,
199+
"uint64_t":$offsetInBits
200+
);
201+
let assemblyFormat = "`<` struct(params) `>`";
202+
}
203+
204+
//===----------------------------------------------------------------------===//
205+
// DIFileAttr
206+
//===----------------------------------------------------------------------===//
207+
208+
def LLVM_DIFileAttr : LLVM_Attr<"DIFile", "di_file", /*traits=*/[], "DIScopeAttr"> {
209+
let parameters = (ins "StringAttr":$name, "StringAttr":$directory);
210+
let builders = [AttrBuilder<(ins "StringRef":$name, "StringRef":$directory), [{
211+
return $_get($_ctxt, StringAttr::get($_ctxt, name),
212+
StringAttr::get($_ctxt, directory));
213+
}]>
214+
];
215+
let assemblyFormat = "`<` $name `in` $directory `>`";
216+
}
217+
218+
//===----------------------------------------------------------------------===//
219+
// DILexicalBlockAttr
220+
//===----------------------------------------------------------------------===//
221+
222+
def LLVM_DILexicalBlockAttr : LLVM_Attr<"DILexicalBlock", "di_lexical_block", [
223+
DeclareAttrInterfaceMethods<SubElementAttrInterface>
224+
], "DIScopeAttr"> {
225+
let parameters = (ins
226+
"DIScopeAttr":$scope,
227+
"DIFileAttr":$file,
228+
"unsigned":$line,
229+
"unsigned":$column
230+
);
231+
let builders = [
232+
AttrBuilderWithInferredContext<(ins
233+
"DIScopeAttr":$scope, "DIFileAttr":$file, "unsigned":$line,
234+
"unsigned":$column
235+
), [{
236+
return $_get(file.getContext(), scope, file, line, column);
237+
}]>
238+
];
239+
let assemblyFormat = "`<` struct(params) `>`";
240+
}
241+
242+
//===----------------------------------------------------------------------===//
243+
// DILexicalBlockFileAttr
244+
//===----------------------------------------------------------------------===//
245+
246+
def LLVM_DILexicalBlockFile : LLVM_Attr<"DILexicalBlockFile", "di_lexical_block_file", [
247+
DeclareAttrInterfaceMethods<SubElementAttrInterface>
248+
], "DIScopeAttr"> {
249+
let parameters = (ins
250+
"DIScopeAttr":$scope,
251+
"DIFileAttr":$file,
252+
"unsigned":$descriminator
253+
);
254+
let builders = [
255+
AttrBuilderWithInferredContext<(ins
256+
"DIScopeAttr":$scope, "DIFileAttr":$file, "unsigned":$descriminator
257+
), [{
258+
return $_get(file.getContext(), scope, file, descriminator);
259+
}]>
260+
];
261+
let assemblyFormat = "`<` struct(params) `>`";
262+
}
263+
264+
//===----------------------------------------------------------------------===//
265+
// DILocalVariableAttr
266+
//===----------------------------------------------------------------------===//
267+
268+
def LLVM_DILocalVariableAttr : LLVM_Attr<"DILocalVariable", "di_local_variable", [
269+
DeclareAttrInterfaceMethods<SubElementAttrInterface>
270+
], "DINodeAttr"> {
271+
let parameters = (ins
272+
"DIScopeAttr":$scope,
273+
"StringAttr":$name,
274+
"DIFileAttr":$file,
275+
"unsigned":$line,
276+
"unsigned":$arg,
277+
"unsigned":$alignInBits,
278+
"DITypeAttr":$type
279+
);
280+
let builders = [
281+
AttrBuilderWithInferredContext<(ins
282+
"DIScopeAttr":$scope, "StringRef":$name, "DIFileAttr":$file,
283+
"unsigned":$line, "unsigned":$arg, "unsigned":$alignInBits,
284+
"DITypeAttr":$type
285+
), [{
286+
MLIRContext *ctx = file.getContext();
287+
return $_get(ctx, scope, StringAttr::get(ctx, name), file, line,
288+
arg, alignInBits, type);
289+
}]>
290+
];
291+
let assemblyFormat = "`<` struct(params) `>`";
292+
}
293+
294+
//===----------------------------------------------------------------------===//
295+
// DISubprogramAttr
296+
//===----------------------------------------------------------------------===//
297+
298+
def LLVM_DISubprogramAttr : LLVM_Attr<"DISubprogram", "di_subprogram", [
299+
DeclareAttrInterfaceMethods<SubElementAttrInterface>
300+
], "DIScopeAttr"> {
301+
let parameters = (ins
302+
"DICompileUnitAttr":$compileUnit,
303+
"DIScopeAttr":$scope,
304+
"StringAttr":$name,
305+
"StringAttr":$linkageName,
306+
"DIFileAttr":$file,
307+
"unsigned":$line,
308+
"unsigned":$scopeLine,
309+
"DISubprogramFlags":$subprogramFlags,
310+
"DISubroutineTypeAttr":$type
311+
);
312+
let builders = [
313+
AttrBuilderWithInferredContext<(ins
314+
"DICompileUnitAttr":$compileUnit, "DIScopeAttr":$scope, "StringRef":$name,
315+
"StringRef":$linkageName, "DIFileAttr":$file, "unsigned":$line,
316+
"unsigned":$scopeLine, "DISubprogramFlags":$subprogramFlags,
317+
"DISubroutineTypeAttr":$type
318+
), [{
319+
MLIRContext *ctx = file.getContext();
320+
return $_get(ctx, compileUnit, scope, StringAttr::get(ctx, name),
321+
StringAttr::get(ctx, linkageName), file, line,
322+
scopeLine, subprogramFlags, type);
323+
}]>
324+
];
325+
326+
let assemblyFormat = "`<` struct(params) `>`";
327+
}
328+
329+
//===----------------------------------------------------------------------===//
330+
// DISubrangeAttr
331+
//===----------------------------------------------------------------------===//
332+
333+
def LLVM_DISubrangeAttr : LLVM_Attr<"DISubrange", "di_subrange", /*traits=*/[],
334+
"DINodeAttr"> {
335+
let parameters = (ins
336+
"IntegerAttr":$count,
337+
"IntegerAttr":$lowerBound,
338+
"IntegerAttr":$upperBound,
339+
"IntegerAttr":$stride
340+
);
341+
let assemblyFormat = "`<` struct(params) `>`";
342+
}
343+
344+
//===----------------------------------------------------------------------===//
345+
// DISubroutineTypeAttr
346+
//===----------------------------------------------------------------------===//
347+
348+
def LLVM_DISubroutineTypeAttr : LLVM_Attr<"DISubroutineType", "di_subroutine_type", [
349+
DeclareAttrInterfaceMethods<SubElementAttrInterface>
350+
], "DITypeAttr"> {
351+
let parameters = (ins
352+
LLVM_DICallingConventionParameter:$callingConvention,
353+
OptionalArrayRefParameter<"DITypeAttr">:$types
354+
);
355+
let builders = [
356+
TypeBuilder<(ins "ArrayRef<DITypeAttr>":$types), [{
357+
return $_get($_ctxt, /*callingConvention=*/0, types);
358+
}]>
359+
];
360+
let assemblyFormat = "`<` struct(params) `>`";
361+
}
362+
84363
#endif // LLVMIR_ATTRDEFS

mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,33 @@ namespace mlir {
2323
namespace LLVM {
2424
class LoopOptionsAttrBuilder;
2525

26+
/// This class represents the base attribute for all debug info attributes.
27+
class DINodeAttr : public Attribute {
28+
public:
29+
using Attribute::Attribute;
30+
31+
// Support LLVM type casting.
32+
static bool classof(Attribute attr);
33+
};
34+
35+
/// This class represents a LLVM attribute that describes a debug info scope.
36+
class DIScopeAttr : public DINodeAttr {
37+
public:
38+
using DINodeAttr::DINodeAttr;
39+
40+
/// Support LLVM type casting.
41+
static bool classof(Attribute attr);
42+
};
43+
44+
/// This class represents a LLVM attribute that describes a debug info type.
45+
class DITypeAttr : public DINodeAttr {
46+
public:
47+
using DINodeAttr::DINodeAttr;
48+
49+
/// Support LLVM type casting.
50+
static bool classof(Attribute attr);
51+
};
52+
2653
// Inline the LLVM generated Linkage enum and utility.
2754
// This is only necessary to isolate the "enum generated code" from the
2855
// attribute definition itself.

mlir/include/mlir/Dialect/LLVMIR/LLVMEnums.td

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,61 @@ def CConv : DialectAttr<
204204
"::mlir::LLVM::CConvAttr::get($_builder.getContext(), $0)";
205205
}
206206

207+
//===----------------------------------------------------------------------===//
208+
// DIEmissionKind
209+
//===----------------------------------------------------------------------===//
210+
211+
def LLVM_DIEmissionNone : I64EnumAttrCase<"None", 0>;
212+
def LLVM_DIEmissionFull : I64EnumAttrCase<"Full", 1>;
213+
def LLVM_DIEmissionLineTablesOnly : I64EnumAttrCase<"LineTablesOnly", 2>;
214+
def LLVM_DIEmissionDebugDirectivesOnly : I64EnumAttrCase<"DebugDirectivesOnly", 3>;
215+
216+
def LLVM_DIEmissionKind : I64EnumAttr<
217+
"DIEmissionKind",
218+
"LLVM debug emission kind", [
219+
LLVM_DIEmissionNone,
220+
LLVM_DIEmissionFull,
221+
LLVM_DIEmissionLineTablesOnly,
222+
LLVM_DIEmissionDebugDirectivesOnly,
223+
]> {
224+
let cppNamespace = "::mlir::LLVM";
225+
}
226+
227+
//===----------------------------------------------------------------------===//
228+
// DISubprogramFlags
229+
//===----------------------------------------------------------------------===//
230+
231+
def LLVM_DISPVirtual : I32BitEnumAttrCaseBit<"Virtual", 0>;
232+
def LLVM_DISPPureVirtual : I32BitEnumAttrCaseBit<"PureVirtual", 1>;
233+
def LLVM_DISPLocalToUnit : I32BitEnumAttrCaseBit<"LocalToUnit", 2>;
234+
def LLVM_DISPDefinition : I32BitEnumAttrCaseBit<"Definition", 3>;
235+
def LLVM_DISPOptimized : I32BitEnumAttrCaseBit<"Optimized", 4>;
236+
def LLVM_DISPPure : I32BitEnumAttrCaseBit<"Pure", 5>;
237+
def LLVM_DISPElemental : I32BitEnumAttrCaseBit<"Elemental", 6>;
238+
def LLVM_DISPRecursive : I32BitEnumAttrCaseBit<"Recursive", 7>;
239+
def LLVM_DISPMainSubprogram : I32BitEnumAttrCaseBit<"MainSubprogram", 8>;
240+
def LLVM_DISPDeleted : I32BitEnumAttrCaseBit<"Deleted", 9>;
241+
def LLVM_DISPObjCDirect : I32BitEnumAttrCaseBit<"ObjCDirect", 11>;
242+
243+
def DISubprogramFlags : I32BitEnumAttr<
244+
"DISubprogramFlags",
245+
"LLVM DISubprogram flags", [
246+
LLVM_DISPVirtual,
247+
LLVM_DISPPureVirtual,
248+
LLVM_DISPLocalToUnit,
249+
LLVM_DISPDefinition,
250+
LLVM_DISPOptimized,
251+
LLVM_DISPPure,
252+
LLVM_DISPElemental,
253+
LLVM_DISPRecursive,
254+
LLVM_DISPMainSubprogram,
255+
LLVM_DISPDeleted,
256+
LLVM_DISPObjCDirect
257+
]> {
258+
let cppNamespace = "::mlir::LLVM";
259+
let printBitEnumPrimaryGroups = 1;
260+
}
261+
207262
//===----------------------------------------------------------------------===//
208263
// FastmathFlags
209264
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)