-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
We need to emit complete debug information for YUL sources, including the generation of relevant debug records such as #dbg_declare for local variables. Below is a hackery attempt to enable #dbg_declare:
libsolidity/codegen/mlir/YulToMLIR.cpp
@@ -562,6 +562,7 @@ void YulToMLIRPass::operator()(VariableDeclaration const &decl) {
getLoc(var.debugData),
/*resTy=*/mlir::LLVM::LLVMPointerType::get(b.getContext()),
/*eltTy=*/getDefIntTy(), bExt.genI256Const(1), getDefAlign());
+ addr->setAttr("var_name", b.getStringAttr(var.name.str()));
trackLocalVarAddr(var.name, addr);
b.create<mlir::LLVM::StoreOp>(loc, rhsExpr, addr, getDefAlign());
}
--- a/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
+++ b/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
@@ -34,6 +34,46 @@ static FileLineColLoc extractFileLoc(Location loc) {
return FileLineColLoc();
}
+static uint32_t getLineFromLoc(mlir::Location loc) {
+ uint32_t line = 1;
+ if (auto fileLoc = mlir::dyn_cast<mlir::FileLineColLoc>(loc))
+ line = fileLoc.getLine();
+ return line;
+}
+
+static void handleDeclareOp(mlir::LLVM::AllocaOp declOp,
+ mlir::LLVM::DIFileAttr fileAttr,
+ mlir::LLVM::DIScopeAttr scopeAttr) {
+ mlir::StringAttr varName = declOp->getAttrOfType<StringAttr>("var_name");
+ /*
+ if (auto fusedLoc =
+ mlir::dyn_cast_if_present<mlir::FusedLoc>(declOp.getLoc()))
+ varName = mlir::dyn_cast_if_present<mlir::StringAttr>(
+ fusedLoc.getMetadata());
+ */
+ if (!varName)
+ return;
+
+ mlir::MLIRContext *context = declOp->getContext();
+ mlir::OpBuilder builder(context);
+ builder.setInsertionPointAfter(declOp);
+
+ auto tyAttr =
+ mlir::LLVM::DIBasicTypeAttr::get(context, llvm::dwarf::DW_TAG_base_type,
+ mlir::StringAttr::get(context,
+ "integer"),
+ 256, llvm::dwarf::DW_ATE_unsigned);
+
+ Location loc = declOp->getLoc();
+ auto localVarAttr = mlir::LLVM::DILocalVariableAttr::get(
+ context, scopeAttr, varName,
+ fileAttr, getLineFromLoc(loc), 0, /* alignInBits*/ 0,
+ tyAttr);
+ declOp->setLoc(builder.getFusedLoc({loc}, localVarAttr));
+ builder.create<mlir::LLVM::DbgDeclareOp>(loc, declOp, localVarAttr);
+}
+
+
/// Creates a DISubprogramAttr with the provided compile unit and attaches it
/// to the function. Does nothing when the function already has an attached
/// subprogram.
@@ -81,6 +121,10 @@ static void addScopeToFunction(LLVM::LLVMFuncOp llvmFunc,
/*line=*/line,
/*scopeline=*/col, subprogramFlags, subroutineTypeAttr);
llvmFunc->setLoc(FusedLoc::get(context, {loc}, subprogramAttr));
+
+ llvmFunc.walk([&](mlir::LLVM::AllocaOp declOp) {
+ handleDeclareOp(declOp, fileAttr, subprogramAttr);
+ });
}
namespace {
@@ -117,7 +161,7 @@ struct DIScopeForLLVMFuncOp
compileUnitAttr = LLVM::DICompileUnitAttr::get(
DistinctAttr::create(UnitAttr::get(context)), llvm::dwarf::DW_LANG_C,
fileAttr, StringAttr::get(context, "MLIR"),
- /*isOptimized=*/true, LLVM::DIEmissionKind::LineTablesOnly);
+ /*isOptimized=*/true, LLVM::DIEmissionKind::Full);
}
// Create subprograms for each function with the same distinct compile unit.
The full solution can be based on the flang approach:
- MLIR attributes are generated by reading information from AST
We may need to introduce additional YUL dialect operations that are not involved in code generation, but exist solely for emitting debug records - Adjust debug attributes and generate debug records when converting Standard dialect to LLVM one
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels