Skip to content

Commit 6da578c

Browse files
authored
[mlir] Add support for DIGlobalVariable and DIGlobalVariableExpression (#73367)
This PR introduces DIGlobalVariableAttr and DIGlobalVariableExpressionAttr so that ModuleTranslation can emit the required metadata needed for debug information about global variable. The translator implementation for debug metadata needed to be refactored in order to allow translation of nodes based on MDNode (DIGlobalVariableExpressionAttr and DIExpression) in addition to DINode-based nodes. A DIGlobalVariableExpressionAttr can now be passed to the GlobalOp operation directly and ModuleTranslation will create the respective DIGlobalVariable and DIGlobalVariableExpression nodes. The compile unit that DIGlobalVariable is expected to be configured with will be updated with the created DIGlobalVariableExpression.
1 parent 8f40ef3 commit 6da578c

File tree

18 files changed

+379
-27
lines changed

18 files changed

+379
-27
lines changed

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

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
include "mlir/Dialect/LLVMIR/LLVMDialect.td"
1313
include "mlir/IR/AttrTypeBase.td"
14+
include "mlir/IR/CommonAttrConstraints.td"
1415

1516
// All of the attributes will extend this class.
1617
class LLVM_Attr<string name, string attrMnemonic,
@@ -261,15 +262,34 @@ def LLVM_DITagParameter : LLVM_DIParameter<
261262
"tag", /*default=*/"", "Tag"
262263
>;
263264

265+
def LLVM_DIOperationEncodingParameter : LLVM_DIParameter<
266+
"operation encoding", /*default=*/"", "OperationEncoding"
267+
>;
268+
264269
//===----------------------------------------------------------------------===//
265270
// DIExpressionAttr
266271
//===----------------------------------------------------------------------===//
267272

268-
// TODO: Implement custom printer/parser for elements so that operators are
269-
// dumped in textual form.
270-
def LLVM_DIExpressionAttr : ArrayOfAttr<LLVM_Dialect, "DIExpression",
271-
"di_expr", "uint64_t"> {
272-
let assemblyFormat = "`<` `[` (`]` `>`) : ($value^ `]` `>`)?";
273+
def LLVM_DIExpressionElemAttr : LLVM_Attr<"DIExpressionElem",
274+
"di_expression_elem"> {
275+
let parameters = (ins
276+
LLVM_DIOperationEncodingParameter:$opcode,
277+
OptionalArrayRefParameter<"uint64_t">:$arguments);
278+
let assemblyFormat = [{
279+
`` $opcode ( `(` custom<ExpressionArg>(ref($opcode), $arguments)^ `)` ) : (``)?
280+
}];
281+
}
282+
283+
def LLVM_DIExpressionAttr : LLVM_Attr<"DIExpression", "di_expression"> {
284+
let parameters = (ins
285+
OptionalArrayRefParameter<"DIExpressionElemAttr">:$operations
286+
);
287+
let builders = [
288+
AttrBuilder<(ins)>
289+
];
290+
let constBuilderCall =
291+
"::mlir::LLVM::DIExpressionAttr::get($_builder.getContext(), $0)";
292+
let assemblyFormat = "`<` ( `[` $operations^ `]` ) : (``)? `>`";
273293
}
274294

275295
//===----------------------------------------------------------------------===//
@@ -374,6 +394,39 @@ def LLVM_DIFileAttr : LLVM_Attr<"DIFile", "di_file", /*traits=*/[], "DIScopeAttr
374394
let assemblyFormat = "`<` $name `in` $directory `>`";
375395
}
376396

397+
//===----------------------------------------------------------------------===//
398+
// DIGlobalVariableExpressionAttr
399+
//===----------------------------------------------------------------------===//
400+
401+
def LLVM_DIGlobalVariableExpressionAttr
402+
: LLVM_Attr<"DIGlobalVariableExpression", "di_global_variable_expression"> {
403+
let parameters = (ins
404+
"DIGlobalVariableAttr":$var,
405+
OptionalParameter<"DIExpressionAttr">:$expr
406+
);
407+
let assemblyFormat = "`<` struct(params) `>`";
408+
let constBuilderCall = "$0";
409+
}
410+
411+
//===----------------------------------------------------------------------===//
412+
// DIGlobalVariableAttr
413+
//===----------------------------------------------------------------------===//
414+
415+
def LLVM_DIGlobalVariable : LLVM_Attr<"DIGlobalVariable", "di_global_variable",
416+
/*traits=*/[], "DINodeAttr"> {
417+
let parameters = (ins
418+
"DIScopeAttr":$scope,
419+
"StringAttr":$name,
420+
"StringAttr":$linkageName,
421+
"DIFileAttr":$file,
422+
"unsigned":$line,
423+
"DITypeAttr":$type,
424+
OptionalParameter<"bool">:$isLocalToUnit,
425+
OptionalParameter<"bool">:$isDefined,
426+
OptionalParameter<"unsigned">:$alignInBits);
427+
let assemblyFormat = "`<` struct(params) `>`";
428+
}
429+
377430
//===----------------------------------------------------------------------===//
378431
// DILexicalBlockAttr
379432
//===----------------------------------------------------------------------===//

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
1818
#include "mlir/IR/OpImplementation.h"
19+
#include "mlir/TableGen/Constraint.h"
20+
#include "llvm/BinaryFormat/Dwarf.h"
21+
#include "llvm/TableGen/Record.h"
1922
#include <optional>
2023

2124
#include "mlir/Dialect/LLVMIR/LLVMOpsEnums.h.inc"

mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ class LLVM_DbgIntrOp<string name, string argName, list<Trait> traits = []>
434434
llvm::MetadataAsValue::get(ctx,
435435
llvm::ValueAsMetadata::get(moduleTranslation.lookupValue(opInst.getOperand(0)))),
436436
llvm::MetadataAsValue::get(ctx, moduleTranslation.translateDebugInfo($varInfo)),
437-
llvm::MetadataAsValue::get(ctx, llvm::DIExpression::get(ctx, $locationExpr)),
437+
llvm::MetadataAsValue::get(ctx, moduleTranslation.translateExpression($locationExpr)),
438438
});
439439
}];
440440
let mlirBuilder = [{
@@ -455,7 +455,7 @@ def LLVM_DbgDeclareOp : LLVM_DbgIntrOp<"dbg.declare", "addr",
455455
let arguments = (ins
456456
LLVM_AnyPointer:$addr,
457457
LLVM_DILocalVariableAttr:$varInfo,
458-
DefaultValuedAttr<LLVM_DIExpressionAttr, "std::nullopt">:$locationExpr
458+
DefaultValuedAttr<LLVM_DIExpressionAttr, "{}">:$locationExpr
459459
);
460460
}
461461

@@ -465,7 +465,7 @@ def LLVM_DbgValueOp : LLVM_DbgIntrOp<"dbg.value", "value",
465465
let arguments = (ins
466466
LLVM_Type:$value,
467467
LLVM_DILocalVariableAttr:$varInfo,
468-
DefaultValuedAttr<LLVM_DIExpressionAttr, "std::nullopt">:$locationExpr
468+
DefaultValuedAttr<LLVM_DIExpressionAttr, "{}">:$locationExpr
469469
);
470470
}
471471

mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,7 @@ def LLVM_GlobalOp : LLVM_Op<"mlir.global",
10871087
OptionalAttr<UnnamedAddr>:$unnamed_addr,
10881088
OptionalAttr<StrAttr>:$section,
10891089
OptionalAttr<SymbolRefAttr>:$comdat,
1090+
DefaultValuedAttr<LLVM_DIGlobalVariableExpressionAttr, "{}">:$dbg_expr,
10901091
DefaultValuedAttr<Visibility, "mlir::LLVM::Visibility::Default">:$visibility_
10911092
);
10921093
let summary = "LLVM dialect global.";
@@ -1196,7 +1197,8 @@ def LLVM_GlobalOp : LLVM_Op<"mlir.global",
11961197
CArg<"bool", "false">:$dsoLocal,
11971198
CArg<"bool", "false">:$thread_local_,
11981199
CArg<"SymbolRefAttr", "{}">:$comdat,
1199-
CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs)>
1200+
CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs,
1201+
CArg<"DIGlobalVariableExpressionAttr", "{}">:$dbgExpr)>
12001202
];
12011203

12021204
let extraClassDeclaration = [{

mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,13 @@ class ModuleTranslation {
191191
/// Translates the given location.
192192
llvm::DILocation *translateLoc(Location loc, llvm::DILocalScope *scope);
193193

194+
/// Translates the given LLVM DWARF expression metadata.
195+
llvm::DIExpression *translateExpression(LLVM::DIExpressionAttr attr);
196+
197+
/// Translates the given LLVM global variable expression metadata.
198+
llvm::DIGlobalVariableExpression *
199+
translateGlobalVariableExpression(LLVM::DIGlobalVariableExpressionAttr attr);
200+
194201
/// Translates the given LLVM debug info metadata.
195202
llvm::Metadata *translateDebugInfo(LLVM::DINodeAttr attr);
196203

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

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,23 @@
1717
#include "llvm/ADT/StringExtras.h"
1818
#include "llvm/ADT/TypeSwitch.h"
1919
#include "llvm/BinaryFormat/Dwarf.h"
20+
#include "llvm/IR/DebugInfoMetadata.h"
2021
#include <optional>
2122

2223
using namespace mlir;
2324
using namespace mlir::LLVM;
2425

26+
/// Parses DWARF expression arguments with respect to the DWARF operation
27+
/// opcode. Some DWARF expression operations have a specific number of operands
28+
/// and may appear in a textual form.
29+
static LogicalResult parseExpressionArg(AsmParser &parser, uint64_t opcode,
30+
SmallVector<uint64_t> &args);
31+
32+
/// Prints DWARF expression arguments with respect to the specific DWARF
33+
/// operation. Some operands are printed in their textual form.
34+
static LogicalResult printExpressionArg(AsmPrinter &printer, uint64_t opcode,
35+
ArrayRef<uint64_t> args);
36+
2537
#include "mlir/Dialect/LLVMIR/LLVMOpsEnums.cpp.inc"
2638
#define GET_ATTRDEF_CLASSES
2739
#include "mlir/Dialect/LLVMIR/LLVMOpsAttrDefs.cpp.inc"
@@ -43,8 +55,8 @@ void LLVMDialect::registerAttributes() {
4355

4456
bool DINodeAttr::classof(Attribute attr) {
4557
return llvm::isa<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
46-
DIDerivedTypeAttr, DIFileAttr, DILabelAttr,
47-
DILexicalBlockAttr, DILexicalBlockFileAttr,
58+
DIDerivedTypeAttr, DIFileAttr, DIGlobalVariableAttr,
59+
DILabelAttr, DILexicalBlockAttr, DILexicalBlockFileAttr,
4860
DILocalVariableAttr, DIModuleAttr, DINamespaceAttr,
4961
DINullTypeAttr, DISubprogramAttr, DISubrangeAttr,
5062
DISubroutineTypeAttr>(attr);
@@ -109,3 +121,66 @@ bool MemoryEffectsAttr::isReadWrite() {
109121
return false;
110122
return true;
111123
}
124+
125+
//===----------------------------------------------------------------------===//
126+
// DIExpression
127+
//===----------------------------------------------------------------------===//
128+
129+
DIExpressionAttr DIExpressionAttr::get(MLIRContext *context) {
130+
return get(context, ArrayRef<DIExpressionElemAttr>({}));
131+
}
132+
133+
LogicalResult parseExpressionArg(AsmParser &parser, uint64_t opcode,
134+
SmallVector<uint64_t> &args) {
135+
auto operandParser = [&]() -> LogicalResult {
136+
uint64_t operand = 0;
137+
if (!args.empty() && opcode == llvm::dwarf::DW_OP_LLVM_convert) {
138+
// Attempt to parse a keyword.
139+
StringRef keyword;
140+
if (succeeded(parser.parseOptionalKeyword(&keyword))) {
141+
operand = llvm::dwarf::getAttributeEncoding(keyword);
142+
if (operand == 0) {
143+
// The keyword is invalid.
144+
return parser.emitError(parser.getCurrentLocation())
145+
<< "encountered unknown attribute encoding \"" << keyword
146+
<< "\"";
147+
}
148+
}
149+
}
150+
151+
// operand should be non-zero if a keyword was parsed. Otherwise, the
152+
// operand MUST be an integer.
153+
if (operand == 0) {
154+
// Parse the next operand as an integer.
155+
if (parser.parseInteger(operand)) {
156+
return parser.emitError(parser.getCurrentLocation())
157+
<< "expected integer operand";
158+
}
159+
}
160+
161+
args.push_back(operand);
162+
return success();
163+
};
164+
165+
// Parse operands as a comma-separated list.
166+
return parser.parseCommaSeparatedList(operandParser);
167+
}
168+
169+
LogicalResult printExpressionArg(AsmPrinter &printer, uint64_t opcode,
170+
ArrayRef<uint64_t> args) {
171+
size_t i = 0;
172+
llvm::interleaveComma(args, printer, [&](uint64_t operand) {
173+
if (i > 0 && opcode == llvm::dwarf::DW_OP_LLVM_convert) {
174+
if (const StringRef keyword =
175+
llvm::dwarf::AttributeEncodingString(operand);
176+
!keyword.empty()) {
177+
printer << keyword;
178+
return;
179+
}
180+
}
181+
// All operands are expected to be printed as integers.
182+
printer << operand;
183+
i++;
184+
});
185+
return success();
186+
}

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,7 +1781,8 @@ void GlobalOp::build(OpBuilder &builder, OperationState &result, Type type,
17811781
bool isConstant, Linkage linkage, StringRef name,
17821782
Attribute value, uint64_t alignment, unsigned addrSpace,
17831783
bool dsoLocal, bool threadLocal, SymbolRefAttr comdat,
1784-
ArrayRef<NamedAttribute> attrs) {
1784+
ArrayRef<NamedAttribute> attrs,
1785+
DIGlobalVariableExpressionAttr dbgExpr) {
17851786
result.addAttribute(getSymNameAttrName(result.name),
17861787
builder.getStringAttr(name));
17871788
result.addAttribute(getGlobalTypeAttrName(result.name), TypeAttr::get(type));
@@ -1812,6 +1813,10 @@ void GlobalOp::build(OpBuilder &builder, OperationState &result, Type type,
18121813
result.addAttribute(getAddrSpaceAttrName(result.name),
18131814
builder.getI32IntegerAttr(addrSpace));
18141815
result.attributes.append(attrs.begin(), attrs.end());
1816+
1817+
if (dbgExpr)
1818+
result.addAttribute(getDbgExprAttrName(result.name), dbgExpr);
1819+
18151820
result.addRegion();
18161821
}
18171822

@@ -2910,7 +2915,8 @@ struct LLVMOpAsmDialectInterface : public OpAsmDialectInterface {
29102915
return TypeSwitch<Attribute, AliasResult>(attr)
29112916
.Case<AccessGroupAttr, AliasScopeAttr, AliasScopeDomainAttr,
29122917
DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
2913-
DIDerivedTypeAttr, DIFileAttr, DILabelAttr, DILexicalBlockAttr,
2918+
DIDerivedTypeAttr, DIFileAttr, DIGlobalVariableAttr,
2919+
DIGlobalVariableExpressionAttr, DILabelAttr, DILexicalBlockAttr,
29142920
DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr,
29152921
DINamespaceAttr, DINullTypeAttr, DISubprogramAttr,
29162922
DISubroutineTypeAttr, LoopAnnotationAttr, LoopVectorizeAttr,

mlir/lib/Target/LLVMIR/DebugImporter.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ DebugImporter::translateImpl(llvm::DILexicalBlockFile *node) {
116116
node->getDiscriminator());
117117
}
118118

119+
DIGlobalVariableAttr
120+
DebugImporter::translateImpl(llvm::DIGlobalVariable *node) {
121+
return DIGlobalVariableAttr::get(
122+
context, translate(node->getScope()),
123+
StringAttr::get(context, node->getName()),
124+
StringAttr::get(context, node->getLinkageName()),
125+
translate(node->getFile()), node->getLine(), translate(node->getType()),
126+
node->isLocalToUnit(), node->isDefinition(), node->getAlignInBits());
127+
}
128+
119129
DILocalVariableAttr DebugImporter::translateImpl(llvm::DILocalVariable *node) {
120130
return DILocalVariableAttr::get(context, translate(node->getScope()),
121131
getStringAttrOrNull(node->getRawName()),
@@ -231,6 +241,8 @@ DINodeAttr DebugImporter::translate(llvm::DINode *node) {
231241
return translateImpl(casted);
232242
if (auto *casted = dyn_cast<llvm::DIFile>(node))
233243
return translateImpl(casted);
244+
if (auto *casted = dyn_cast<llvm::DIGlobalVariable>(node))
245+
return translateImpl(casted);
234246
if (auto *casted = dyn_cast<llvm::DILabel>(node))
235247
return translateImpl(casted);
236248
if (auto *casted = dyn_cast<llvm::DILexicalBlock>(node))
@@ -281,6 +293,28 @@ Location DebugImporter::translateLoc(llvm::DILocation *loc) {
281293
return result;
282294
}
283295

296+
DIExpressionAttr DebugImporter::translateExpression(llvm::DIExpression *node) {
297+
SmallVector<DIExpressionElemAttr> ops;
298+
299+
// Begin processing the operations.
300+
for (const llvm::DIExpression::ExprOperand &op : node->expr_ops()) {
301+
SmallVector<uint64_t> operands;
302+
operands.reserve(op.getNumArgs());
303+
for (const auto &i : llvm::seq(op.getNumArgs()))
304+
operands.push_back(op.getArg(i));
305+
const auto attr = DIExpressionElemAttr::get(context, op.getOp(), operands);
306+
ops.push_back(attr);
307+
}
308+
return DIExpressionAttr::get(context, ops);
309+
}
310+
311+
DIGlobalVariableExpressionAttr DebugImporter::translateGlobalVariableExpression(
312+
llvm::DIGlobalVariableExpression *node) {
313+
return DIGlobalVariableExpressionAttr::get(
314+
context, translate(node->getVariable()),
315+
translateExpression(node->getExpression()));
316+
}
317+
284318
StringAttr DebugImporter::getStringAttrOrNull(llvm::MDString *stringNode) {
285319
if (!stringNode)
286320
return StringAttr();

mlir/lib/Target/LLVMIR/DebugImporter.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ class DebugImporter {
3535
/// Translates the given LLVM debug location to an MLIR location.
3636
Location translateLoc(llvm::DILocation *loc);
3737

38+
/// Translates the LLVM DWARF expression metadata to MLIR.
39+
DIExpressionAttr translateExpression(llvm::DIExpression *node);
40+
41+
/// Translates the LLVM DWARF global variable expression metadata to MLIR.
42+
DIGlobalVariableExpressionAttr
43+
translateGlobalVariableExpression(llvm::DIGlobalVariableExpression *node);
44+
3845
/// Translates the debug information for the given function into a Location.
3946
/// Returns UnknownLoc if `func` has no debug information attached to it.
4047
Location translateFuncLocation(llvm::Function *func);
@@ -61,6 +68,7 @@ class DebugImporter {
6168
DILabelAttr translateImpl(llvm::DILabel *node);
6269
DILexicalBlockAttr translateImpl(llvm::DILexicalBlock *node);
6370
DILexicalBlockFileAttr translateImpl(llvm::DILexicalBlockFile *node);
71+
DIGlobalVariableAttr translateImpl(llvm::DIGlobalVariable *node);
6472
DILocalVariableAttr translateImpl(llvm::DILocalVariable *node);
6573
DIModuleAttr translateImpl(llvm::DIModule *node);
6674
DINamespaceAttr translateImpl(llvm::DINamespace *node);

0 commit comments

Comments
 (0)