[flang-commits] [flang] fe2f7e4 - [flang] Support -ffunction-sections and -fdata-sections. (#199731)
via flang-commits
flang-commits at lists.llvm.org
Tue Jun 2 10:53:35 PDT 2026
Author: Abid Qadeer
Date: 2026-06-02T18:53:30+01:00
New Revision: fe2f7e40994574dd5d7efa4da8be5d9237905416
URL: https://github.com/llvm/llvm-project/commit/fe2f7e40994574dd5d7efa4da8be5d9237905416
DIFF: https://github.com/llvm/llvm-project/commit/fe2f7e40994574dd5d7efa4da8be5d9237905416.diff
LOG: [flang] Support -ffunction-sections and -fdata-sections. (#199731)
Wire the flags through the driver, frontend, and TargetMachine, and add
driver and codegen lit tests.
Fixes https://github.com/llvm/llvm-project/issues/163550
---------
Co-authored-by: Cursor <cursoragent at cursor.com>
Added:
flang/test/Driver/function-sections.f90
flang/test/Integration/function-sections.f90
Modified:
clang/include/clang/Driver/CommonArgs.h
clang/include/clang/Options/Options.td
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Driver/ToolChains/CommonArgs.cpp
clang/lib/Driver/ToolChains/Flang.cpp
flang/include/flang/Frontend/CodeGenOptions.def
flang/lib/Frontend/CompilerInstance.cpp
flang/lib/Frontend/CompilerInvocation.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Driver/CommonArgs.h b/clang/include/clang/Driver/CommonArgs.h
index 34b3d302fe189..cdadb824a8ac3 100644
--- a/clang/include/clang/Driver/CommonArgs.h
+++ b/clang/include/clang/Driver/CommonArgs.h
@@ -161,6 +161,11 @@ llvm::StringRef getLTOParallelism(const llvm::opt::ArgList &Args,
bool areOptimizationsEnabled(const llvm::opt::ArgList &Args);
bool isUseSeparateSections(const llvm::Triple &Triple);
+/// Append -ffunction-sections / -fdata-sections to \p CmdArgs when the
+/// corresponding flags are enabled (explicitly or by target default).
+void addSeparateSectionFlags(const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args,
+ llvm::opt::ArgStringList &CmdArgs);
// Parse -mtls-dialect=. Return true if the target supports both general-dynamic
// and TLSDESC, and TLSDESC is requested.
bool isTLSDESCEnabled(const ToolChain &TC, const llvm::opt::ArgList &Args);
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 025e8e7d7d761..8451a3698ef17 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -4832,9 +4832,9 @@ defm zero_initialized_in_bss : BoolFOption<"zero-initialized-in-bss",
PosFlag<SetFalse>>;
defm function_sections : BoolFOption<"function-sections",
CodeGenOpts<"FunctionSections">, DefaultFalse,
- PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option],
"Place each function in its own section">,
- NegFlag<SetFalse>>;
+ NegFlag<SetFalse, [], [FlangOption, FC1Option]>>;
defm basic_block_address_map : BoolFOption<"basic-block-address-map",
CodeGenOpts<"BBAddrMap">, DefaultFalse,
PosFlag<SetTrue, [], [CC1Option], "Emit the basic block address map section.">,
@@ -4847,9 +4847,9 @@ def fbasic_block_sections_EQ : Joined<["-"], "fbasic-block-sections=">, Group<f_
MarshallingInfoString<CodeGenOpts<"BBSections">, [{"none"}]>;
defm data_sections : BoolFOption<"data-sections",
CodeGenOpts<"DataSections">, DefaultFalse,
- PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option],
"Place each data in its own section">,
- NegFlag<SetFalse>>;
+ NegFlag<SetFalse, [], [FlangOption, FC1Option]>>;
defm experimental_call_graph_section
: BoolFOption<"experimental-call-graph-section",
CodeGenOpts<"CallGraphSection">, DefaultFalse,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 7657afb14f077..0c328dd370b05 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6356,12 +6356,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString("-crash-diagnostics-dir=" + Dir));
}
- bool UseSeparateSections = isUseSeparateSections(Triple);
-
- if (Args.hasFlag(options::OPT_ffunction_sections,
- options::OPT_fno_function_sections, UseSeparateSections)) {
- CmdArgs.push_back("-ffunction-sections");
- }
+ addSeparateSectionFlags(Triple, Args, CmdArgs);
if (Arg *A = Args.getLastArg(options::OPT_fbasic_block_address_map,
options::OPT_fno_basic_block_address_map)) {
@@ -6407,12 +6402,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
}
- bool HasDefaultDataSections = Triple.isOSBinFormatXCOFF();
- if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
- UseSeparateSections || HasDefaultDataSections)) {
- CmdArgs.push_back("-fdata-sections");
- }
-
Args.addOptOutFlag(CmdArgs, options::OPT_funique_section_names,
options::OPT_fno_unique_section_names);
Args.addOptInFlag(CmdArgs, options::OPT_fseparate_named_sections,
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index d0dab119fa6d8..47953bc3a23b5 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -946,6 +946,20 @@ bool tools::isUseSeparateSections(const llvm::Triple &Triple) {
return Triple.isPS();
}
+void tools::addSeparateSectionFlags(const llvm::Triple &Triple,
+ const ArgList &Args,
+ ArgStringList &CmdArgs) {
+ bool UseSeparateSections = isUseSeparateSections(Triple);
+ if (Args.hasFlag(options::OPT_ffunction_sections,
+ options::OPT_fno_function_sections, UseSeparateSections))
+ CmdArgs.push_back("-ffunction-sections");
+
+ bool HasDefaultDataSections = Triple.isOSBinFormatXCOFF();
+ if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
+ UseSeparateSections || HasDefaultDataSections))
+ CmdArgs.push_back("-fdata-sections");
+}
+
bool tools::isTLSDESCEnabled(const ToolChain &TC,
const llvm::opt::ArgList &Args) {
const llvm::Triple &Triple = TC.getEffectiveTriple();
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index ae9ae8176e281..4e4f10f27b1c8 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -262,6 +262,10 @@ void Flang::addCodegenOptions(const ArgList &Args,
options::OPT_fstack_repack_arrays, options::OPT_fno_stack_repack_arrays,
options::OPT_ftime_report, options::OPT_ftime_report_EQ,
options::OPT_funroll_loops, options::OPT_fno_unroll_loops});
+
+ const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
+ addSeparateSectionFlags(Triple, Args, CmdArgs);
+
if (Args.hasArg(options::OPT_fcoarray))
CmdArgs.push_back("-fcoarray");
}
diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def
index 17b8e61649da9..d8bbb94bd8cde 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.def
+++ b/flang/include/flang/Frontend/CodeGenOptions.def
@@ -35,6 +35,9 @@ CODEGENOPT(InstrumentFunctions, 1, 0) ///< Set when -finstrument_functions is
CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as
+CODEGENOPT(FunctionSections, 1, 0) ///< -ffunction-sections
+CODEGENOPT(DataSections, 1, 0) ///< -fdata-sections
+
CODEGENOPT(IsPIE, 1, 0) ///< PIE level is the same as PIC Level.
CODEGENOPT(PICLevel, 2, 0) ///< PIC level of the LLVM module.
CODEGENOPT(PrepareForFatLTO , 1, 0) ///< Set when -ffat-lto-objects is enabled.
diff --git a/flang/lib/Frontend/CompilerInstance.cpp b/flang/lib/Frontend/CompilerInstance.cpp
index 3e820d386f8a9..7f562b1c39027 100644
--- a/flang/lib/Frontend/CompilerInstance.cpp
+++ b/flang/lib/Frontend/CompilerInstance.cpp
@@ -385,6 +385,8 @@ bool CompilerInstance::setUpTargetMachine() {
tOpts.EnableAIXExtendedAltivecABI = targetOpts.EnableAIXExtendedAltivecABI;
tOpts.VecLib = convertDriverVectorLibraryToVectorLibrary(CGOpts.getVecLib());
tOpts.DisableIntegratedAS = CGOpts.DisableIntegratedAS;
+ tOpts.FunctionSections = CGOpts.FunctionSections;
+ tOpts.DataSections = CGOpts.DataSections;
targetMachine.reset(theTarget->createTargetMachine(
triple, /*CPU=*/targetOpts.cpu,
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 7349b60c3caa1..fa0a40304545e 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -360,6 +360,14 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
clang::options::OPT_fno_integrated_as, true))
opts.DisableIntegratedAS = 1;
+ opts.FunctionSections =
+ args.hasFlag(clang::options::OPT_ffunction_sections,
+ clang::options::OPT_fno_function_sections,
+ /*Default=*/false);
+ opts.DataSections = args.hasFlag(clang::options::OPT_fdata_sections,
+ clang::options::OPT_fno_data_sections,
+ /*Default=*/false);
+
if (const llvm::opt::Arg *a =
args.getLastArg(clang::options::OPT_mcode_object_version_EQ)) {
llvm::StringRef s = a->getValue();
diff --git a/flang/test/Driver/function-sections.f90 b/flang/test/Driver/function-sections.f90
new file mode 100644
index 0000000000000..7072d62a9d3e2
--- /dev/null
+++ b/flang/test/Driver/function-sections.f90
@@ -0,0 +1,35 @@
+! Test handling of -f(no-)function-sections and -f(no-)data-sections (driver).
+!
+! CHECK-FS: "-ffunction-sections"
+! CHECK-NOFS-NOT: "-ffunction-sections"
+! CHECK-DS: "-fdata-sections"
+! CHECK-NODS-NOT: "-fdata-sections"
+
+! RUN: %flang -### %s 2>&1 \
+! RUN: | FileCheck %s --check-prefix=CHECK-NOFS --check-prefix=CHECK-NODS
+
+! RUN: %flang -### %s -ffunction-sections 2>&1 \
+! RUN: | FileCheck %s --check-prefix=CHECK-FS
+
+! RUN: %flang -### %s -fno-function-sections 2>&1 \
+! RUN: | FileCheck %s --check-prefix=CHECK-NOFS
+
+! RUN: %flang -### %s -ffunction-sections -fno-function-sections 2>&1 \
+! RUN: | FileCheck %s --check-prefix=CHECK-NOFS
+
+! RUN: %flang -### %s -fno-function-sections -ffunction-sections 2>&1 \
+! RUN: | FileCheck %s --check-prefix=CHECK-FS
+
+! RUN: %flang -### %s -fdata-sections 2>&1 \
+! RUN: | FileCheck %s --check-prefix=CHECK-DS
+
+! RUN: %flang -### %s -fno-data-sections 2>&1 \
+! RUN: | FileCheck %s --check-prefix=CHECK-NODS
+
+! RUN: %flang -### %s -fdata-sections -fno-data-sections 2>&1 \
+! RUN: | FileCheck %s --check-prefix=CHECK-NODS
+
+! RUN: %flang -### %s -fno-data-sections -fdata-sections 2>&1 \
+! RUN: | FileCheck %s --check-prefix=CHECK-DS
+
+end program
diff --git a/flang/test/Integration/function-sections.f90 b/flang/test/Integration/function-sections.f90
new file mode 100644
index 0000000000000..ab8bfc986e13f
--- /dev/null
+++ b/flang/test/Integration/function-sections.f90
@@ -0,0 +1,48 @@
+! Test -ffunction-sections and -fdata-sections codegen.
+
+! DEFINE: %{triple} =
+! DEFINE: %{check-func-sect} = %flang_fc1 -triple %{triple} -S -ffunction-sections -o - %s | FileCheck %s --check-prefix=FUNC-SECT
+! DEFINE: %{check-func-plain} = %flang_fc1 -triple %{triple} -S -o - %s | FileCheck %s --check-prefix=FUNC-PLAIN
+! DEFINE: %{check-data-sect} = %flang_fc1 -triple %{triple} -S -fdata-sections -o - %s | FileCheck %s --check-prefix=DATA-SECT --check-prefix=RODATA-SECT
+! DEFINE: %{check-data-plain} = %flang_fc1 -triple %{triple} -S -o - %s | FileCheck %s --check-prefix=DATA-PLAIN --check-prefix=RODATA-PLAIN
+
+! REDEFINE: %{triple} = aarch64-unknown-linux-gnu
+! RUN: %if aarch64-registered-target %{ %{check-func-sect} %}
+! RUN: %if aarch64-registered-target %{ %{check-func-plain} %}
+! RUN: %if aarch64-registered-target %{ %{check-data-sect} %}
+! RUN: %if aarch64-registered-target %{ %{check-data-plain} %}
+
+! REDEFINE: %{triple} = x86_64-unknown-linux-gnu
+! RUN: %if x86-registered-target %{ %{check-func-sect} %}
+! RUN: %if x86-registered-target %{ %{check-func-plain} %}
+! RUN: %if x86-registered-target %{ %{check-data-sect} %}
+! RUN: %if x86-registered-target %{ %{check-data-plain} %}
+
+module data_sect_mod
+ integer, save :: g = 1
+end module
+
+module param_mod
+ integer, parameter :: n = 42
+end module
+
+subroutine foo
+end subroutine
+
+program test
+ use data_sect_mod
+ use param_mod
+ integer :: x
+ call foo
+ x = n
+end program
+
+! FUNC-SECT: .section{{.*}}.text.foo_
+! FUNC-PLAIN-NOT: .section{{.*}}.text.
+
+! DATA-SECT: .section{{.*}}.data._QMdata_sect_modEg
+! DATA-PLAIN: .data
+! DATA-PLAIN-NOT: .section{{.*}}.data.
+
+! RODATA-SECT: .section{{.*}}.rodata._QMparam_modECn
+! RODATA-PLAIN-NOT: .section{{.*}}.rodata._QMparam_modECn
More information about the flang-commits
mailing list