12
12
include "mlir/Dialect/LLVMIR/LLVMDialect.td"
13
13
include "mlir/IR/AttrTypeBase.td"
14
14
include "mlir/IR/CommonAttrConstraints.td"
15
+ include "mlir/Dialect/LLVMIR/LLVMInterfaces.td"
15
16
16
17
// All of the attributes will extend this class.
17
18
class LLVM_Attr<string name, string attrMnemonic,
@@ -238,41 +239,42 @@ def LoopAnnotationAttr : LLVM_Attr<"LoopAnnotation", "loop_annotation"> {
238
239
//===----------------------------------------------------------------------===//
239
240
240
241
class LLVM_DIParameter<string summary, string default, string parseName,
241
- string printName = parseName>
242
+ string errorCase, string printName = parseName>
242
243
: AttrOrTypeParameter<"unsigned", "debug info " # summary> {
243
244
let parser = [{ [&]() -> FailureOr<unsigned> {
244
245
SMLoc tagLoc = $_parser.getCurrentLocation();
245
246
StringRef name;
246
247
if ($_parser.parseKeyword(&name))
247
248
return failure();
248
249
249
- if (unsigned tag = llvm::dwarf::get}] # parseName # [{(name))
250
- return tag;
251
- return $_parser.emitError(tagLoc)
252
- << "invalid debug info }] # summary # [{ name: " << name;
250
+ unsigned tag = llvm::dwarf::get}] # parseName # [{(name);
251
+ if (tag == }] # errorCase # [{)
252
+ return $_parser.emitError(tagLoc)
253
+ << "invalid debug info }] # summary # [{ name: " << name;
254
+ return tag;
253
255
}() }];
254
256
let printer = "$_printer << llvm::dwarf::" # printName # "String($_self)";
255
257
let defaultValue = default;
256
258
}
257
259
258
260
def LLVM_DICallingConventionParameter : LLVM_DIParameter<
259
- "calling convention", /*default=*/"0", "CallingConvention", "Convention"
261
+ "calling convention", /*default=*/"0", "CallingConvention", "0", " Convention"
260
262
>;
261
263
262
264
def LLVM_DIEncodingParameter : LLVM_DIParameter<
263
- "encoding", /*default=*/"0", "AttributeEncoding"
265
+ "encoding", /*default=*/"0", "AttributeEncoding", "0"
264
266
>;
265
267
266
268
def LLVM_DILanguageParameter : LLVM_DIParameter<
267
- "language", /*default=*/"", "Language"
269
+ "language", /*default=*/"", "Language", "0"
268
270
>;
269
271
270
272
def LLVM_DITagParameter : LLVM_DIParameter<
271
- "tag", /*default=*/"", "Tag"
273
+ "tag", /*default=*/"", "Tag", /*errorCase=*/"llvm::dwarf::DW_TAG_invalid"
272
274
>;
273
275
274
276
def LLVM_DIOperationEncodingParameter : LLVM_DIParameter<
275
- "operation encoding", /*default=*/"", "OperationEncoding"
277
+ "operation encoding", /*default=*/"", "OperationEncoding", "0"
276
278
>;
277
279
278
280
//===----------------------------------------------------------------------===//
@@ -301,70 +303,6 @@ def LLVM_DIExpressionAttr : LLVM_Attr<"DIExpression", "di_expression"> {
301
303
let assemblyFormat = "`<` ( `[` $operations^ `]` ) : (``)? `>`";
302
304
}
303
305
304
- //===----------------------------------------------------------------------===//
305
- // DIRecursiveTypeAttr
306
- //===----------------------------------------------------------------------===//
307
-
308
- def LLVM_DIRecursiveTypeAttr : LLVM_Attr<"DIRecursiveType", "di_recursive_type",
309
- /*traits=*/[], "DITypeAttr"> {
310
- let description = [{
311
- This attribute enables recursive DITypes. There are two modes for this
312
- attribute.
313
-
314
- 1. If `baseType` is present:
315
- - This type is considered a recursive declaration (rec-decl).
316
- - The `baseType` is a self-recursive type identified by the `recId` field.
317
-
318
- 2. If `baseType` is not present:
319
- - This type is considered a recursive self reference (rec-self).
320
- - This DIRecursiveType itself is a placeholder type that should be
321
- conceptually replaced with the closet parent DIRecursiveType with the
322
- same `recId` field.
323
-
324
- e.g. To represent a linked list struct:
325
-
326
- #rec_self = di_recursive_type<recId = 0>
327
- #ptr = di_derived_type<baseType: #rec_self, ...>
328
- #field = di_derived_type<name = "next", baseType: #ptr, ...>
329
- #struct = di_composite_type<name = "Node", elements: #field, ...>
330
- #rec = di_recursive_type<recId = 0, baseType: #struct>
331
-
332
- #var = di_local_variable<type = #struct_type, ...>
333
-
334
- Note that a rec-self without an outer rec-decl with the same recId is
335
- conceptually the same as an "unbound" variable. The context needs to provide
336
- meaning to the rec-self.
337
-
338
- This can be avoided by calling the `getUnfoldedBaseType()` method on a
339
- rec-decl, which returns the `baseType` with all matching rec-self instances
340
- replaced with this rec-decl again. This is useful, for example, for fetching
341
- a field out of a recursive struct and maintaining the legality of the field
342
- type.
343
- }];
344
-
345
- let parameters = (ins
346
- "DistinctAttr":$recId,
347
- OptionalParameter<"DITypeAttr">:$baseType
348
- );
349
-
350
- let builders = [
351
- AttrBuilderWithInferredContext<(ins "DistinctAttr":$recId), [{
352
- return $_get(recId.getContext(), recId, nullptr);
353
- }]>
354
- ];
355
-
356
- let extraClassDeclaration = [{
357
- /// Whether this node represents a self-reference.
358
- bool isRecSelf() { return !getBaseType(); }
359
-
360
- /// Get the `baseType` with all instances of the corresponding rec-self
361
- /// replaced with this attribute. This can only be called if `!isRecSelf()`.
362
- DITypeAttr getUnfoldedBaseType();
363
- }];
364
-
365
- let assemblyFormat = "`<` struct(params) `>`";
366
- }
367
-
368
306
//===----------------------------------------------------------------------===//
369
307
// DINullTypeAttr
370
308
//===----------------------------------------------------------------------===//
@@ -421,9 +359,11 @@ def LLVM_DICompileUnitAttr : LLVM_Attr<"DICompileUnit", "di_compile_unit",
421
359
//===----------------------------------------------------------------------===//
422
360
423
361
def LLVM_DICompositeTypeAttr : LLVM_Attr<"DICompositeType", "di_composite_type",
424
- /*traits=*/[], "DITypeAttr"> {
362
+ [LLVM_DIRecursiveTypeAttrInterface],
363
+ "DITypeAttr"> {
425
364
let parameters = (ins
426
365
LLVM_DITagParameter:$tag,
366
+ OptionalParameter<"DistinctAttr">:$recId,
427
367
OptionalParameter<"StringAttr">:$name,
428
368
OptionalParameter<"DIFileAttr">:$file,
429
369
OptionalParameter<"uint32_t">:$line,
@@ -435,6 +375,21 @@ def LLVM_DICompositeTypeAttr : LLVM_Attr<"DICompositeType", "di_composite_type",
435
375
OptionalArrayRefParameter<"DINodeAttr">:$elements
436
376
);
437
377
let assemblyFormat = "`<` struct(params) `>`";
378
+ let extraClassDeclaration = [{
379
+ /// Requirements of DIRecursiveTypeAttrInterface.
380
+ /// @{
381
+
382
+ /// Get whether this attr describes a recursive self reference.
383
+ bool isRecSelf() { return getTag() == 0; }
384
+
385
+ /// Get a copy of this type attr but with the recursive ID set to `recId`.
386
+ DIRecursiveTypeAttrInterface withRecId(DistinctAttr recId);
387
+
388
+ /// Build a rec-self instance using the provided recId.
389
+ static DIRecursiveTypeAttrInterface getRecSelf(DistinctAttr recId);
390
+
391
+ /// @}
392
+ }];
438
393
}
439
394
440
395
//===----------------------------------------------------------------------===//
@@ -590,15 +545,14 @@ def LLVM_DISubprogramAttr : LLVM_Attr<"DISubprogram", "di_subprogram",
590
545
OptionalParameter<"unsigned">:$line,
591
546
OptionalParameter<"unsigned">:$scopeLine,
592
547
"DISubprogramFlags":$subprogramFlags,
593
- OptionalParameter<"DIRecursiveTypeAttrOf< DISubroutineTypeAttr> ">:$type
548
+ OptionalParameter<"DISubroutineTypeAttr">:$type
594
549
);
595
550
let builders = [
596
551
AttrBuilderWithInferredContext<(ins
597
552
"DistinctAttr":$id, "DICompileUnitAttr":$compileUnit,
598
553
"DIScopeAttr":$scope, "StringRef":$name, "StringRef":$linkageName,
599
554
"DIFileAttr":$file, "unsigned":$line, "unsigned":$scopeLine,
600
- "DISubprogramFlags":$subprogramFlags,
601
- "DIRecursiveTypeAttrOf<DISubroutineTypeAttr>":$type
555
+ "DISubprogramFlags":$subprogramFlags, "DISubroutineTypeAttr":$type
602
556
), [{
603
557
MLIRContext *ctx = file.getContext();
604
558
return $_get(ctx, id, compileUnit, scope, StringAttr::get(ctx, name),
0 commit comments