[clang] [Clang] Add clang driver option -fpartition-static-data-sections (PR #124991)
Mingming Liu via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 6 13:59:24 PST 2026
https://github.com/mingmingl-llvm updated https://github.com/llvm/llvm-project/pull/124991
>From 755b5d07f8fb792793036179df72eec6bda19260 Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Wed, 29 Jan 2025 13:17:11 -0800
Subject: [PATCH 1/5] [Clang]Add -fpartition-static-data-section
---
clang/include/clang/Basic/CodeGenOptions.def | 2 ++
clang/include/clang/Driver/Options.td | 6 ++++++
clang/lib/CodeGen/BackendUtil.cpp | 2 ++
clang/lib/Driver/ToolChains/Clang.cpp | 14 ++++++++++++++
clang/lib/Driver/ToolChains/CommonArgs.cpp | 8 ++++++++
.../test/Driver/fpartition-static-data-sections.c | 13 +++++++++++++
clang/test/Driver/test.c | 13 +++++++++++++
7 files changed, 58 insertions(+)
create mode 100644 clang/test/Driver/fpartition-static-data-sections.c
create mode 100644 clang/test/Driver/test.c
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 259972bdf8f00..86246eb373630 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -199,6 +199,8 @@ CODEGENOPT(DisableBlockSignatureString, 1, 0) ///< Set when -fdisable-block-sign
CODEGENOPT(HIPSaveKernelArgName, 1, 0) ///< Set when -fhip-kernel-arg-name is enabled.
CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Internal Linkage symbols get unique names.
CODEGENOPT(SplitMachineFunctions, 1, 0) ///< Split machine functions using profile information.
+CODEGENOPT(PartitionStaticDataSections, 1,
+ 0) /// < Partition static data sections using profile information.
CODEGENOPT(PPCUseFullRegisterNames, 1, 0) ///< Print full register names in assembly
CODEGENOPT(X86RelaxRelocations, 1, 1) ///< -Wa,-mrelax-relocations={yes,no}
CODEGENOPT(X86Sse2Avx , 1, 0) ///< -Wa,-msse2avx
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index ba5600e1912a6..c7c01fd54290b 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4385,6 +4385,12 @@ defm split_machine_functions: BoolFOption<"split-machine-functions",
NegFlag<SetFalse, [], [ClangOption], "Disable">,
BothFlags<[], [ClangOption], " late function splitting using profile information (x86 and aarch64 ELF)">>;
+defm partition_static_data_sections: BoolFOption<"partition-static-data-sections",
+ CodeGenOpts<"PartitionStaticDataSections">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [ClangOption], " partition static data sections using profile information (x86 ELF)">>;
+
defm strict_return : BoolFOption<"strict-return",
CodeGenOpts<"StrictReturn">, DefaultTrue,
NegFlag<SetFalse, [], [ClangOption, CC1Option],
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 3e65eeb3755d2..9c29e02017227 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -442,6 +442,8 @@ static bool initTargetOptions(const CompilerInstance &CI,
}
Options.EnableMachineFunctionSplitter = CodeGenOpts.SplitMachineFunctions;
+ Options.EnableStaticDataPartitioning =
+ CodeGenOpts.PartitionStaticDataSections;
Options.FunctionSections = CodeGenOpts.FunctionSections;
Options.DataSections = CodeGenOpts.DataSections;
Options.IgnoreXCOFFVisibility = LangOpts.IgnoreXCOFFVisibility;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 70e5e9847dff6..e67df32180ea9 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6401,6 +6401,20 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
}
+ if (Arg *A =
+ Args.getLastArg(options::OPT_fpartition_static_data_sections,
+ options::OPT_fno_partition_static_data_sections)) {
+ if (!A->getOption().matches(
+ options::OPT_fno_partition_static_data_sections)) {
+ // This codegen pass is only available on x86 and AArch64 ELF targets.
+ if (Triple.isX86() && Triple.isOSBinFormatELF())
+ A->render(Args, CmdArgs);
+ else
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << A->getAsString(Args) << TripleStr;
+ }
+ }
+
Args.AddLastArg(CmdArgs, options::OPT_finstrument_functions,
options::OPT_finstrument_functions_after_inlining,
options::OPT_finstrument_function_entry_bare);
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 2c4b082bcce4a..40878e9778499 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1087,6 +1087,14 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
"-split-machine-functions"));
}
+ if (auto *A =
+ Args.getLastArg(options::OPT_fpartition_static_data_sections,
+ options::OPT_fno_partition_static_data_sections)) {
+ if (A->getOption().matches(options::OPT_fpartition_static_data_sections))
+ CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
+ "-partition-static-data-sections"));
+ }
+
if (Arg *A = getLastProfileSampleUseArg(Args)) {
StringRef FName = A->getValue();
if (!llvm::sys::fs::exists(FName))
diff --git a/clang/test/Driver/fpartition-static-data-sections.c b/clang/test/Driver/fpartition-static-data-sections.c
new file mode 100644
index 0000000000000..271b22a55c188
--- /dev/null
+++ b/clang/test/Driver/fpartition-static-data-sections.c
@@ -0,0 +1,13 @@
+// RUN: %clang -### --target=x86_64 -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefixes=OPT
+// RUN: not %clang -### --target=aarch64 -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefixes=ERR
+
+// RUN: %clang -### --target=x86_64 -fpartition-static-data-sections -fno-partition-static-data-sections %s 2>&1 | FileCheck %s --implicit-check-not="-fpartition-static-data-sections"
+
+// RUN: %clang -### --target=x86_64-linux -flto -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefix=LTO
+// RUN: %clang -### --target=x86_64-linux -flto -fpartition-static-data-sections -fno-partition-static-data-sections %s 2>&1 | FileCheck %s --implicit-check-not="-plugin-opt=-fpartition-static-data-sections"
+
+// OPT: "-fpartition-static-data-sections"
+
+// ERR: error: unsupported option '-fpartition-static-data-sections' for target
+
+// LTO: "-plugin-opt=-partition-static-data-sections"
diff --git a/clang/test/Driver/test.c b/clang/test/Driver/test.c
new file mode 100644
index 0000000000000..271b22a55c188
--- /dev/null
+++ b/clang/test/Driver/test.c
@@ -0,0 +1,13 @@
+// RUN: %clang -### --target=x86_64 -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefixes=OPT
+// RUN: not %clang -### --target=aarch64 -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefixes=ERR
+
+// RUN: %clang -### --target=x86_64 -fpartition-static-data-sections -fno-partition-static-data-sections %s 2>&1 | FileCheck %s --implicit-check-not="-fpartition-static-data-sections"
+
+// RUN: %clang -### --target=x86_64-linux -flto -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefix=LTO
+// RUN: %clang -### --target=x86_64-linux -flto -fpartition-static-data-sections -fno-partition-static-data-sections %s 2>&1 | FileCheck %s --implicit-check-not="-plugin-opt=-fpartition-static-data-sections"
+
+// OPT: "-fpartition-static-data-sections"
+
+// ERR: error: unsupported option '-fpartition-static-data-sections' for target
+
+// LTO: "-plugin-opt=-partition-static-data-sections"
>From b5d07b4c608dfd0cdf95004513d60d9d90997d1e Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Wed, 29 Jan 2025 13:39:52 -0800
Subject: [PATCH 2/5] support aarch64
---
clang/include/clang/Driver/Options.td | 2 +-
clang/lib/Driver/ToolChains/Clang.cpp | 2 +-
clang/test/Driver/fpartition-static-data-sections.c | 4 +++-
clang/test/Driver/test.c | 4 +++-
4 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index c7c01fd54290b..a7a3f58f60c6c 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4389,7 +4389,7 @@ defm partition_static_data_sections: BoolFOption<"partition-static-data-sections
CodeGenOpts<"PartitionStaticDataSections">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
NegFlag<SetFalse, [], [ClangOption], "Disable">,
- BothFlags<[], [ClangOption], " partition static data sections using profile information (x86 ELF)">>;
+ BothFlags<[], [ClangOption], " partition static data sections using profile information (x86 and aarch64 ELF)">>;
defm strict_return : BoolFOption<"strict-return",
CodeGenOpts<"StrictReturn">, DefaultTrue,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index e67df32180ea9..ff0e467e67dde 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6407,7 +6407,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (!A->getOption().matches(
options::OPT_fno_partition_static_data_sections)) {
// This codegen pass is only available on x86 and AArch64 ELF targets.
- if (Triple.isX86() && Triple.isOSBinFormatELF())
+ if ((Triple.isX86() || Triple.isAArch64()) && Triple.isOSBinFormatELF())
A->render(Args, CmdArgs);
else
D.Diag(diag::err_drv_unsupported_opt_for_target)
diff --git a/clang/test/Driver/fpartition-static-data-sections.c b/clang/test/Driver/fpartition-static-data-sections.c
index 271b22a55c188..8f158b81373de 100644
--- a/clang/test/Driver/fpartition-static-data-sections.c
+++ b/clang/test/Driver/fpartition-static-data-sections.c
@@ -1,5 +1,7 @@
// RUN: %clang -### --target=x86_64 -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefixes=OPT
-// RUN: not %clang -### --target=aarch64 -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefixes=ERR
+// RUN: %clang -### --target=aarch64 -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefixes=OPT
+
+// RUN: not %clang -### --target=arm -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefixes=ERR
// RUN: %clang -### --target=x86_64 -fpartition-static-data-sections -fno-partition-static-data-sections %s 2>&1 | FileCheck %s --implicit-check-not="-fpartition-static-data-sections"
diff --git a/clang/test/Driver/test.c b/clang/test/Driver/test.c
index 271b22a55c188..8f158b81373de 100644
--- a/clang/test/Driver/test.c
+++ b/clang/test/Driver/test.c
@@ -1,5 +1,7 @@
// RUN: %clang -### --target=x86_64 -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefixes=OPT
-// RUN: not %clang -### --target=aarch64 -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefixes=ERR
+// RUN: %clang -### --target=aarch64 -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefixes=OPT
+
+// RUN: not %clang -### --target=arm -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefixes=ERR
// RUN: %clang -### --target=x86_64 -fpartition-static-data-sections -fno-partition-static-data-sections %s 2>&1 | FileCheck %s --implicit-check-not="-fpartition-static-data-sections"
>From 0bcfaecc3988473da5438ffcd86fb9124f1482d2 Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Mon, 22 Dec 2025 11:13:11 -0800
Subject: [PATCH 3/5] Add flags
---
clang/lib/Driver/ToolChains/Clang.cpp | 10 ++++++++--
clang/lib/Driver/ToolChains/CommonArgs.cpp | 3 ++-
.../test/Driver/fpartition-static-data-sections.c | 1 +
clang/test/Driver/test.c | 15 ---------------
4 files changed, 11 insertions(+), 18 deletions(-)
delete mode 100644 clang/test/Driver/test.c
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index c52bc40363f5e..c023383921001 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6188,9 +6188,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (!A->getOption().matches(
options::OPT_fno_partition_static_data_sections)) {
// This codegen pass is only available on x86 and AArch64 ELF targets.
- if ((Triple.isX86() || Triple.isAArch64()) && Triple.isOSBinFormatELF())
+ if ((Triple.isX86() || Triple.isAArch64()) && Triple.isOSBinFormatELF()) {
A->render(Args, CmdArgs);
- else
+ // Turn on -memprof-annotate-static-data-prefix.
+ // When the memory profile (specified by --fmemory-profile-use) has
+ // static data access profiles, global variable hotness are inferrred
+ // from the profile. Otherwise this option is no-op.
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-memprof-annotate-static-data-prefix");
+ } else
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
}
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index ea38cfe6e00a1..5a28648802d82 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1244,9 +1244,10 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
if (auto *A =
Args.getLastArg(options::OPT_fpartition_static_data_sections,
options::OPT_fno_partition_static_data_sections)) {
- if (A->getOption().matches(options::OPT_fpartition_static_data_sections))
+ if (A->getOption().matches(options::OPT_fpartition_static_data_sections)) {
CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
"-partition-static-data-sections"));
+ }
}
if (Arg *A = getLastProfileSampleUseArg(Args)) {
diff --git a/clang/test/Driver/fpartition-static-data-sections.c b/clang/test/Driver/fpartition-static-data-sections.c
index 8f158b81373de..b200d673bb7fa 100644
--- a/clang/test/Driver/fpartition-static-data-sections.c
+++ b/clang/test/Driver/fpartition-static-data-sections.c
@@ -9,6 +9,7 @@
// RUN: %clang -### --target=x86_64-linux -flto -fpartition-static-data-sections -fno-partition-static-data-sections %s 2>&1 | FileCheck %s --implicit-check-not="-plugin-opt=-fpartition-static-data-sections"
// OPT: "-fpartition-static-data-sections"
+// OPT: "-mllvm" "-memprof-annotate-static-data-prefix"
// ERR: error: unsupported option '-fpartition-static-data-sections' for target
diff --git a/clang/test/Driver/test.c b/clang/test/Driver/test.c
deleted file mode 100644
index 8f158b81373de..0000000000000
--- a/clang/test/Driver/test.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: %clang -### --target=x86_64 -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefixes=OPT
-// RUN: %clang -### --target=aarch64 -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefixes=OPT
-
-// RUN: not %clang -### --target=arm -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefixes=ERR
-
-// RUN: %clang -### --target=x86_64 -fpartition-static-data-sections -fno-partition-static-data-sections %s 2>&1 | FileCheck %s --implicit-check-not="-fpartition-static-data-sections"
-
-// RUN: %clang -### --target=x86_64-linux -flto -fpartition-static-data-sections %s 2>&1 | FileCheck %s --check-prefix=LTO
-// RUN: %clang -### --target=x86_64-linux -flto -fpartition-static-data-sections -fno-partition-static-data-sections %s 2>&1 | FileCheck %s --implicit-check-not="-plugin-opt=-fpartition-static-data-sections"
-
-// OPT: "-fpartition-static-data-sections"
-
-// ERR: error: unsupported option '-fpartition-static-data-sections' for target
-
-// LTO: "-plugin-opt=-partition-static-data-sections"
>From ded3aa14cabd005fb7c3f7152da50687272ce2a9 Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Fri, 26 Dec 2025 09:25:50 -0800
Subject: [PATCH 4/5] Add lightweight documentation in code comments
---
clang/lib/Driver/ToolChains/Clang.cpp | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index c023383921001..7657cf70ed9ea 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6191,11 +6191,27 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if ((Triple.isX86() || Triple.isAArch64()) && Triple.isOSBinFormatELF()) {
A->render(Args, CmdArgs);
// Turn on -memprof-annotate-static-data-prefix.
- // When the memory profile (specified by --fmemory-profile-use) has
- // static data access profiles, global variable hotness are inferrred
- // from the profile. Otherwise this option is no-op.
+ // * When the memory profile (specified by -fmemory-profile-use) has
+ // static data access profiles, global variable hotness are inferred
+ // from a combination of PGO profile and data access profile:
+ // - For data covered by both profiles (e.g., module-internal data
+ // with
+ // symbols in the executable), the hotness is the max of PGO profile
+ // hotness and data access profile hotness.
+ // - For data covered by only one profile, the hotness is inferred
+ // from that profile. Most notably, symbolizable data with external
+ // linkage is only covered by data access profile, and
+ // module-internal unsymbolizable data is only covered by PGO
+ // profile.
+ // * When -fmemory-profile-use is not specified, this LLVM flag is a
+ // no-op.
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("-memprof-annotate-static-data-prefix");
+ // Note that the Clang driver PGO options don't typically imply
+ // linker options (e.g., -fprofile-use and
+ // -Wl,-z,-keep-text-section-prefix are specified together); similarly
+ // -fpartition-static-data-sections doesn't imply
+ // `-Wl,-z,-keep-data-section-prefix` if the specified linker is lld.
} else
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
>From c556f11b0fec85b87642a1c52a581b9b3fdf57d4 Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Tue, 6 Jan 2026 13:59:02 -0800
Subject: [PATCH 5/5] remove comments
---
clang/lib/Driver/ToolChains/Clang.cpp | 20 --------------------
1 file changed, 20 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 7657cf70ed9ea..88c9ac4594c3e 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6190,28 +6190,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// This codegen pass is only available on x86 and AArch64 ELF targets.
if ((Triple.isX86() || Triple.isAArch64()) && Triple.isOSBinFormatELF()) {
A->render(Args, CmdArgs);
- // Turn on -memprof-annotate-static-data-prefix.
- // * When the memory profile (specified by -fmemory-profile-use) has
- // static data access profiles, global variable hotness are inferred
- // from a combination of PGO profile and data access profile:
- // - For data covered by both profiles (e.g., module-internal data
- // with
- // symbols in the executable), the hotness is the max of PGO profile
- // hotness and data access profile hotness.
- // - For data covered by only one profile, the hotness is inferred
- // from that profile. Most notably, symbolizable data with external
- // linkage is only covered by data access profile, and
- // module-internal unsymbolizable data is only covered by PGO
- // profile.
- // * When -fmemory-profile-use is not specified, this LLVM flag is a
- // no-op.
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("-memprof-annotate-static-data-prefix");
- // Note that the Clang driver PGO options don't typically imply
- // linker options (e.g., -fprofile-use and
- // -Wl,-z,-keep-text-section-prefix are specified together); similarly
- // -fpartition-static-data-sections doesn't imply
- // `-Wl,-z,-keep-data-section-prefix` if the specified linker is lld.
} else
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
More information about the cfe-commits
mailing list