https://github.com/abidh updated https://github.com/llvm/llvm-project/pull/160540
>From e2876ad56fa614c2b6cf9bbfb8a151ac1911d6c3 Mon Sep 17 00:00:00 2001 From: Abid Qadeer <haqad...@amd.com> Date: Tue, 23 Sep 2025 19:28:15 +0100 Subject: [PATCH 1/3] [flang][Driver] Support -gsplit-dwarf. I have tried to follow the logic of the clang implementation where possible. Some functions were moved where they could be used by both clang and flang. The `addOtherOptions` was renamed to `addDebugOptions` to better reflect its purpose. The clang also set the splitDebugFilename field of the DICompileUnit in the IR when this option is present. That part is currently missing from this patch and it will come in a follow-up PR. --- clang/include/clang/Driver/CommonArgs.h | 10 ++++ clang/include/clang/Driver/Options.td | 15 +++--- clang/lib/Driver/ToolChains/Clang.cpp | 31 ----------- clang/lib/Driver/ToolChains/Clang.h | 6 --- clang/lib/Driver/ToolChains/CommonArgs.cpp | 31 +++++++++++ clang/lib/Driver/ToolChains/Flang.cpp | 51 +++++++++++++++++-- clang/lib/Driver/ToolChains/Flang.h | 8 ++- flang/include/flang/Frontend/CodeGenOptions.h | 7 +++ flang/lib/Frontend/CompilerInvocation.cpp | 6 +++ flang/lib/Frontend/FrontendActions.cpp | 18 ++++++- flang/test/Driver/split-debug.f90 | 43 ++++++++++++++++ flang/test/Integration/debug-split-dwarf.f90 | 21 ++++++++ 12 files changed, 195 insertions(+), 52 deletions(-) create mode 100644 flang/test/Driver/split-debug.f90 create mode 100644 flang/test/Integration/debug-split-dwarf.f90 diff --git a/clang/include/clang/Driver/CommonArgs.h b/clang/include/clang/Driver/CommonArgs.h index 1464ce4e1b31b..40ae40665b040 100644 --- a/clang/include/clang/Driver/CommonArgs.h +++ b/clang/include/clang/Driver/CommonArgs.h @@ -105,6 +105,16 @@ unsigned DwarfVersionNum(StringRef ArgValue); const llvm::opt::Arg *getDwarfNArg(const llvm::opt::ArgList &Args); unsigned getDwarfVersion(const ToolChain &TC, const llvm::opt::ArgList &Args); +enum class DwarfFissionKind { None, Split, Single }; + +DwarfFissionKind getDebugFissionKind(const Driver &D, + const llvm::opt::ArgList &Args, + llvm::opt::Arg *&Arg); + +bool checkDebugInfoOption(const llvm::opt::Arg *A, + const llvm::opt::ArgList &Args, const Driver &D, + const ToolChain &TC); + void AddAssemblerKPIC(const ToolChain &ToolChain, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs); diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 16e1c396fedbe..61fd0fa3794ee 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4754,13 +4754,13 @@ defm column_info : BoolOption<"g", "column-info", PosFlag<SetTrue>, BothFlags<[], [ClangOption, CLOption, DXCOption]>>, Group<g_flags_Group>; def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group<g_flags_Group>, - Visibility<[ClangOption, CLOption, DXCOption]>; + Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>; def gsplit_dwarf_EQ : Joined<["-"], "gsplit-dwarf=">, Group<g_flags_Group>, - Visibility<[ClangOption, CLOption, DXCOption]>, + Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, HelpText<"Set DWARF fission mode">, Values<"split,single">; def gno_split_dwarf : Flag<["-"], "gno-split-dwarf">, Group<g_flags_Group>, - Visibility<[ClangOption, CLOption, DXCOption]>; + Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>; def gtemplate_alias : Flag<["-"], "gtemplate-alias">, Group<g_flags_Group>, Visibility<[ClangOption, CC1Option]>; def gno_template_alias : Flag<["-"], "gno-template-alias">, Group<g_flags_Group>, Visibility<[ClangOption]>; def gsimple_template_names : Flag<["-"], "gsimple-template-names">, Group<g_flags_Group>; @@ -8405,7 +8405,7 @@ def main_file_name : Separate<["-"], "main-file-name">, MarshallingInfoString<CodeGenOpts<"MainFileName">>; def split_dwarf_output : Separate<["-"], "split-dwarf-output">, HelpText<"File name to use for split dwarf debug info output">, - Visibility<[CC1Option, CC1AsOption]>, + Visibility<[CC1Option, CC1AsOption, FC1Option]>, MarshallingInfoString<CodeGenOpts<"SplitDwarfOutput">>; let Visibility = [CC1Option, FC1Option] in { @@ -8437,6 +8437,10 @@ def dependent_lib : Joined<["--"], "dependent-lib=">, HelpText<"Add dependent library">, MarshallingInfoStringVector<CodeGenOpts<"DependentLibraries">>; +def split_dwarf_file : Separate<["-"], "split-dwarf-file">, + HelpText<"Name of the split dwarf debug info file to encode in the object file">, + MarshallingInfoString<CodeGenOpts<"SplitDwarfFile">>; + } // let Visibility = [CC1Option, FC1Option] let Visibility = [CC1Option] in { @@ -8447,9 +8451,6 @@ def fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">, def fexternc_nounwind : Flag<["-"], "fexternc-nounwind">, HelpText<"Assume all functions with C linkage do not unwind">, MarshallingInfoFlag<LangOpts<"ExternCNoUnwind">>; -def split_dwarf_file : Separate<["-"], "split-dwarf-file">, - HelpText<"Name of the split dwarf debug info file to encode in the object file">, - MarshallingInfoString<CodeGenOpts<"SplitDwarfFile">>; def fno_wchar : Flag<["-"], "fno-wchar">, HelpText<"Disable C++ builtin type wchar_t">, MarshallingInfoNegativeFlag<LangOpts<"WChar">, cplusplus.KeyPath>, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index e7aabee273a34..43cf8f54e272e 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -695,16 +695,6 @@ RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs, } } -static bool checkDebugInfoOption(const Arg *A, const ArgList &Args, - const Driver &D, const ToolChain &TC) { - assert(A && "Expected non-nullptr argument."); - if (TC.supportsDebugInfoOption(A)) - return true; - D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target) - << A->getAsString(Args) << TC.getTripleString(); - return false; -} - static void RenderDebugInfoCompressionArgs(const ArgList &Args, ArgStringList &CmdArgs, const Driver &D, @@ -4327,27 +4317,6 @@ static void RenderDiagnosticsOptions(const Driver &D, const ArgList &Args, Args.addLastArg(CmdArgs, options::OPT_warning_suppression_mappings_EQ); } -DwarfFissionKind tools::getDebugFissionKind(const Driver &D, - const ArgList &Args, Arg *&Arg) { - Arg = Args.getLastArg(options::OPT_gsplit_dwarf, options::OPT_gsplit_dwarf_EQ, - options::OPT_gno_split_dwarf); - if (!Arg || Arg->getOption().matches(options::OPT_gno_split_dwarf)) - return DwarfFissionKind::None; - - if (Arg->getOption().matches(options::OPT_gsplit_dwarf)) - return DwarfFissionKind::Split; - - StringRef Value = Arg->getValue(); - if (Value == "split") - return DwarfFissionKind::Split; - if (Value == "single") - return DwarfFissionKind::Single; - - D.Diag(diag::err_drv_unsupported_option_argument) - << Arg->getSpelling() << Arg->getValue(); - return DwarfFissionKind::None; -} - static void renderDwarfFormat(const Driver &D, const llvm::Triple &T, const ArgList &Args, ArgStringList &CmdArgs, unsigned DwarfVersion) { diff --git a/clang/lib/Driver/ToolChains/Clang.h b/clang/lib/Driver/ToolChains/Clang.h index 18f6c5ed06a59..c22789591e00a 100644 --- a/clang/lib/Driver/ToolChains/Clang.h +++ b/clang/lib/Driver/ToolChains/Clang.h @@ -187,12 +187,6 @@ class LLVM_LIBRARY_VISIBILITY LinkerWrapper final : public Tool { const char *LinkingOutput) const override; }; -enum class DwarfFissionKind { None, Split, Single }; - -DwarfFissionKind getDebugFissionKind(const Driver &D, - const llvm::opt::ArgList &Args, - llvm::opt::Arg *&Arg); - // Calculate the output path of the module file when compiling a module unit // with the `-fmodule-output` option or `-fmodule-output=` option specified. // The behavior is: diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 08cd98fd04df0..4902c2f3c0cbe 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -2270,6 +2270,37 @@ unsigned tools::getDwarfVersion(const ToolChain &TC, return DwarfVersion; } +DwarfFissionKind tools::getDebugFissionKind(const Driver &D, + const ArgList &Args, Arg *&Arg) { + Arg = Args.getLastArg(options::OPT_gsplit_dwarf, options::OPT_gsplit_dwarf_EQ, + options::OPT_gno_split_dwarf); + if (!Arg || Arg->getOption().matches(options::OPT_gno_split_dwarf)) + return DwarfFissionKind::None; + + if (Arg->getOption().matches(options::OPT_gsplit_dwarf)) + return DwarfFissionKind::Split; + + StringRef Value = Arg->getValue(); + if (Value == "split") + return DwarfFissionKind::Split; + if (Value == "single") + return DwarfFissionKind::Single; + + D.Diag(diag::err_drv_unsupported_option_argument) + << Arg->getSpelling() << Arg->getValue(); + return DwarfFissionKind::None; +} + +bool tools::checkDebugInfoOption(const Arg *A, const ArgList &Args, + const Driver &D, const ToolChain &TC) { + assert(A && "Expected non-nullptr argument."); + if (TC.supportsDebugInfoOption(A)) + return true; + D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target) + << A->getAsString(Args) << TC.getTripleString(); + return false; +} + void tools::AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args, ArgStringList &CmdArgs) { llvm::Reloc::Model RelocationModel; diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 6fc372eb75eb7..3e8444c151f36 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -120,7 +120,11 @@ static bool shouldLoopVersion(const ArgList &Args) { return false; } -void Flang::addOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const { +void Flang::addDebugOptions(const llvm::opt::ArgList &Args, const JobAction &JA, + const InputInfo &Output, const InputInfo &Input, + llvm::opt::ArgStringList &CmdArgs) const { + const auto &TC = getToolChain(); + const Driver &D = TC.getDriver(); Args.addAllArgs(CmdArgs, {options::OPT_module_dir, options::OPT_fdebug_module_writer, options::OPT_fintrinsic_modules_path, options::OPT_pedantic, @@ -131,20 +135,57 @@ void Flang::addOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const { options::OPT_finstrument_functions}); llvm::codegenoptions::DebugInfoKind DebugInfoKind; + bool hasDwarfNArg = getDwarfNArg(Args) != nullptr; if (Args.hasArg(options::OPT_gN_Group)) { Arg *gNArg = Args.getLastArg(options::OPT_gN_Group); DebugInfoKind = debugLevelToInfoKind(*gNArg); - } else if (Args.hasArg(options::OPT_g_Group)) { + } else if (Args.hasArg(options::OPT_g_Flag) || hasDwarfNArg) { DebugInfoKind = llvm::codegenoptions::FullDebugInfo; } else { DebugInfoKind = llvm::codegenoptions::NoDebugInfo; } addDebugInfoKind(CmdArgs, DebugInfoKind); - if (getDwarfNArg(Args)) { + if (hasDwarfNArg) { const unsigned DwarfVersion = getDwarfVersion(getToolChain(), Args); CmdArgs.push_back( Args.MakeArgString("-dwarf-version=" + Twine(DwarfVersion))); } + if (Args.hasArg(options::OPT_gsplit_dwarf) || + Args.hasArg(options::OPT_gsplit_dwarf_EQ)) { + // FIXME: -gsplit-dwarf on AIX is currently unimplemented. + if (TC.getTriple().isOSAIX()) { + D.Diag(diag::err_drv_unsupported_opt_for_target) + << Args.getLastArg(options::OPT_gsplit_dwarf)->getSpelling() + << TC.getTriple().str(); + return; + } + if (DebugInfoKind == llvm::codegenoptions::NoDebugInfo) + return; + + Arg *SplitDWARFArg; + DwarfFissionKind DwarfFission = getDebugFissionKind(D, Args, SplitDWARFArg); + + if (DwarfFission == DwarfFissionKind::None || + !checkDebugInfoOption(SplitDWARFArg, Args, D, TC)) + return; + + if (!TC.getTriple().isOSBinFormatELF() && + !TC.getTriple().isOSBinFormatWasm() && + !TC.getTriple().isOSBinFormatCOFF()) + return; + + if (!isa<AssembleJobAction>(JA) && !isa<CompileJobAction>(JA) && + isa<BackendJobAction>(JA)) + return; + + const char *SplitDWARFOut = SplitDebugName(JA, Args, Input, Output); + CmdArgs.push_back("-split-dwarf-file"); + CmdArgs.push_back(SplitDWARFOut); + if (DwarfFission == DwarfFissionKind::Split) { + CmdArgs.push_back("-split-dwarf-output"); + CmdArgs.push_back(SplitDWARFOut); + } + } } void Flang::addCodegenOptions(const ArgList &Args, @@ -936,8 +977,8 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, if (willEmitRemarks(Args)) renderRemarksOptions(Args, CmdArgs, Input); - // Add other compile options - addOtherOptions(Args, CmdArgs); + // Add debug compile options + addDebugOptions(Args, JA, Output, Input, CmdArgs); // Disable all warnings // TODO: Handle interactions between -w, -pedantic, -Wall, -WOption diff --git a/clang/lib/Driver/ToolChains/Flang.h b/clang/lib/Driver/ToolChains/Flang.h index 98167e1b75e15..c0837b80c032e 100644 --- a/clang/lib/Driver/ToolChains/Flang.h +++ b/clang/lib/Driver/ToolChains/Flang.h @@ -125,12 +125,16 @@ class LLVM_LIBRARY_VISIBILITY Flang : public Tool { void addCodegenOptions(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; - /// Extract other compilation options from the driver arguments and add them + /// Extract debug compilation options from the driver arguments and add them /// to the command arguments. /// /// \param [in] Args The list of input driver arguments + /// \param [in] JA The job action + /// \param [in] Output The output information on the current file output + /// \param [in] Input The input information on the current file input /// \param [out] CmdArgs The list of output command arguments - void addOtherOptions(const llvm::opt::ArgList &Args, + void addDebugOptions(const llvm::opt::ArgList &Args, const JobAction &JA, + const InputInfo &Output, const InputInfo &Input, llvm::opt::ArgStringList &CmdArgs) const; public: diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h index df6063cc90340..3dca169d43b39 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -168,6 +168,13 @@ class CodeGenOptions : public CodeGenOptionsBase { /// by -fprofile-sample-use or -fprofile-instr-use. std::string ProfileRemappingFile; + /// The name for the split debug info file used for the DW_AT_[GNU_]dwo_name + /// attribute in the skeleton CU. + std::string SplitDwarfFile; + + /// Output filename for the split debug info, not used in the skeleton CU. + std::string SplitDwarfOutput; + /// Check if Clang profile instrumenation is on. bool hasProfileClangInstr() const { return getProfileInstr() == llvm::driver::ProfileClangInstr; diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 09b51730d6216..81610edee36fb 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -160,6 +160,12 @@ static bool parseDebugArgs(Fortran::frontend::CodeGenOptions &opts, opts.DwarfVersion = getLastArgIntValue(args, clang::driver::options::OPT_dwarf_version_EQ, /*Default=*/0, diags); + if (const llvm::opt::Arg *a = + args.getLastArg(clang::driver::options::OPT_split_dwarf_file)) + opts.SplitDwarfFile = a->getValue(); + if (const llvm::opt::Arg *a = + args.getLastArg(clang::driver::options::OPT_split_dwarf_output)) + opts.SplitDwarfOutput = a->getValue(); } return true; } diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index c3c53d51015a2..867797ff1efdb 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -898,7 +898,19 @@ static void generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags, llvm::CodeGenFileType cgft = (act == BackendActionTy::Backend_EmitAssembly) ? llvm::CodeGenFileType::AssemblyFile : llvm::CodeGenFileType::ObjectFile; - if (tm.addPassesToEmitFile(codeGenPasses, os, nullptr, cgft)) { + std::unique_ptr<llvm::ToolOutputFile> DwoOS; + if (!codeGenOpts.SplitDwarfOutput.empty()) { + std::error_code EC; + DwoOS = std::make_unique<llvm::ToolOutputFile>(codeGenOpts.SplitDwarfOutput, + EC, llvm::sys::fs::OF_None); + if (EC) { + diags.Report(clang::diag::err_fe_unable_to_open_output) + << codeGenOpts.SplitDwarfOutput << EC.message(); + return; + } + } + if (tm.addPassesToEmitFile(codeGenPasses, os, DwoOS ? &DwoOS->os() : nullptr, + cgft)) { unsigned diagID = diags.getCustomDiagID(clang::DiagnosticsEngine::Error, "emission of this file type is not supported"); @@ -909,6 +921,9 @@ static void generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags, // Run the passes codeGenPasses.run(llvmModule); + if (DwoOS) + DwoOS->keep(); + // Cleanup delete tlii; } @@ -1324,6 +1339,7 @@ void CodeGenAction::executeAction() { llvm::TargetMachine &targetMachine = ci.getTargetMachine(); targetMachine.Options.MCOptions.AsmVerbose = targetOpts.asmVerbose; + targetMachine.Options.MCOptions.SplitDwarfFile = codeGenOpts.SplitDwarfFile; const llvm::Triple &theTriple = targetMachine.getTargetTriple(); diff --git a/flang/test/Driver/split-debug.f90 b/flang/test/Driver/split-debug.f90 new file mode 100644 index 0000000000000..a63024328d807 --- /dev/null +++ b/flang/test/Driver/split-debug.f90 @@ -0,0 +1,43 @@ +! Test -gsplit-dwarf and -gsplit-dwarf={split,single}. + +! RUN: %flang -### -c -target x86_64 -g -gsplit-dwarf %s 2>&1 | FileCheck %s --check-prefixes=SPLIT +! RUN: %flang -### -c -target x86_64 -gsplit-dwarf -g %s 2>&1 | FileCheck %s --check-prefixes=SPLIT +! RUN: %flang -### -c -target x86_64 -gsplit-dwarf=split -g %s 2>&1 | FileCheck %s --check-prefixes=SPLIT + +! SPLIT: "-split-dwarf-file" "split-debug.dwo" "-split-dwarf-output" "split-debug.dwo" + +! -gsplit-dwarf is a no-op on a non-ELF platform. +! RUN: %flang -### -c -target x86_64-apple-darwin -gsplit-dwarf -g %s 2>&1 | FileCheck %s --check-prefix=DARWIN +! DARWIN-NOT: "-split-dwarf + + +! -gno-split-dwarf disables debug fission. +! RUN: %flang -### -c -target x86_64 -gsplit-dwarf -g -gno-split-dwarf %s 2>&1 | FileCheck %s --check-prefix=NOSPLIT +! RUN: %flang -### -c -target x86_64 -gsplit-dwarf=single -g -gno-split-dwarf %s 2>&1 | FileCheck %s --check-prefix=NOSPLIT +! RUN: %flang -### -c -target x86_64 -gno-split-dwarf -g -gsplit-dwarf %s 2>&1 | FileCheck %s --check-prefixes=SPLIT + +! NOSPLIT-NOT: "-split-dwarf + +! Test -gsplit-dwarf=single. +! RUN: %flang -### -c -target x86_64 -gsplit-dwarf=single -g %s 2>&1 | FileCheck %s --check-prefix=SINGLE + +! SINGLE: "-split-dwarf-file" "split-debug.o" +! SINGLE-NOT: "-split-dwarf-output" + +! RUN: %flang -### -c -target x86_64 -gsplit-dwarf=single -g -o %tfoo.o %s 2>&1 | FileCheck %s --check-prefix=SINGLE_WITH_FILENAME +! SINGLE_WITH_FILENAME: "-split-dwarf-file" "{{.*}}foo.o" +! SINGLE_WITH_FILENAME-NOT: "-split-dwarf-output" + + +! Invoke objcopy if not using the integrated assembler. +! RUN: %flang -### -c -target x86_64-unknown-linux-gnu -fno-integrated-as -gsplit-dwarf -g %s 2>&1 | FileCheck %s --check-prefix=OBJCOPY +! OBJCOPY: objcopy{{(.exe)?}}" "--extract-dwo" +! OBJCOPY-NEXT: objcopy{{(.exe)?}}" "--strip-dwo" + +! RUN: not %flang -target powerpc-ibm-aix -gdwarf-4 -gsplit-dwarf %s 2>&1 \ +! RUN: | FileCheck %s --check-prefix=UNSUP_OPT_AIX +! RUN: not %flang -target powerpc64-ibm-aix -gdwarf-4 -gsplit-dwarf %s 2>&1 \ +! RUN: | FileCheck %s --check-prefix=UNSUP_OPT_AIX64 + +// UNSUP_OPT_AIX: error: unsupported option '-gsplit-dwarf' for target 'powerpc-ibm-aix' +// UNSUP_OPT_AIX64: error: unsupported option '-gsplit-dwarf' for target 'powerpc64-ibm-aix' diff --git a/flang/test/Integration/debug-split-dwarf.f90 b/flang/test/Integration/debug-split-dwarf.f90 new file mode 100644 index 0000000000000..60373efddc358 --- /dev/null +++ b/flang/test/Integration/debug-split-dwarf.f90 @@ -0,0 +1,21 @@ +! REQUIRES: x86-registered-target + +! 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 + +! 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 + +! DWO: .dwo +! SPLIT-NOT: .dwo + +program test +end program test >From d100412cd111999371d275f7bac46f30d9b1b269 Mon Sep 17 00:00:00 2001 From: Abid Qadeer <haqad...@amd.com> Date: Thu, 25 Sep 2025 10:57:23 +0100 Subject: [PATCH 2/3] Handle review comments. --- flang/lib/Frontend/FrontendActions.cpp | 18 +++++++++--------- flang/test/Driver/split-debug.f90 | 10 ++++++---- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index 867797ff1efdb..9e0bef035a643 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -898,18 +898,18 @@ static void generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags, llvm::CodeGenFileType cgft = (act == BackendActionTy::Backend_EmitAssembly) ? llvm::CodeGenFileType::AssemblyFile : llvm::CodeGenFileType::ObjectFile; - std::unique_ptr<llvm::ToolOutputFile> DwoOS; + std::unique_ptr<llvm::ToolOutputFile> dwoOS; if (!codeGenOpts.SplitDwarfOutput.empty()) { - std::error_code EC; - DwoOS = std::make_unique<llvm::ToolOutputFile>(codeGenOpts.SplitDwarfOutput, - EC, llvm::sys::fs::OF_None); - if (EC) { + std::error_code ec; + dwoOS = std::make_unique<llvm::ToolOutputFile>(codeGenOpts.SplitDwarfOutput, + ec, llvm::sys::fs::OF_None); + if (ec) { diags.Report(clang::diag::err_fe_unable_to_open_output) - << codeGenOpts.SplitDwarfOutput << EC.message(); + << codeGenOpts.SplitDwarfOutput << ec.message(); return; } } - if (tm.addPassesToEmitFile(codeGenPasses, os, DwoOS ? &DwoOS->os() : nullptr, + if (tm.addPassesToEmitFile(codeGenPasses, os, dwoOS ? &dwoOS->os() : nullptr, cgft)) { unsigned diagID = diags.getCustomDiagID(clang::DiagnosticsEngine::Error, @@ -921,8 +921,8 @@ static void generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags, // Run the passes codeGenPasses.run(llvmModule); - if (DwoOS) - DwoOS->keep(); + if (dwoOS) + dwoOS->keep(); // Cleanup delete tlii; diff --git a/flang/test/Driver/split-debug.f90 b/flang/test/Driver/split-debug.f90 index a63024328d807..de8863eae0934 100644 --- a/flang/test/Driver/split-debug.f90 +++ b/flang/test/Driver/split-debug.f90 @@ -31,13 +31,15 @@ ! Invoke objcopy if not using the integrated assembler. ! RUN: %flang -### -c -target x86_64-unknown-linux-gnu -fno-integrated-as -gsplit-dwarf -g %s 2>&1 | FileCheck %s --check-prefix=OBJCOPY -! OBJCOPY: objcopy{{(.exe)?}}" "--extract-dwo" -! OBJCOPY-NEXT: objcopy{{(.exe)?}}" "--strip-dwo" +! OBJCOPY: objcopy{{(.exe)?}} +! OBJCOPY-SAME: --extract-dwo +! OBJCOPY-NEXT: objcopy{{(.exe)?}} +! OBJCOPY-SAME: --strip-dwo ! RUN: not %flang -target powerpc-ibm-aix -gdwarf-4 -gsplit-dwarf %s 2>&1 \ ! RUN: | FileCheck %s --check-prefix=UNSUP_OPT_AIX ! RUN: not %flang -target powerpc64-ibm-aix -gdwarf-4 -gsplit-dwarf %s 2>&1 \ ! RUN: | FileCheck %s --check-prefix=UNSUP_OPT_AIX64 -// UNSUP_OPT_AIX: error: unsupported option '-gsplit-dwarf' for target 'powerpc-ibm-aix' -// UNSUP_OPT_AIX64: error: unsupported option '-gsplit-dwarf' for target 'powerpc64-ibm-aix' +! UNSUP_OPT_AIX: error: unsupported option '-gsplit-dwarf' for target 'powerpc-ibm-aix' +! UNSUP_OPT_AIX64: error: unsupported option '-gsplit-dwarf' for target 'powerpc64-ibm-aix' >From 9d0589fa5526628065b0a4f5dee5e1897e76994c Mon Sep 17 00:00:00 2001 From: Abid Qadeer <haqad...@amd.com> Date: Thu, 25 Sep 2025 12:50:50 +0100 Subject: [PATCH 3/3] Add warning on non-supported platforms. --- clang/lib/Driver/ToolChains/Flang.cpp | 5 ++++- flang/test/Driver/split-debug.f90 | 7 +++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 3e8444c151f36..a5394813eeb97 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -171,8 +171,11 @@ void Flang::addDebugOptions(const llvm::opt::ArgList &Args, const JobAction &JA, if (!TC.getTriple().isOSBinFormatELF() && !TC.getTriple().isOSBinFormatWasm() && - !TC.getTriple().isOSBinFormatCOFF()) + !TC.getTriple().isOSBinFormatCOFF()) { + D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target) + << SplitDWARFArg->getSpelling() << TC.getTriple().str(); return; + } if (!isa<AssembleJobAction>(JA) && !isa<CompileJobAction>(JA) && isa<BackendJobAction>(JA)) diff --git a/flang/test/Driver/split-debug.f90 b/flang/test/Driver/split-debug.f90 index de8863eae0934..1cb9f84d7a5d2 100644 --- a/flang/test/Driver/split-debug.f90 +++ b/flang/test/Driver/split-debug.f90 @@ -6,10 +6,9 @@ ! SPLIT: "-split-dwarf-file" "split-debug.dwo" "-split-dwarf-output" "split-debug.dwo" -! -gsplit-dwarf is a no-op on a non-ELF platform. -! RUN: %flang -### -c -target x86_64-apple-darwin -gsplit-dwarf -g %s 2>&1 | FileCheck %s --check-prefix=DARWIN -! DARWIN-NOT: "-split-dwarf - +! Check warning on non-supported platforms. +! RUN: %flang -### -c -target x86_64-apple-darwin -gsplit-dwarf -g %s 2>&1 | FileCheck %s --check-prefix=WARN +! WARN: warning: debug information option '-gsplit-dwarf' is not supported for target 'x86_64-apple-darwin' ! -gno-split-dwarf disables debug fission. ! RUN: %flang -### -c -target x86_64 -gsplit-dwarf -g -gno-split-dwarf %s 2>&1 | FileCheck %s --check-prefix=NOSPLIT _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits