https://github.com/cyyself updated https://github.com/llvm/llvm-project/pull/181686
>From d3c8fbfb4528726349e255ec8c1ebad7b1c7fc9b Mon Sep 17 00:00:00 2001 From: Yangyu Chen <[email protected]> Date: Mon, 16 Feb 2026 23:25:54 +0800 Subject: [PATCH] [flang] Implement -grecord-command-line for Flang Enable Flang to match Clang behavior for command-line recording in DWARF producer strings when using -grecord-command-line. Signed-off-by: Yangyu Chen <[email protected]> --- clang/include/clang/Options/Options.td | 12 ++++++----- flang/include/flang/Frontend/CodeGenOptions.h | 5 +++++ .../flang/Optimizer/Passes/Pipelines.h | 7 +++++-- .../flang/Optimizer/Transforms/Passes.td | 5 ++++- flang/include/flang/Tools/CrossToolHelpers.h | 2 ++ flang/lib/Frontend/CompilerInvocation.cpp | 5 +++++ flang/lib/Optimizer/Passes/Pipelines.cpp | 12 +++++++---- .../lib/Optimizer/Transforms/AddDebugInfo.cpp | 8 ++++++-- flang/test/Driver/grecord-command-line.f90 | 14 +++++++++++++ .../Transforms/debug-dwarf-debug-flags.fir | 20 +++++++++++++++++++ 10 files changed, 76 insertions(+), 14 deletions(-) create mode 100644 flang/test/Driver/grecord-command-line.f90 create mode 100644 flang/test/Transforms/debug-dwarf-debug-flags.fir diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index a274017953b1d..11c56d6eb519b 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -4938,9 +4938,11 @@ def gxcoff : Joined<["-"], "gxcoff">, Group<g_Group>, Flags<[Unsupported]>; def gvms : Joined<["-"], "gvms">, Group<g_Group>, Flags<[Unsupported]>; def gtoggle : Flag<["-"], "gtoggle">, Group<g_flags_Group>, Flags<[Unsupported]>; def grecord_command_line : Flag<["-"], "grecord-command-line">, - Group<g_flags_Group>; + Group<g_flags_Group>, + Visibility<[ClangOption, FlangOption]>; def gno_record_command_line : Flag<["-"], "gno-record-command-line">, - Group<g_flags_Group>; + Group<g_flags_Group>, + Visibility<[ClangOption, FlangOption]>; def : Flag<["-"], "grecord-gcc-switches">, Alias<grecord_command_line>; def : Flag<["-"], "gno-record-gcc-switches">, Alias<gno_record_command_line>; defm strict_dwarf : BoolOption<"g", "strict-dwarf", @@ -7887,6 +7889,9 @@ def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">; def record_command_line : Separate<["-"], "record-command-line">, HelpText<"The string to embed in the .LLVM.command.line section.">, MarshallingInfoString<CodeGenOpts<"RecordCommandLine">>; +def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">, + HelpText<"The string to embed in the Dwarf debug flags record.">, + MarshallingInfoString<CodeGenOpts<"DwarfDebugFlags">>; def dwarf_version_EQ : Joined<["-"], "dwarf-version=">, MarshallingInfoInt<CodeGenOpts<"DwarfVersion">>; @@ -7908,9 +7913,6 @@ def debugger_tuning_EQ : Joined<["-"], "debugger-tuning=">, Values<"gdb,lldb,sce,dbx">, NormalizedValuesScope<"llvm::DebuggerKind">, NormalizedValues<["GDB", "LLDB", "SCE", "DBX"]>, MarshallingInfoEnum<CodeGenOpts<"DebuggerTuning">, "Default">; -def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">, - HelpText<"The string to embed in the Dwarf debug flags record.">, - MarshallingInfoString<CodeGenOpts<"DwarfDebugFlags">>; def compress_debug_sections_EQ : Joined<["-", "--"], "compress-debug-sections=">, HelpText<"DWARF debug sections compression type">, Values<"none,zlib,zstd">, NormalizedValuesScope<"llvm::DebugCompressionType">, NormalizedValues<["None", "Zlib", "Zstd"]>, diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h index 3dca169d43b39..5a141e3c0a87d 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -73,6 +73,11 @@ class CodeGenOptions : public CodeGenOptionsBase { /// The string containing the commandline for the llvm.commandline metadata. std::optional<std::string> RecordCommandLine; + /// The value from -dwarf-debug-flags to append to DW_AT_producer. + /// This is typically a reconstructed user command line (e.g. from + /// -grecord-command-line) and may contain multiple space-separated flags. + std::string DwarfDebugFlags; + /// The name of the file to which the backend should save YAML optimization /// records. std::string OptRecordFile; diff --git a/flang/include/flang/Optimizer/Passes/Pipelines.h b/flang/include/flang/Optimizer/Passes/Pipelines.h index 1a7ff4ff3dfa2..8f2ff5f82299d 100644 --- a/flang/include/flang/Optimizer/Passes/Pipelines.h +++ b/flang/include/flang/Optimizer/Passes/Pipelines.h @@ -103,7 +103,9 @@ void addCompilerGeneratedNamesConversionPass(mlir::PassManager &pm); 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, + llvm::StringRef dwarfDebugFlags); /// Create FIRToLLVMPassOptions from pipeline configuration. FIRToLLVMPassOptions @@ -164,7 +166,8 @@ void createDebugPasses(mlir::PassManager &pm, llvm::codegenoptions::DebugInfoKind debugLevel, llvm::OptimizationLevel OptLevel, llvm::StringRef inputFilename, int32_t dwarfVersion, - llvm::StringRef splitDwarfFile); + llvm::StringRef splitDwarfFile, + llvm::StringRef dwarfDebugFlags); 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 d812e271b158d..bdee252d14c72 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -260,7 +260,10 @@ def AddDebugInfo : Pass<"add-debug-info", "mlir::ModuleOp"> { "dwarf version">, Option<"splitDwarfFile", "split-dwarf-file", "std::string", /*default=*/"std::string{}", - "Name of the split dwarf file"> + "Name of the split dwarf file">, + Option<"dwarfDebugFlags", "dwarf-debug-flags", + "std::string", /*default=*/"std::string{}", + "Command-line flags to append to DWARF producer"> ]; } diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index 44fb252d2b366..f29fc8ef0ea56 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -110,6 +110,7 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { } DwarfVersion = opts.DwarfVersion; SplitDwarfFile = opts.SplitDwarfFile; + DwarfDebugFlags = opts.DwarfDebugFlags; } llvm::OptimizationLevel OptLevel; ///< optimisation level @@ -148,6 +149,7 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { 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 + std::string DwarfDebugFlags = ""; ///< Debug flags to append to DWARF producer }; struct OffloadModuleOpts { diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index fc4975f9592eb..72b766e52ab3b 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -165,6 +165,11 @@ static bool parseDebugArgs(Fortran::frontend::CodeGenOptions &opts, args.getLastArg(clang::options::OPT_split_dwarf_output)) opts.SplitDwarfOutput = a->getValue(); } + + if (const llvm::opt::Arg *arg = + args.getLastArg(clang::options::OPT_dwarf_debug_flags)) + opts.DwarfDebugFlags = arg->getValue(); + return true; } diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp index 9b73d587ee7bc..64e925c0a4922 100644 --- a/flang/lib/Optimizer/Passes/Pipelines.cpp +++ b/flang/lib/Optimizer/Passes/Pipelines.cpp @@ -97,13 +97,15 @@ void addDebugInfoPass(mlir::PassManager &pm, llvm::codegenoptions::DebugInfoKind debugLevel, llvm::OptimizationLevel optLevel, llvm::StringRef inputFilename, int32_t dwarfVersion, - llvm::StringRef splitDwarfFile) { + llvm::StringRef splitDwarfFile, + llvm::StringRef dwarfDebugFlags) { fir::AddDebugInfoOptions options; options.debugLevel = getEmissionKind(debugLevel); options.isOptimized = optLevel != llvm::OptimizationLevel::O0; options.inputFilename = inputFilename; options.dwarfVersion = dwarfVersion; options.splitDwarfFile = splitDwarfFile; + options.dwarfDebugFlags = dwarfDebugFlags; addPassConditionally(pm, disableDebugInfo, [&]() { return fir::createAddDebugInfoPass(options); }); } @@ -362,10 +364,11 @@ void createDebugPasses(mlir::PassManager &pm, llvm::codegenoptions::DebugInfoKind debugLevel, llvm::OptimizationLevel OptLevel, llvm::StringRef inputFilename, int32_t dwarfVersion, - llvm::StringRef splitDwarfFile) { + llvm::StringRef splitDwarfFile, + llvm::StringRef dwarfDebugFlags) { if (debugLevel != llvm::codegenoptions::NoDebugInfo) addDebugInfoPass(pm, debugLevel, OptLevel, inputFilename, dwarfVersion, - splitDwarfFile); + splitDwarfFile, dwarfDebugFlags); } void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm, @@ -384,7 +387,8 @@ 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.SplitDwarfFile); + config.DwarfVersion, config.SplitDwarfFile, + config.DwarfDebugFlags); fir::addTargetRewritePass(pm); fir::addCompilerGeneratedNamesConversionPass(pm); diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp index 35d8a2f6c3aa9..8f712ab5fe262 100644 --- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp +++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp @@ -861,8 +861,12 @@ void AddDebugInfoPass::runOnOperation() { mlir::LLVM::DIFileAttr fileAttr = mlir::LLVM::DIFileAttr::get(context, fileName, filePath); - mlir::StringAttr producer = - mlir::StringAttr::get(context, Fortran::common::getFlangFullVersion()); + // Match Clang style by starting with the full compiler version and + // appending -dwarf-debug-flags content when provided. + std::string producerString = Fortran::common::getFlangFullVersion(); + if (!dwarfDebugFlags.empty()) + producerString += " " + dwarfDebugFlags; + mlir::StringAttr producer = mlir::StringAttr::get(context, producerString); mlir::LLVM::DICompileUnitAttr cuAttr = mlir::LLVM::DICompileUnitAttr::get( mlir::DistinctAttr::create(mlir::UnitAttr::get(context)), llvm::dwarf::getLanguage("DW_LANG_Fortran95"), fileAttr, producer, diff --git a/flang/test/Driver/grecord-command-line.f90 b/flang/test/Driver/grecord-command-line.f90 new file mode 100644 index 0000000000000..269381e464e7d --- /dev/null +++ b/flang/test/Driver/grecord-command-line.f90 @@ -0,0 +1,14 @@ +! This checks that -grecord-command-line is forwarded by the flang driver to +! an FC1 -dwarf-debug-flags argument and that -gno-record-command-line +! disables it, matching clang behavior. +! +! RUN: %flang -### -grecord-command-line %s 2>&1 | FileCheck --check-prefix=GRECORD %s +! RUN: %flang -### -gno-record-command-line %s 2>&1 | FileCheck --check-prefix=GNO_RECORD %s +! RUN: %flang -### -grecord-command-line -gno-record-command-line %s 2>&1 | FileCheck --check-prefix=GNO_RECORD %s +! +! GRECORD: "-dwarf-debug-flags" +! +! GNO_RECORD-NOT: "-dwarf-debug-flags" + +program p +end program p diff --git a/flang/test/Transforms/debug-dwarf-debug-flags.fir b/flang/test/Transforms/debug-dwarf-debug-flags.fir new file mode 100644 index 0000000000000..e3b43508a6a89 --- /dev/null +++ b/flang/test/Transforms/debug-dwarf-debug-flags.fir @@ -0,0 +1,20 @@ +// Test the dwarf-debug-flags option will passed to MLIR correctly and show +// up in the generated debug info. +// RUN: fir-opt --add-debug-info="debug-level=Full" --mlir-print-debuginfo %s \ +// RUN: | FileCheck --check-prefix=CHECK-NO-FLAGS %s +// RUN: fir-opt --add-debug-info="debug-level=Full dwarf-debug-flags=\"-grecord-command-line -O2\"" \ +// RUN: --mlir-print-debuginfo %s | FileCheck --check-prefix=CHECK-FLAGS %s + +module { + func.func @_QPs() { + return loc(#loc_s) + } loc(#loc_s) +} loc(#loc_module) +#loc_module = loc("simple.f90":1:1) +#loc_s = loc("simple.f90":2:1) + +// CHECK-NO-FLAGS: #llvm.di_compile_unit< +// CHECK-NO-FLAGS-SAME: producer = "{{.*}}flang{{.*}}" + +// CHECK-FLAGS: #llvm.di_compile_unit< +// CHECK-FLAGS-SAME: producer = "{{.*}} -grecord-command-line -O2" _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
