Skip to content

Commit 1481118

Browse files
committed
Replace dedicated type with interface instead
1 parent 143658c commit 1481118

File tree

11 files changed

+202
-196
lines changed

11 files changed

+202
-196
lines changed

mlir/include/mlir/Dialect/LLVMIR/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ add_mlir_doc(LLVMIntrinsicOps LLVMIntrinsicOps Dialects/ -gen-op-doc)
2929
set(LLVM_TARGET_DEFINITIONS LLVMInterfaces.td)
3030
mlir_tablegen(LLVMInterfaces.h.inc -gen-op-interface-decls)
3131
mlir_tablegen(LLVMInterfaces.cpp.inc -gen-op-interface-defs)
32+
mlir_tablegen(LLVMAttrInterfaces.h.inc -gen-attr-interface-decls)
33+
mlir_tablegen(LLVMAttrInterfaces.cpp.inc -gen-attr-interface-defs)
3234
mlir_tablegen(LLVMTypeInterfaces.h.inc -gen-type-interface-decls)
3335
mlir_tablegen(LLVMTypeInterfaces.cpp.inc -gen-type-interface-defs)
3436
add_public_tablegen_target(MLIRLLVMInterfacesIncGen)

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

Lines changed: 32 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
include "mlir/Dialect/LLVMIR/LLVMDialect.td"
1313
include "mlir/IR/AttrTypeBase.td"
1414
include "mlir/IR/CommonAttrConstraints.td"
15+
include "mlir/Dialect/LLVMIR/LLVMInterfaces.td"
1516

1617
// All of the attributes will extend this class.
1718
class LLVM_Attr<string name, string attrMnemonic,
@@ -238,41 +239,42 @@ def LoopAnnotationAttr : LLVM_Attr<"LoopAnnotation", "loop_annotation"> {
238239
//===----------------------------------------------------------------------===//
239240

240241
class LLVM_DIParameter<string summary, string default, string parseName,
241-
string printName = parseName>
242+
string errorCase, string printName = parseName>
242243
: AttrOrTypeParameter<"unsigned", "debug info " # summary> {
243244
let parser = [{ [&]() -> FailureOr<unsigned> {
244245
SMLoc tagLoc = $_parser.getCurrentLocation();
245246
StringRef name;
246247
if ($_parser.parseKeyword(&name))
247248
return failure();
248249

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;
253255
}() }];
254256
let printer = "$_printer << llvm::dwarf::" # printName # "String($_self)";
255257
let defaultValue = default;
256258
}
257259

258260
def LLVM_DICallingConventionParameter : LLVM_DIParameter<
259-
"calling convention", /*default=*/"0", "CallingConvention", "Convention"
261+
"calling convention", /*default=*/"0", "CallingConvention", "0", "Convention"
260262
>;
261263

262264
def LLVM_DIEncodingParameter : LLVM_DIParameter<
263-
"encoding", /*default=*/"0", "AttributeEncoding"
265+
"encoding", /*default=*/"0", "AttributeEncoding", "0"
264266
>;
265267

266268
def LLVM_DILanguageParameter : LLVM_DIParameter<
267-
"language", /*default=*/"", "Language"
269+
"language", /*default=*/"", "Language", "0"
268270
>;
269271

270272
def LLVM_DITagParameter : LLVM_DIParameter<
271-
"tag", /*default=*/"", "Tag"
273+
"tag", /*default=*/"", "Tag", /*errorCase=*/"llvm::dwarf::DW_TAG_invalid"
272274
>;
273275

274276
def LLVM_DIOperationEncodingParameter : LLVM_DIParameter<
275-
"operation encoding", /*default=*/"", "OperationEncoding"
277+
"operation encoding", /*default=*/"", "OperationEncoding", "0"
276278
>;
277279

278280
//===----------------------------------------------------------------------===//
@@ -301,70 +303,6 @@ def LLVM_DIExpressionAttr : LLVM_Attr<"DIExpression", "di_expression"> {
301303
let assemblyFormat = "`<` ( `[` $operations^ `]` ) : (``)? `>`";
302304
}
303305

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-
368306
//===----------------------------------------------------------------------===//
369307
// DINullTypeAttr
370308
//===----------------------------------------------------------------------===//
@@ -421,9 +359,11 @@ def LLVM_DICompileUnitAttr : LLVM_Attr<"DICompileUnit", "di_compile_unit",
421359
//===----------------------------------------------------------------------===//
422360

423361
def LLVM_DICompositeTypeAttr : LLVM_Attr<"DICompositeType", "di_composite_type",
424-
/*traits=*/[], "DITypeAttr"> {
362+
[LLVM_DIRecursiveTypeAttrInterface],
363+
"DITypeAttr"> {
425364
let parameters = (ins
426365
LLVM_DITagParameter:$tag,
366+
OptionalParameter<"DistinctAttr">:$recId,
427367
OptionalParameter<"StringAttr">:$name,
428368
OptionalParameter<"DIFileAttr">:$file,
429369
OptionalParameter<"uint32_t">:$line,
@@ -435,6 +375,21 @@ def LLVM_DICompositeTypeAttr : LLVM_Attr<"DICompositeType", "di_composite_type",
435375
OptionalArrayRefParameter<"DINodeAttr">:$elements
436376
);
437377
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+
}];
438393
}
439394

440395
//===----------------------------------------------------------------------===//
@@ -590,15 +545,14 @@ def LLVM_DISubprogramAttr : LLVM_Attr<"DISubprogram", "di_subprogram",
590545
OptionalParameter<"unsigned">:$line,
591546
OptionalParameter<"unsigned">:$scopeLine,
592547
"DISubprogramFlags":$subprogramFlags,
593-
OptionalParameter<"DIRecursiveTypeAttrOf<DISubroutineTypeAttr>">:$type
548+
OptionalParameter<"DISubroutineTypeAttr">:$type
594549
);
595550
let builders = [
596551
AttrBuilderWithInferredContext<(ins
597552
"DistinctAttr":$id, "DICompileUnitAttr":$compileUnit,
598553
"DIScopeAttr":$scope, "StringRef":$name, "StringRef":$linkageName,
599554
"DIFileAttr":$file, "unsigned":$line, "unsigned":$scopeLine,
600-
"DISubprogramFlags":$subprogramFlags,
601-
"DIRecursiveTypeAttrOf<DISubroutineTypeAttr>":$type
555+
"DISubprogramFlags":$subprogramFlags, "DISubroutineTypeAttr":$type
602556
), [{
603557
MLIRContext *ctx = file.getContext();
604558
return $_get(ctx, id, compileUnit, scope, StringAttr::get(ctx, name),

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

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,6 @@ class TBAANodeAttr : public Attribute {
7474
}
7575
};
7676

77-
// Forward declare.
78-
template <typename BaseType>
79-
class DIRecursiveTypeAttrOf;
80-
8177
// Inline the LLVM generated Linkage enum and utility.
8278
// This is only necessary to isolate the "enum generated code" from the
8379
// attribute definition itself.
@@ -88,34 +84,9 @@ using linkage::Linkage;
8884
} // namespace LLVM
8985
} // namespace mlir
9086

87+
#include "mlir/Dialect/LLVMIR/LLVMAttrInterfaces.h.inc"
88+
9189
#define GET_ATTRDEF_CLASSES
9290
#include "mlir/Dialect/LLVMIR/LLVMOpsAttrDefs.h.inc"
9391

94-
namespace mlir {
95-
namespace LLVM {
96-
/// This class represents either a concrete attr, or a DIRecursiveTypeAttr
97-
/// containing such a concrete attr.
98-
template <typename BaseType>
99-
class DIRecursiveTypeAttrOf : public DITypeAttr {
100-
public:
101-
static_assert(std::is_base_of_v<DITypeAttr, BaseType>);
102-
using DITypeAttr::DITypeAttr;
103-
/// Support LLVM type casting.
104-
static bool classof(Attribute attr) {
105-
if (auto rec = llvm::dyn_cast<DIRecursiveTypeAttr>(attr))
106-
return llvm::isa<BaseType>(rec.getBaseType());
107-
return llvm::isa<BaseType>(attr);
108-
}
109-
110-
DIRecursiveTypeAttrOf(BaseType baseTypeAttr) : DITypeAttr(baseTypeAttr) {}
111-
112-
BaseType getUnfoldedBaseType() {
113-
if (auto rec = llvm::dyn_cast<DIRecursiveTypeAttr>(this))
114-
return llvm::cast<BaseType>(rec.getUnfoldedBaseType());
115-
return llvm::cast<BaseType>(this);
116-
}
117-
};
118-
} // namespace LLVM
119-
} // namespace mlir
120-
12192
#endif // MLIR_DIALECT_LLVMIR_LLVMATTRS_H_

mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88
//
9-
// This file defines op and type interfaces for the LLVM dialect in MLIR.
9+
// This file defines op, type, & attr interfaces for the LLVM dialect in MLIR.
1010
//
1111
//===----------------------------------------------------------------------===//
1212

@@ -319,4 +319,64 @@ def LLVM_PointerElementTypeInterface
319319
];
320320
}
321321

322+
//===----------------------------------------------------------------------===//
323+
// LLVM dialect attr interfaces.
324+
//===----------------------------------------------------------------------===//
325+
326+
def LLVM_DIRecursiveTypeAttrInterface
327+
: AttrInterface<"DIRecursiveTypeAttrInterface"> {
328+
let description = [{
329+
This attribute represents a DITypeAttr that is recursive. Only DITypeAttrs
330+
that translate to LLVM DITypes that support mutation should implement this
331+
interface.
332+
333+
There are two modes for conforming attributes:
334+
335+
1. "rec-decl":
336+
- This attr is a recursive declaration identified by a recId.
337+
338+
2. "rec-self":
339+
- This attr is considered a recursive self reference.
340+
- This attr itself is a placeholder type that should be conceptually
341+
replaced with the closest parent attr of the same type with the same
342+
recId.
343+
344+
e.g. To represent a linked list struct:
345+
346+
#rec_self = di_composite_type<recId = 0>
347+
#ptr = di_derived_type<baseType: #struct_self, ...>
348+
#field = di_derived_type<name = "next", baseType: #ptr, ...>
349+
#rec = di_composite_type<recId = 0, name = "Node", elements: #field, ...>
350+
#var = di_local_variable<type = #rec, ...>
351+
352+
Note that a rec-self without an outer rec-decl with the same recId is
353+
conceptually the same as an "unbound" variable. The context needs to provide
354+
meaning to the rec-self.
355+
356+
This can be avoided by calling the `getUnfoldedBaseType()` method on a
357+
rec-decl, which returns the same type with all matching rec-self instances
358+
replaced with this rec-decl again. This is useful, for example, for fetching
359+
a field out of a recursive struct and maintaining the legality of the field
360+
type.
361+
}];
362+
let cppNamespace = "::mlir::LLVM";
363+
let methods = [
364+
InterfaceMethod<[{
365+
Get whether this attr describes a recursive self reference.
366+
}], "bool", "isRecSelf", (ins)>,
367+
InterfaceMethod<[{
368+
Get the recursive ID used for matching "rec-decl" with "rec-self".
369+
If this attr instance is not recursive, return a null attribute.
370+
}], "DistinctAttr", "getRecId", (ins)>,
371+
InterfaceMethod<[{
372+
Get a copy of this type attr but with the recursive ID set to `recId`.
373+
}], "DIRecursiveTypeAttrInterface", "withRecId",
374+
(ins "DistinctAttr":$recId)>,
375+
StaticInterfaceMethod<[{
376+
Build a rec-self instance using the provided recId.
377+
}], "DIRecursiveTypeAttrInterface", "getRecSelf",
378+
(ins "DistinctAttr":$recId)>
379+
];
380+
}
381+
322382
#endif // LLVMIR_INTERFACES

mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ static LogicalResult parseExpressionArg(AsmParser &parser, uint64_t opcode,
3535
static void printExpressionArg(AsmPrinter &printer, uint64_t opcode,
3636
ArrayRef<uint64_t> args);
3737

38+
#include "mlir/Dialect/LLVMIR/LLVMAttrInterfaces.cpp.inc"
3839
#include "mlir/Dialect/LLVMIR/LLVMOpsEnums.cpp.inc"
3940
#define GET_ATTRDEF_CLASSES
4041
#include "mlir/Dialect/LLVMIR/LLVMOpsAttrDefs.cpp.inc"
@@ -86,9 +87,8 @@ bool DILocalScopeAttr::classof(Attribute attr) {
8687
//===----------------------------------------------------------------------===//
8788

8889
bool DITypeAttr::classof(Attribute attr) {
89-
return llvm::isa<DIRecursiveTypeAttr, DINullTypeAttr, DIBasicTypeAttr,
90-
DICompositeTypeAttr, DIDerivedTypeAttr,
91-
DISubroutineTypeAttr>(attr);
90+
return llvm::isa<DINullTypeAttr, DIBasicTypeAttr, DICompositeTypeAttr,
91+
DIDerivedTypeAttr, DISubroutineTypeAttr>(attr);
9292
}
9393

9494
//===----------------------------------------------------------------------===//
@@ -187,17 +187,21 @@ void printExpressionArg(AsmPrinter &printer, uint64_t opcode,
187187
}
188188

189189
//===----------------------------------------------------------------------===//
190-
// DIRecursiveTypeAttr
190+
// DICompositeTypeAttr
191191
//===----------------------------------------------------------------------===//
192192

193-
DITypeAttr DIRecursiveTypeAttr::getUnfoldedBaseType() {
194-
assert(!isRecSelf() && "cannot get baseType from a rec-self type");
195-
return llvm::cast<DITypeAttr>(getBaseType().replace(
196-
[&](DIRecursiveTypeAttr rec) -> std::optional<DIRecursiveTypeAttr> {
197-
if (rec.getRecId() == getRecId())
198-
return *this;
199-
return std::nullopt;
200-
}));
193+
DIRecursiveTypeAttrInterface
194+
DICompositeTypeAttr::withRecId(DistinctAttr recId) {
195+
return DICompositeTypeAttr::get(getContext(), getTag(), recId, getName(),
196+
getFile(), getLine(), getScope(),
197+
getBaseType(), getFlags(), getSizeInBits(),
198+
getAlignInBits(), getElements());
199+
}
200+
201+
DIRecursiveTypeAttrInterface
202+
DICompositeTypeAttr::getRecSelf(DistinctAttr recId) {
203+
return DICompositeTypeAttr::get(recId.getContext(), 0, recId, {}, {}, 0, {},
204+
{}, DIFlags(), 0, 0, {});
201205
}
202206

203207
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)