Skip to content

Commit 1e8dad3

Browse files
zyx-billygysit
andauthored
[MLIR][LLVM] Support Recursive DITypes (#80251)
Following the discussion from [this thread](https://discourse.llvm.org/t/handling-cyclic-dependencies-in-debug-info/67526/11), this PR adds support for recursive DITypes. This PR adds: 1. DIRecursiveTypeAttrInterface: An interface that DITypeAttrs can implement to indicate that it supports recursion. See full description in code. 2. Importer & exporter support (The only DITypeAttr that implements the interface is DICompositeTypeAttr, so the exporter is only implemented for composites too. There will be two methods that each llvm DI type that supports mutation needs to implement since there's nothing general). --------- Co-authored-by: Tobias Gysi <[email protected]>
1 parent 9a42bdc commit 1e8dad3

File tree

15 files changed

+416
-143
lines changed

15 files changed

+416
-143
lines changed

mlir/include/mlir-c/Dialect/LLVM.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,10 @@ MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDIBasicTypeAttrGet(
229229

230230
/// Creates a LLVM DICompositeType attribute.
231231
MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDICompositeTypeAttrGet(
232-
MlirContext ctx, unsigned int tag, MlirAttribute name, MlirAttribute file,
233-
uint32_t line, MlirAttribute scope, MlirAttribute baseType, int64_t flags,
234-
uint64_t sizeInBits, uint64_t alignInBits, intptr_t nElements,
235-
MlirAttribute const *elements);
232+
MlirContext ctx, unsigned int tag, MlirAttribute recId, MlirAttribute name,
233+
MlirAttribute file, uint32_t line, MlirAttribute scope,
234+
MlirAttribute baseType, int64_t flags, uint64_t sizeInBits,
235+
uint64_t alignInBits, intptr_t nElements, MlirAttribute const *elements);
236236

237237
/// Creates a LLVM DIDerivedType attribute.
238238
MLIR_CAPI_EXPORTED MlirAttribute mlirLLVMDIDerivedTypeAttrGet(

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: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define LLVMIR_ATTRDEFS
1111

1212
include "mlir/Dialect/LLVMIR/LLVMDialect.td"
13+
include "mlir/Dialect/LLVMIR/LLVMInterfaces.td"
1314
include "mlir/IR/AttrTypeBase.td"
1415
include "mlir/IR/CommonAttrConstraints.td"
1516

@@ -238,41 +239,43 @@ 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", /*errorCase=*/"0",
262+
"Convention"
260263
>;
261264

262265
def LLVM_DIEncodingParameter : LLVM_DIParameter<
263-
"encoding", /*default=*/"0", "AttributeEncoding"
266+
"encoding", /*default=*/"0", "AttributeEncoding", /*errorCase=*/"0"
264267
>;
265268

266269
def LLVM_DILanguageParameter : LLVM_DIParameter<
267-
"language", /*default=*/"", "Language"
270+
"language", /*default=*/"", "Language", /*errorCase=*/"0"
268271
>;
269272

270273
def LLVM_DITagParameter : LLVM_DIParameter<
271-
"tag", /*default=*/"", "Tag"
274+
"tag", /*default=*/"", "Tag", /*errorCase=*/"llvm::dwarf::DW_TAG_invalid"
272275
>;
273276

274277
def LLVM_DIOperationEncodingParameter : LLVM_DIParameter<
275-
"operation encoding", /*default=*/"", "OperationEncoding"
278+
"operation encoding", /*default=*/"", "OperationEncoding", /*errorCase=*/"0"
276279
>;
277280

278281
//===----------------------------------------------------------------------===//
@@ -357,9 +360,11 @@ def LLVM_DICompileUnitAttr : LLVM_Attr<"DICompileUnit", "di_compile_unit",
357360
//===----------------------------------------------------------------------===//
358361

359362
def LLVM_DICompositeTypeAttr : LLVM_Attr<"DICompositeType", "di_composite_type",
360-
/*traits=*/[], "DITypeAttr"> {
363+
[LLVM_DIRecursiveTypeAttrInterface],
364+
"DITypeAttr"> {
361365
let parameters = (ins
362366
LLVM_DITagParameter:$tag,
367+
OptionalParameter<"DistinctAttr">:$recId,
363368
OptionalParameter<"StringAttr">:$name,
364369
OptionalParameter<"DIFileAttr">:$file,
365370
OptionalParameter<"uint32_t">:$line,
@@ -371,6 +376,21 @@ def LLVM_DICompositeTypeAttr : LLVM_Attr<"DICompositeType", "di_composite_type",
371376
OptionalArrayRefParameter<"DINodeAttr">:$elements
372377
);
373378
let assemblyFormat = "`<` struct(params) `>`";
379+
let extraClassDeclaration = [{
380+
/// Requirements of DIRecursiveTypeAttrInterface.
381+
/// @{
382+
383+
/// Get whether this attr describes a recursive self reference.
384+
bool isRecSelf() { return getTag() == 0; }
385+
386+
/// Get a copy of this type attr but with the recursive ID set to `recId`.
387+
DIRecursiveTypeAttrInterface withRecId(DistinctAttr recId);
388+
389+
/// Build a rec-self instance using the provided `recId`.
390+
static DIRecursiveTypeAttrInterface getRecSelf(DistinctAttr recId);
391+
392+
/// @}
393+
}];
374394
}
375395

376396
//===----------------------------------------------------------------------===//

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ using linkage::Linkage;
8484
} // namespace LLVM
8585
} // namespace mlir
8686

87+
#include "mlir/Dialect/LLVMIR/LLVMAttrInterfaces.h.inc"
88+
8789
#define GET_ATTRDEF_CLASSES
8890
#include "mlir/Dialect/LLVMIR/LLVMOpsAttrDefs.h.inc"
8991

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

Lines changed: 55 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 interfaces for the LLVM dialect in MLIR.
1010
//
1111
//===----------------------------------------------------------------------===//
1212

@@ -319,4 +319,58 @@ 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+
For example, to represent a linked list struct:
345+
346+
#rec_self = di_composite_type<recId = 0>
347+
#ptr = di_derived_type<baseType: #rec_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+
let cppNamespace = "::mlir::LLVM";
357+
let methods = [
358+
InterfaceMethod<[{
359+
Get whether this attr describes a recursive self reference.
360+
}], "bool", "isRecSelf", (ins)>,
361+
InterfaceMethod<[{
362+
Get the recursive ID used for matching "rec-decl" with "rec-self".
363+
If this attr instance is not recursive, return a null attribute.
364+
}], "DistinctAttr", "getRecId", (ins)>,
365+
InterfaceMethod<[{
366+
Get a copy of this type attr but with the recursive ID set to `recId`.
367+
}], "DIRecursiveTypeAttrInterface", "withRecId",
368+
(ins "DistinctAttr":$recId)>,
369+
StaticInterfaceMethod<[{
370+
Build a rec-self instance using the provided `recId`.
371+
}], "DIRecursiveTypeAttrInterface", "getRecSelf",
372+
(ins "DistinctAttr":$recId)>
373+
];
374+
}
375+
322376
#endif // LLVMIR_INTERFACES

mlir/lib/CAPI/Dialect/LLVM.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -152,18 +152,18 @@ MlirAttribute mlirLLVMDIBasicTypeAttrGet(MlirContext ctx, unsigned int tag,
152152
}
153153

154154
MlirAttribute mlirLLVMDICompositeTypeAttrGet(
155-
MlirContext ctx, unsigned int tag, MlirAttribute name, MlirAttribute file,
156-
uint32_t line, MlirAttribute scope, MlirAttribute baseType, int64_t flags,
157-
uint64_t sizeInBits, uint64_t alignInBits, intptr_t nElements,
158-
MlirAttribute const *elements) {
155+
MlirContext ctx, unsigned int tag, MlirAttribute recId, MlirAttribute name,
156+
MlirAttribute file, uint32_t line, MlirAttribute scope,
157+
MlirAttribute baseType, int64_t flags, uint64_t sizeInBits,
158+
uint64_t alignInBits, intptr_t nElements, MlirAttribute const *elements) {
159159
SmallVector<Attribute> elementsStorage;
160160
elementsStorage.reserve(nElements);
161161

162162
return wrap(DICompositeTypeAttr::get(
163-
unwrap(ctx), tag, cast<StringAttr>(unwrap(name)),
164-
cast<DIFileAttr>(unwrap(file)), line, cast<DIScopeAttr>(unwrap(scope)),
165-
cast<DITypeAttr>(unwrap(baseType)), DIFlags(flags), sizeInBits,
166-
alignInBits,
163+
unwrap(ctx), tag, cast<DistinctAttr>(unwrap(recId)),
164+
cast<StringAttr>(unwrap(name)), cast<DIFileAttr>(unwrap(file)), line,
165+
cast<DIScopeAttr>(unwrap(scope)), cast<DITypeAttr>(unwrap(baseType)),
166+
DIFlags(flags), sizeInBits, alignInBits,
167167
llvm::map_to_vector(unwrapList(nElements, elements, elementsStorage),
168168
[](Attribute a) { return a.cast<DINodeAttr>(); })));
169169
}

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

Lines changed: 19 additions & 0 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"
@@ -185,6 +186,24 @@ void printExpressionArg(AsmPrinter &printer, uint64_t opcode,
185186
});
186187
}
187188

189+
//===----------------------------------------------------------------------===//
190+
// DICompositeTypeAttr
191+
//===----------------------------------------------------------------------===//
192+
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, {});
205+
}
206+
188207
//===----------------------------------------------------------------------===//
189208
// TargetFeaturesAttr
190209
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)