diff --git a/flang/include/flang/Optimizer/Passes/Pipelines.h b/flang/include/flang/Optimizer/Passes/Pipelines.h index fd8c43cc88a19..f9c41b382abe5 100644 --- a/flang/include/flang/Optimizer/Passes/Pipelines.h +++ b/flang/include/flang/Optimizer/Passes/Pipelines.h @@ -102,7 +102,7 @@ void addCompilerGeneratedNamesConversionPass(mlir::PassManager &pm); void addDebugInfoPass(mlir::PassManager &pm, llvm::codegenoptions::DebugInfoKind debugLevel, llvm::OptimizationLevel optLevel, - llvm::StringRef inputFilename); + llvm::StringRef inputFilename, int32_t dwarfVersion); void addFIRToLLVMPass(mlir::PassManager &pm, const MLIRToLLVMPassPipelineConfig &config); @@ -158,7 +158,7 @@ void createOpenMPFIRPassPipeline(mlir::PassManager &pm, void createDebugPasses(mlir::PassManager &pm, llvm::codegenoptions::DebugInfoKind debugLevel, llvm::OptimizationLevel OptLevel, - llvm::StringRef inputFilename); + llvm::StringRef inputFilename, int32_t dwarfVersion); 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 e3001454cdf19..b7fa0ca5f5719 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -242,6 +242,10 @@ def AddDebugInfo : Pass<"add-debug-info", "mlir::ModuleOp"> { "std::string", /*default=*/"std::string{}", "name of the input source file">, + Option<"dwarfVersion", "dwarf-version", + "int32_t", + /*default=*/"0", + "dwarf version">, ]; } diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index 335f0a45531c8..038f388f2ec0b 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -108,6 +108,7 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { InstrumentFunctionEntry = "__cyg_profile_func_enter"; InstrumentFunctionExit = "__cyg_profile_func_exit"; } + DwarfVersion = opts.DwarfVersion; } llvm::OptimizationLevel OptLevel; ///< optimisation level @@ -143,6 +144,7 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { Fortran::frontend::CodeGenOptions::ComplexRangeKind ComplexRange = Fortran::frontend::CodeGenOptions::ComplexRangeKind:: CX_Full; ///< Method for calculating complex number division + int32_t DwarfVersion = 0; ///< Version of DWARF debug info to generate }; struct OffloadModuleOpts { diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index a00e568bb4a54..4729f8a7611a2 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -157,10 +157,9 @@ static bool parseDebugArgs(Fortran::frontend::CodeGenOptions &opts, clang::DiagnosticsEngine::Warning, "Unsupported debug option: %0"); diags.Report(debugWarning) << arg->getValue(); } - // The default value of 2 here is to match clang. opts.DwarfVersion = getLastArgIntValue(args, clang::driver::options::OPT_dwarf_version_EQ, - /*Default=*/2, diags); + /*Default=*/0, diags); } return true; } diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp index 7c2777baebef1..58f60d43b1d49 100644 --- a/flang/lib/Optimizer/Passes/Pipelines.cpp +++ b/flang/lib/Optimizer/Passes/Pipelines.cpp @@ -95,11 +95,12 @@ getEmissionKind(llvm::codegenoptions::DebugInfoKind kind) { void addDebugInfoPass(mlir::PassManager &pm, llvm::codegenoptions::DebugInfoKind debugLevel, llvm::OptimizationLevel optLevel, - llvm::StringRef inputFilename) { + llvm::StringRef inputFilename, int32_t dwarfVersion) { fir::AddDebugInfoOptions options; options.debugLevel = getEmissionKind(debugLevel); options.isOptimized = optLevel != llvm::OptimizationLevel::O0; options.inputFilename = inputFilename; + options.dwarfVersion = dwarfVersion; addPassConditionally(pm, disableDebugInfo, [&]() { return fir::createAddDebugInfoPass(options); }); } @@ -333,9 +334,9 @@ void createOpenMPFIRPassPipeline(mlir::PassManager &pm, void createDebugPasses(mlir::PassManager &pm, llvm::codegenoptions::DebugInfoKind debugLevel, llvm::OptimizationLevel OptLevel, - llvm::StringRef inputFilename) { + llvm::StringRef inputFilename, int32_t dwarfVersion) { if (debugLevel != llvm::codegenoptions::NoDebugInfo) - addDebugInfoPass(pm, debugLevel, OptLevel, inputFilename); + addDebugInfoPass(pm, debugLevel, OptLevel, inputFilename, dwarfVersion); } void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm, @@ -352,7 +353,8 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm, fir::addCodeGenRewritePass( pm, (config.DebugInfo != llvm::codegenoptions::NoDebugInfo)); fir::addExternalNameConversionPass(pm, config.Underscoring); - fir::createDebugPasses(pm, config.DebugInfo, config.OptLevel, inputFilename); + fir::createDebugPasses(pm, config.DebugInfo, config.OptLevel, inputFilename, + config.DwarfVersion); fir::addTargetRewritePass(pm); fir::addCompilerGeneratedNamesConversionPass(pm); diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp index 6eb914e67fd54..af96c0be6fae9 100644 --- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp +++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp @@ -649,6 +649,19 @@ void AddDebugInfoPass::runOnOperation() { signalPassFailure(); return; } + mlir::OpBuilder builder(context); + if (dwarfVersion > 0) { + mlir::OpBuilder::InsertionGuard guard(builder); + builder.setInsertionPointToEnd(module.getBody()); + llvm::SmallVector moduleFlags; + mlir::IntegerType int32Ty = mlir::IntegerType::get(context, 32); + moduleFlags.push_back(builder.getAttr( + mlir::LLVM::ModFlagBehavior::Max, + mlir::StringAttr::get(context, "Dwarf Version"), + mlir::IntegerAttr::get(int32Ty, dwarfVersion))); + mlir::LLVM::ModuleFlagsOp::create(builder, module.getLoc(), + builder.getArrayAttr(moduleFlags)); + } fir::DebugTypeGenerator typeGen(module, &symbolTable, *dl); // We need 2 type of file paths here. // 1. Name of the file as was presented to compiler. This can be absolute @@ -686,7 +699,6 @@ void AddDebugInfoPass::runOnOperation() { module.walk([&](mlir::func::FuncOp funcOp) { handleFuncOp(funcOp, fileAttr, cuAttr, typeGen, &symbolTable); }); - mlir::OpBuilder builder(context); // We have processed all function. Attach common block variables to the // global that represent the storage. for (auto [global, exprs] : globalToGlobalExprsMap) { diff --git a/flang/test/Integration/debug-dwarf-flags.f90 b/flang/test/Integration/debug-dwarf-flags.f90 new file mode 100644 index 0000000000000..ac5b1c0d8d4b2 --- /dev/null +++ b/flang/test/Integration/debug-dwarf-flags.f90 @@ -0,0 +1,23 @@ +! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone -dwarf-version=5 %s \ +! RUN: -o - | FileCheck --check-prefix=CHECK-DWARF5 %s +! RUN: %flang_fc1 -emit-llvm -debug-info-kind=line-tables-only -dwarf-version=5 \ +! RUN: %s -o - | FileCheck --check-prefix=CHECK-DWARF5 %s +! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone -dwarf-version=4 %s \ +! RUN: -o - | FileCheck --check-prefix=CHECK-DWARF4 %s +! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone -dwarf-version=3 %s \ +! RUN: -o - | FileCheck --check-prefix=CHECK-DWARF3 %s +! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone -dwarf-version=2 %s \ +! RUN: -o - | FileCheck --check-prefix=CHECK-DWARF2 %s +! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o -\ +! RUN: | FileCheck --check-prefix=CHECK-WITHOUT-VERSION %s +! RUN: %flang_fc1 -emit-llvm -dwarf-version=5 %s -o - \ +! RUN: | FileCheck --check-prefix=CHECK-WITHOUT-VERSION %s + +program test +end program test + +! CHECK-DWARF5: !{i32 7, !"Dwarf Version", i32 5} +! CHECK-DWARF4: !{i32 7, !"Dwarf Version", i32 4} +! CHECK-DWARF3: !{i32 7, !"Dwarf Version", i32 3} +! CHECK-DWARF2: !{i32 7, !"Dwarf Version", i32 2} +! CHECK-WITHOUT-VERSION-NOT: "Dwarf Version" diff --git a/flang/test/Transforms/debug-dwarf-version.fir b/flang/test/Transforms/debug-dwarf-version.fir new file mode 100644 index 0000000000000..fe2700274ab87 --- /dev/null +++ b/flang/test/Transforms/debug-dwarf-version.fir @@ -0,0 +1,21 @@ +// RUN: fir-opt --add-debug-info="dwarf-version=5" --mlir-print-debuginfo %s \ +// RUN: | FileCheck --check-prefix=CHECK-DWARF5 %s +// RUN: fir-opt --add-debug-info="dwarf-version=4" --mlir-print-debuginfo %s \ +// RUN: | FileCheck --check-prefix=CHECK-DWARF4 %s +// RUN: fir-opt --add-debug-info="dwarf-version=3" --mlir-print-debuginfo %s \ +// RUN: | FileCheck --check-prefix=CHECK-DWARF3 %s +// RUN: fir-opt --add-debug-info="dwarf-version=2" --mlir-print-debuginfo %s \ +// RUN: | FileCheck --check-prefix=CHECK-DWARF2 %s +// RUN: fir-opt --add-debug-info= --mlir-print-debuginfo %s \ +// RUN: | FileCheck --check-prefix=CHECK-WITHOUT-VERSION %s +// REQUIRES: system-linux + +module { +} loc(#loc) +#loc = loc("simple.f90":0:0) + +// CHECK-DWARF5: llvm.module_flags [#llvm.mlir.module_flag] +// CHECK-DWARF4: llvm.module_flags [#llvm.mlir.module_flag] +// CHECK-DWARF3: llvm.module_flags [#llvm.mlir.module_flag] +// CHECK-DWARF2: llvm.module_flags [#llvm.mlir.module_flag] +// CHECK-WITHOUT-VERSION-NOT: llvm.module_flags