[MLIR][LLVM] Enable export of DISubprograms on function declarations (#78026)

This commit changes the MLIR to LLVMIR export to also attach subprogram
debug attachements to function declarations.
This commit additonally fixes the two passes that produce subprograms to
not attach the "Definition" flag to function declarations. This
otherwise results in invalid LLVM IR.
This commit is contained in:
Christian Ulmann 2024-01-15 07:34:13 +01:00 committed by GitHub
parent 148e55c230
commit fa5255eee2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 15 deletions

View File

@ -97,16 +97,18 @@ void AddDebugFoundationPass::runOnOperation() {
// Only definitions need a distinct identifier and a compilation unit.
mlir::DistinctAttr id;
mlir::LLVM::DICompileUnitAttr compilationUnit;
auto subprogramFlags = mlir::LLVM::DISubprogramFlags::Optimized;
if (!funcOp.isExternal()) {
id = mlir::DistinctAttr::create(mlir::UnitAttr::get(context));
compilationUnit = cuAttr;
subprogramFlags =
subprogramFlags | mlir::LLVM::DISubprogramFlags::Definition;
}
mlir::LLVM::DISubprogramAttr spAttr = mlir::LLVM::DISubprogramAttr::get(
auto spAttr = mlir::LLVM::DISubprogramAttr::get(
context, id, compilationUnit, fileAttr, funcName, funcName,
funcFileAttr,
/*line=*/1,
/*scopeline=*/1, mlir::LLVM::DISubprogramFlags::Definition,
subTypeAttr);
/*scopeline=*/1, subprogramFlags, subTypeAttr);
funcOp->setLoc(builder.getFusedLoc({funcOp->getLoc()}, spAttr));
});
}

View File

@ -24,7 +24,7 @@ module attributes { fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.dat
// CHECK: #[[DECL_LOC:.*]] = loc("./simple.f90":10:1)
// CHECK: #di_compile_unit = #llvm.di_compile_unit<id = distinct[{{.*}}]<>, sourceLanguage = DW_LANG_Fortran95, file = #di_file, producer = "Flang", isOptimized = false, emissionKind = LineTablesOnly>
// CHECK: #di_subroutine_type = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #di_basic_type, #di_basic_type>
// CHECK: #[[SB_SUBPROGRAM:.*]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #di_compile_unit, scope = #di_file, name = "[[SB_NAME]]", linkageName = "[[SB_NAME]]", file = #di_file, line = 1, scopeLine = 1, subprogramFlags = Definition, type = #di_subroutine_type>
// CHECK: #[[DECL_SUBPROGRAM:.*]] = #llvm.di_subprogram<scope = #di_file, name = "[[DECL_NAME]]", linkageName = "[[DECL_NAME]]", file = #di_file, line = 1, scopeLine = 1, subprogramFlags = Definition, type = #di_subroutine_type>
// CHECK: #[[SB_SUBPROGRAM:.*]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #di_compile_unit, scope = #di_file, name = "[[SB_NAME]]", linkageName = "[[SB_NAME]]", file = #di_file, line = 1, scopeLine = 1, subprogramFlags = "Definition|Optimized", type = #di_subroutine_type>
// CHECK: #[[DECL_SUBPROGRAM:.*]] = #llvm.di_subprogram<scope = #di_file, name = "[[DECL_NAME]]", linkageName = "[[DECL_NAME]]", file = #di_file, line = 1, scopeLine = 1, subprogramFlags = Optimized, type = #di_subroutine_type>
// CHECK: #[[FUSED_SB_LOC]] = loc(fused<#[[SB_SUBPROGRAM]]>[#[[SB_LOC]]])
// CHECK: #[[FUSED_DECL_LOC]] = loc(fused<#[[DECL_SUBPROGRAM]]>[#[[DECL_LOC]]])

View File

@ -67,18 +67,19 @@ static void addScopeToFunction(LLVM::LLVMFuncOp llvmFunc,
StringAttr funcNameAttr = llvmFunc.getNameAttr();
// Only definitions need a distinct identifier and a compilation unit.
mlir::DistinctAttr id;
if (!llvmFunc.isExternal())
DistinctAttr id;
auto subprogramFlags = LLVM::DISubprogramFlags::Optimized;
if (!llvmFunc.isExternal()) {
id = mlir::DistinctAttr::create(mlir::UnitAttr::get(context));
else
subprogramFlags = subprogramFlags | LLVM::DISubprogramFlags::Definition;
} else {
compileUnitAttr = {};
mlir::LLVM::DISubprogramAttr subprogramAttr = LLVM::DISubprogramAttr::get(
}
auto subprogramAttr = LLVM::DISubprogramAttr::get(
context, id, compileUnitAttr, fileAttr, funcNameAttr, funcNameAttr,
fileAttr,
/*line=*/line,
/*scopeline=*/col,
LLVM::DISubprogramFlags::Definition | LLVM::DISubprogramFlags::Optimized,
subroutineTypeAttr);
/*scopeline=*/col, subprogramFlags, subroutineTypeAttr);
llvmFunc->setLoc(FusedLoc::get(context, {loc}, subprogramAttr));
}

View File

@ -1074,9 +1074,6 @@ LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) {
branchMapping.clear();
llvm::Function *llvmFunc = lookupFunction(func.getName());
// Translate the debug information for this function.
debugTranslation->translate(func, *llvmFunc);
// Add function arguments to the value remapping table.
for (auto [mlirArg, llvmArg] :
llvm::zip(func.getArguments(), llvmFunc->args()))
@ -1261,6 +1258,9 @@ LogicalResult ModuleTranslation::convertFunctionSignatures() {
if (auto alignment = function.getAlignment())
llvmFunc->setAlignment(llvm::MaybeAlign(*alignment));
// Translate the debug information for this function.
debugTranslation->translate(function, *llvmFunc);
}
return success();

View File

@ -169,6 +169,20 @@ llvm.func @empty_types() {
// -----
#di_file = #llvm.di_file<"foo.mlir" in "/test/">
#di_subprogram = #llvm.di_subprogram<
scope = #di_file, name = "func_decl_with_subprogram", file = #di_file, subprogramFlags = "Optimized"
>
// CHECK-LABEL: declare !dbg
// CHECK-SAME: ![[SUBPROGRAM:.*]] i32 @func_decl_with_subprogram(
llvm.func @func_decl_with_subprogram() -> (i32) loc(fused<#di_subprogram>["foo.mlir":2:1])
// CHECK: ![[SUBPROGRAM]] = !DISubprogram(name: "func_decl_with_subprogram", scope: ![[FILE:.*]], file: ![[FILE]], spFlags: DISPFlagOptimized)
// CHECK: ![[FILE]] = !DIFile(filename: "foo.mlir", directory: "/test/")
// -----
#di_basic_type = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int", sizeInBits = 32, encoding = DW_ATE_signed>
#di_file = #llvm.di_file<"foo.mlir" in "/test/">
#di_compile_unit = #llvm.di_compile_unit<