Skip to content

[mlir] Add support for DIGlobalVariable and DIGlobalVariableExpression #73367

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 58 additions & 5 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

include "mlir/Dialect/LLVMIR/LLVMDialect.td"
include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/CommonAttrConstraints.td"

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

def LLVM_DIOperationEncodingParameter : LLVM_DIParameter<
"operation encoding", /*default=*/"", "OperationEncoding"
>;

//===----------------------------------------------------------------------===//
// DIExpressionAttr
//===----------------------------------------------------------------------===//

// TODO: Implement custom printer/parser for elements so that operators are
// dumped in textual form.
def LLVM_DIExpressionAttr : ArrayOfAttr<LLVM_Dialect, "DIExpression",
"di_expr", "uint64_t"> {
let assemblyFormat = "`<` `[` (`]` `>`) : ($value^ `]` `>`)?";
def LLVM_DIExpressionElemAttr : LLVM_Attr<"DIExpressionElem",
"di_expression_elem"> {
let parameters = (ins
LLVM_DIOperationEncodingParameter:$opcode,
OptionalArrayRefParameter<"uint64_t">:$arguments);
let assemblyFormat = [{
`` $opcode ( `(` custom<ExpressionArg>(ref($opcode), $arguments)^ `)` ) : (``)?
}];
}

def LLVM_DIExpressionAttr : LLVM_Attr<"DIExpression", "di_expression"> {
let parameters = (ins
OptionalArrayRefParameter<"DIExpressionElemAttr">:$operations
);
let builders = [
AttrBuilder<(ins)>
];
let constBuilderCall =
"::mlir::LLVM::DIExpressionAttr::get($_builder.getContext(), $0)";
let assemblyFormat = "`<` ( `[` $operations^ `]` ) : (``)? `>`";
}

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

//===----------------------------------------------------------------------===//
// DIGlobalVariableExpressionAttr
//===----------------------------------------------------------------------===//

def LLVM_DIGlobalVariableExpressionAttr
: LLVM_Attr<"DIGlobalVariableExpression", "di_global_variable_expression"> {
let parameters = (ins
"DIGlobalVariableAttr":$var,
OptionalParameter<"DIExpressionAttr">:$expr
);
let assemblyFormat = "`<` struct(params) `>`";
let constBuilderCall = "$0";
}

//===----------------------------------------------------------------------===//
// DIGlobalVariableAttr
//===----------------------------------------------------------------------===//

def LLVM_DIGlobalVariable : LLVM_Attr<"DIGlobalVariable", "di_global_variable",
/*traits=*/[], "DINodeAttr"> {
let parameters = (ins
"DIScopeAttr":$scope,
"StringAttr":$name,
"StringAttr":$linkageName,
"DIFileAttr":$file,
"unsigned":$line,
"DITypeAttr":$type,
OptionalParameter<"bool">:$isLocalToUnit,
OptionalParameter<"bool">:$isDefined,
OptionalParameter<"unsigned">:$alignInBits);
let assemblyFormat = "`<` struct(params) `>`";
}

//===----------------------------------------------------------------------===//
// DILexicalBlockAttr
//===----------------------------------------------------------------------===//
Expand Down
3 changes: 3 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/TableGen/Constraint.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/TableGen/Record.h"
#include <optional>

#include "mlir/Dialect/LLVMIR/LLVMOpsEnums.h.inc"
Expand Down
6 changes: 3 additions & 3 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ class LLVM_DbgIntrOp<string name, string argName, list<Trait> traits = []>
llvm::MetadataAsValue::get(ctx,
llvm::ValueAsMetadata::get(moduleTranslation.lookupValue(opInst.getOperand(0)))),
llvm::MetadataAsValue::get(ctx, moduleTranslation.translateDebugInfo($varInfo)),
llvm::MetadataAsValue::get(ctx, llvm::DIExpression::get(ctx, $locationExpr)),
llvm::MetadataAsValue::get(ctx, moduleTranslation.translateExpression($locationExpr)),
});
}];
let mlirBuilder = [{
Expand All @@ -455,7 +455,7 @@ def LLVM_DbgDeclareOp : LLVM_DbgIntrOp<"dbg.declare", "addr",
let arguments = (ins
LLVM_AnyPointer:$addr,
LLVM_DILocalVariableAttr:$varInfo,
DefaultValuedAttr<LLVM_DIExpressionAttr, "std::nullopt">:$locationExpr
DefaultValuedAttr<LLVM_DIExpressionAttr, "{}">:$locationExpr
);
}

Expand All @@ -465,7 +465,7 @@ def LLVM_DbgValueOp : LLVM_DbgIntrOp<"dbg.value", "value",
let arguments = (ins
LLVM_Type:$value,
LLVM_DILocalVariableAttr:$varInfo,
DefaultValuedAttr<LLVM_DIExpressionAttr, "std::nullopt">:$locationExpr
DefaultValuedAttr<LLVM_DIExpressionAttr, "{}">:$locationExpr
);
}

Expand Down
4 changes: 3 additions & 1 deletion mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,7 @@ def LLVM_GlobalOp : LLVM_Op<"mlir.global",
OptionalAttr<UnnamedAddr>:$unnamed_addr,
OptionalAttr<StrAttr>:$section,
OptionalAttr<SymbolRefAttr>:$comdat,
DefaultValuedAttr<LLVM_DIGlobalVariableExpressionAttr, "{}">:$dbg_expr,
DefaultValuedAttr<Visibility, "mlir::LLVM::Visibility::Default">:$visibility_
);
let summary = "LLVM dialect global.";
Expand Down Expand Up @@ -1196,7 +1197,8 @@ def LLVM_GlobalOp : LLVM_Op<"mlir.global",
CArg<"bool", "false">:$dsoLocal,
CArg<"bool", "false">:$thread_local_,
CArg<"SymbolRefAttr", "{}">:$comdat,
CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs)>
CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs,
CArg<"DIGlobalVariableExpressionAttr", "{}">:$dbgExpr)>
];

let extraClassDeclaration = [{
Expand Down
7 changes: 7 additions & 0 deletions mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,13 @@ class ModuleTranslation {
/// Translates the given location.
llvm::DILocation *translateLoc(Location loc, llvm::DILocalScope *scope);

/// Translates the given LLVM DWARF expression metadata.
llvm::DIExpression *translateExpression(LLVM::DIExpressionAttr attr);

/// Translates the given LLVM global variable expression metadata.
llvm::DIGlobalVariableExpression *
translateGlobalVariableExpression(LLVM::DIGlobalVariableExpressionAttr attr);

/// Translates the given LLVM debug info metadata.
llvm::Metadata *translateDebugInfo(LLVM::DINodeAttr attr);

Expand Down
79 changes: 77 additions & 2 deletions mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,23 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include <optional>

using namespace mlir;
using namespace mlir::LLVM;

/// Parses DWARF expression arguments with respect to the DWARF operation
/// opcode. Some DWARF expression operations have a specific number of operands
/// and may appear in a textual form.
static LogicalResult parseExpressionArg(AsmParser &parser, uint64_t opcode,
SmallVector<uint64_t> &args);

/// Prints DWARF expression arguments with respect to the specific DWARF
/// operation. Some operands are printed in their textual form.
static LogicalResult printExpressionArg(AsmPrinter &printer, uint64_t opcode,
ArrayRef<uint64_t> args);

#include "mlir/Dialect/LLVMIR/LLVMOpsEnums.cpp.inc"
#define GET_ATTRDEF_CLASSES
#include "mlir/Dialect/LLVMIR/LLVMOpsAttrDefs.cpp.inc"
Expand All @@ -43,8 +55,8 @@ void LLVMDialect::registerAttributes() {

bool DINodeAttr::classof(Attribute attr) {
return llvm::isa<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
DIDerivedTypeAttr, DIFileAttr, DILabelAttr,
DILexicalBlockAttr, DILexicalBlockFileAttr,
DIDerivedTypeAttr, DIFileAttr, DIGlobalVariableAttr,
DILabelAttr, DILexicalBlockAttr, DILexicalBlockFileAttr,
DILocalVariableAttr, DIModuleAttr, DINamespaceAttr,
DINullTypeAttr, DISubprogramAttr, DISubrangeAttr,
DISubroutineTypeAttr>(attr);
Expand Down Expand Up @@ -109,3 +121,66 @@ bool MemoryEffectsAttr::isReadWrite() {
return false;
return true;
}

//===----------------------------------------------------------------------===//
// DIExpression
//===----------------------------------------------------------------------===//

DIExpressionAttr DIExpressionAttr::get(MLIRContext *context) {
return get(context, ArrayRef<DIExpressionElemAttr>({}));
}

LogicalResult parseExpressionArg(AsmParser &parser, uint64_t opcode,
SmallVector<uint64_t> &args) {
auto operandParser = [&]() -> LogicalResult {
uint64_t operand = 0;
if (!args.empty() && opcode == llvm::dwarf::DW_OP_LLVM_convert) {
// Attempt to parse a keyword.
StringRef keyword;
if (succeeded(parser.parseOptionalKeyword(&keyword))) {
operand = llvm::dwarf::getAttributeEncoding(keyword);
if (operand == 0) {
// The keyword is invalid.
return parser.emitError(parser.getCurrentLocation())
<< "encountered unknown attribute encoding \"" << keyword
<< "\"";
}
}
}

// operand should be non-zero if a keyword was parsed. Otherwise, the
// operand MUST be an integer.
if (operand == 0) {
// Parse the next operand as an integer.
if (parser.parseInteger(operand)) {
return parser.emitError(parser.getCurrentLocation())
<< "expected integer operand";
}
}

args.push_back(operand);
return success();
};

// Parse operands as a comma-separated list.
return parser.parseCommaSeparatedList(operandParser);
}

LogicalResult printExpressionArg(AsmPrinter &printer, uint64_t opcode,
ArrayRef<uint64_t> args) {
size_t i = 0;
llvm::interleaveComma(args, printer, [&](uint64_t operand) {
if (i > 0 && opcode == llvm::dwarf::DW_OP_LLVM_convert) {
if (const StringRef keyword =
llvm::dwarf::AttributeEncodingString(operand);
!keyword.empty()) {
printer << keyword;
return;
}
}
// All operands are expected to be printed as integers.
printer << operand;
i++;
});
return success();
}
10 changes: 8 additions & 2 deletions mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1781,7 +1781,8 @@ void GlobalOp::build(OpBuilder &builder, OperationState &result, Type type,
bool isConstant, Linkage linkage, StringRef name,
Attribute value, uint64_t alignment, unsigned addrSpace,
bool dsoLocal, bool threadLocal, SymbolRefAttr comdat,
ArrayRef<NamedAttribute> attrs) {
ArrayRef<NamedAttribute> attrs,
DIGlobalVariableExpressionAttr dbgExpr) {
result.addAttribute(getSymNameAttrName(result.name),
builder.getStringAttr(name));
result.addAttribute(getGlobalTypeAttrName(result.name), TypeAttr::get(type));
Expand Down Expand Up @@ -1812,6 +1813,10 @@ void GlobalOp::build(OpBuilder &builder, OperationState &result, Type type,
result.addAttribute(getAddrSpaceAttrName(result.name),
builder.getI32IntegerAttr(addrSpace));
result.attributes.append(attrs.begin(), attrs.end());

if (dbgExpr)
result.addAttribute(getDbgExprAttrName(result.name), dbgExpr);

result.addRegion();
}

Expand Down Expand Up @@ -2896,7 +2901,8 @@ struct LLVMOpAsmDialectInterface : public OpAsmDialectInterface {
return TypeSwitch<Attribute, AliasResult>(attr)
.Case<AccessGroupAttr, AliasScopeAttr, AliasScopeDomainAttr,
DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
DIDerivedTypeAttr, DIFileAttr, DILabelAttr, DILexicalBlockAttr,
DIDerivedTypeAttr, DIFileAttr, DIGlobalVariableAttr,
DIGlobalVariableExpressionAttr, DILabelAttr, DILexicalBlockAttr,
DILexicalBlockFileAttr, DILocalVariableAttr, DIModuleAttr,
DINamespaceAttr, DINullTypeAttr, DISubprogramAttr,
DISubroutineTypeAttr, LoopAnnotationAttr, LoopVectorizeAttr,
Expand Down
34 changes: 34 additions & 0 deletions mlir/lib/Target/LLVMIR/DebugImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,16 @@ DebugImporter::translateImpl(llvm::DILexicalBlockFile *node) {
node->getDiscriminator());
}

DIGlobalVariableAttr
DebugImporter::translateImpl(llvm::DIGlobalVariable *node) {
return DIGlobalVariableAttr::get(
context, translate(node->getScope()),
StringAttr::get(context, node->getName()),
StringAttr::get(context, node->getLinkageName()),
translate(node->getFile()), node->getLine(), translate(node->getType()),
node->isLocalToUnit(), node->isDefinition(), node->getAlignInBits());
}

DILocalVariableAttr DebugImporter::translateImpl(llvm::DILocalVariable *node) {
return DILocalVariableAttr::get(context, translate(node->getScope()),
getStringAttrOrNull(node->getRawName()),
Expand Down Expand Up @@ -231,6 +241,8 @@ DINodeAttr DebugImporter::translate(llvm::DINode *node) {
return translateImpl(casted);
if (auto *casted = dyn_cast<llvm::DIFile>(node))
return translateImpl(casted);
if (auto *casted = dyn_cast<llvm::DIGlobalVariable>(node))
return translateImpl(casted);
if (auto *casted = dyn_cast<llvm::DILabel>(node))
return translateImpl(casted);
if (auto *casted = dyn_cast<llvm::DILexicalBlock>(node))
Expand Down Expand Up @@ -281,6 +293,28 @@ Location DebugImporter::translateLoc(llvm::DILocation *loc) {
return result;
}

DIExpressionAttr DebugImporter::translateExpression(llvm::DIExpression *node) {
SmallVector<DIExpressionElemAttr> ops;

// Begin processing the operations.
for (const llvm::DIExpression::ExprOperand &op : node->expr_ops()) {
SmallVector<uint64_t> operands;
operands.reserve(op.getNumArgs());
for (const auto &i : llvm::seq(op.getNumArgs()))
operands.push_back(op.getArg(i));
const auto attr = DIExpressionElemAttr::get(context, op.getOp(), operands);
ops.push_back(attr);
}
return DIExpressionAttr::get(context, ops);
}

DIGlobalVariableExpressionAttr DebugImporter::translateGlobalVariableExpression(
llvm::DIGlobalVariableExpression *node) {
return DIGlobalVariableExpressionAttr::get(
context, translate(node->getVariable()),
translateExpression(node->getExpression()));
}

StringAttr DebugImporter::getStringAttrOrNull(llvm::MDString *stringNode) {
if (!stringNode)
return StringAttr();
Expand Down
8 changes: 8 additions & 0 deletions mlir/lib/Target/LLVMIR/DebugImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ class DebugImporter {
/// Translates the given LLVM debug location to an MLIR location.
Location translateLoc(llvm::DILocation *loc);

/// Translates the LLVM DWARF expression metadata to MLIR.
DIExpressionAttr translateExpression(llvm::DIExpression *node);

/// Translates the LLVM DWARF global variable expression metadata to MLIR.
DIGlobalVariableExpressionAttr
translateGlobalVariableExpression(llvm::DIGlobalVariableExpression *node);

/// Translates the debug information for the given function into a Location.
/// Returns UnknownLoc if `func` has no debug information attached to it.
Location translateFuncLocation(llvm::Function *func);
Expand All @@ -61,6 +68,7 @@ class DebugImporter {
DILabelAttr translateImpl(llvm::DILabel *node);
DILexicalBlockAttr translateImpl(llvm::DILexicalBlock *node);
DILexicalBlockFileAttr translateImpl(llvm::DILexicalBlockFile *node);
DIGlobalVariableAttr translateImpl(llvm::DIGlobalVariable *node);
DILocalVariableAttr translateImpl(llvm::DILocalVariable *node);
DIModuleAttr translateImpl(llvm::DIModule *node);
DINamespaceAttr translateImpl(llvm::DINamespace *node);
Expand Down
Loading