diff --git a/flang/include/flang/Optimizer/Passes/Pipelines.h b/flang/include/flang/Optimizer/Passes/Pipelines.h index f9c41b382abe5..682dd829239ef 100644 --- a/flang/include/flang/Optimizer/Passes/Pipelines.h +++ b/flang/include/flang/Optimizer/Passes/Pipelines.h @@ -158,7 +158,8 @@ void createOpenMPFIRPassPipeline(mlir::PassManager &pm, void createDebugPasses(mlir::PassManager &pm, llvm::codegenoptions::DebugInfoKind debugLevel, llvm::OptimizationLevel OptLevel, - llvm::StringRef inputFilename, int32_t dwarfVersion); + llvm::StringRef inputFilename, int32_t dwarfVersion, + llvm::StringRef splitDwarfFile); void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm, MLIRToLLVMPassPipelineConfig config, diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index 88573fa9dff7d..e2ba9c3522837 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -246,6 +246,10 @@ def AddDebugInfo : Pass<"add-debug-info", "mlir::ModuleOp"> { "int32_t", /*default=*/"0", "dwarf version">, + Option<"splitDwarfFile", "split-dwarf-file", + "std::string", /*default=*/"std::string{}", + "Name of the split dwarf file"> + ]; } diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index 01c34eee014f3..850bd1f0940f7 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -109,6 +109,7 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { InstrumentFunctionExit = "__cyg_profile_func_exit"; } DwarfVersion = opts.DwarfVersion; + SplitDwarfFile = opts.SplitDwarfFile; } llvm::OptimizationLevel OptLevel; ///< optimisation level @@ -146,6 +147,7 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { Fortran::frontend::CodeGenOptions::ComplexRangeKind:: CX_Full; ///< Method for calculating complex number division int32_t DwarfVersion = 0; ///< Version of DWARF debug info to generate + std::string SplitDwarfFile = ""; ///< File name for the split debug info }; struct OffloadModuleOpts { diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp index c089941688352..a83b0665eaf1f 100644 --- a/flang/lib/Optimizer/Passes/Pipelines.cpp +++ b/flang/lib/Optimizer/Passes/Pipelines.cpp @@ -95,12 +95,14 @@ getEmissionKind(llvm::codegenoptions::DebugInfoKind kind) { void addDebugInfoPass(mlir::PassManager &pm, llvm::codegenoptions::DebugInfoKind debugLevel, llvm::OptimizationLevel optLevel, - llvm::StringRef inputFilename, int32_t dwarfVersion) { + llvm::StringRef inputFilename, int32_t dwarfVersion, + llvm::StringRef splitDwarfFile) { fir::AddDebugInfoOptions options; options.debugLevel = getEmissionKind(debugLevel); options.isOptimized = optLevel != llvm::OptimizationLevel::O0; options.inputFilename = inputFilename; options.dwarfVersion = dwarfVersion; + options.splitDwarfFile = splitDwarfFile; addPassConditionally(pm, disableDebugInfo, [&]() { return fir::createAddDebugInfoPass(options); }); } @@ -340,9 +342,11 @@ void createOpenMPFIRPassPipeline(mlir::PassManager &pm, void createDebugPasses(mlir::PassManager &pm, llvm::codegenoptions::DebugInfoKind debugLevel, llvm::OptimizationLevel OptLevel, - llvm::StringRef inputFilename, int32_t dwarfVersion) { + llvm::StringRef inputFilename, int32_t dwarfVersion, + llvm::StringRef splitDwarfFile) { if (debugLevel != llvm::codegenoptions::NoDebugInfo) - addDebugInfoPass(pm, debugLevel, OptLevel, inputFilename, dwarfVersion); + addDebugInfoPass(pm, debugLevel, OptLevel, inputFilename, dwarfVersion, + splitDwarfFile); } void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm, @@ -360,7 +364,7 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm, pm, (config.DebugInfo != llvm::codegenoptions::NoDebugInfo)); fir::addExternalNameConversionPass(pm, config.Underscoring); fir::createDebugPasses(pm, config.DebugInfo, config.OptLevel, inputFilename, - config.DwarfVersion); + config.DwarfVersion, config.SplitDwarfFile); fir::addTargetRewritePass(pm); fir::addCompilerGeneratedNamesConversionPass(pm); diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp index bc6592dd72078..bdf7e4a366cf1 100644 --- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp +++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp @@ -696,7 +696,8 @@ void AddDebugInfoPass::runOnOperation() { llvm::dwarf::getLanguage("DW_LANG_Fortran95"), fileAttr, producer, isOptimized, debugLevel, /*nameTableKind=*/mlir::LLVM::DINameTableKind::Default, - /*splitDebugFilename=*/mlir::StringAttr()); + splitDwarfFile.empty() ? mlir::StringAttr() + : mlir::StringAttr::get(context, splitDwarfFile)); module.walk([&](mlir::func::FuncOp funcOp) { handleFuncOp(funcOp, fileAttr, cuAttr, typeGen, &symbolTable); diff --git a/flang/test/Integration/debug-split-dwarf.f90 b/flang/test/Integration/debug-split-dwarf.f90 index 60373efddc358..ebfa040a42632 100644 --- a/flang/test/Integration/debug-split-dwarf.f90 +++ b/flang/test/Integration/debug-split-dwarf.f90 @@ -2,20 +2,28 @@ ! Testing to ensure that setting only -split-dwarf-file allows to place ! .dwo sections into regular output object. -! RUN: %flang_fc1 -debug-info-kind=standalone -triple x86_64-unknown-linux \ -! RUN: -split-dwarf-file %t.o -emit-obj -o %t.o %s -! RUN: llvm-readobj -S %t.o | FileCheck --check-prefix=DWO %s +! RUN: %flang_fc1 -debug-info-kind=standalone -triple x86_64-unknown-linux \ +! RUN: -split-dwarf-file %t.o -emit-obj -o %t.o %s +! RUN: llvm-readobj -S %t.o | FileCheck --check-prefix=DWO %s ! Testing to ensure that setting both -split-dwarf-file and -split-dwarf-output ! does not place .dwo sections into regular output object but in a separate ! file. -! RUN: %flang_fc1 -debug-info-kind=standalone -triple x86_64-unknown-linux \ -! RUN: -split-dwarf-file %t.dwo -split-dwarf-output %t.dwo -emit-obj -o %t.o %s -! RUN: llvm-readobj -S %t.dwo | FileCheck --check-prefix=DWO %s -! RUN: llvm-readobj -S %t.o | FileCheck --check-prefix=SPLIT %s +! RUN: %flang_fc1 -debug-info-kind=standalone -triple x86_64-unknown-linux \ +! RUN: -split-dwarf-file %t.dwo -split-dwarf-output %t.dwo -emit-obj -o %t.o %s +! RUN: llvm-readobj -S %t.dwo | FileCheck --check-prefix=DWO %s +! RUN: llvm-readobj -S %t.o | FileCheck --check-prefix=SPLIT %s -! DWO: .dwo -! SPLIT-NOT: .dwo +! Test that splitDebugFilename field of the DICompileUnit get correctly +! generated. +! RUN: %flang_fc1 -debug-info-kind=standalone -triple x86_64-unknown-linux \ +! RUN: -split-dwarf-file %t.test_dwo -split-dwarf-output %t.test_dwo \ +! RUN: -emit-llvm %s -o - | FileCheck --check-prefix=CU %s + +! DWO: .dwo +! SPLIT-NOT: .dwo +! CU: !DICompileUnit +! CU-SAME: splitDebugFilename: "{{.*}}test_dwo" program test end program test diff --git a/flang/test/Transforms/debug-split-dwarf.fir b/flang/test/Transforms/debug-split-dwarf.fir new file mode 100644 index 0000000000000..9c095457fb117 --- /dev/null +++ b/flang/test/Transforms/debug-split-dwarf.fir @@ -0,0 +1,12 @@ +// RUN: fir-opt --add-debug-info="split-dwarf-file=test.dwo" \ +// RUN: --mlir-print-debuginfo %s -o - | FileCheck %s + +module { + func.func @test() { + return + } loc(#loc1) +} +#loc1 = loc("test.f90":15:1) + +// CHECK: llvm.di_compile_unit +// CHECK-SAME: splitDebugFilename = "test.dwo"