[clang] [clang] Add -mlarge-data-threshold for x86_64 medium code model (PR #66839)
Arthur Eubanks via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 19 16:41:41 PDT 2023
https://github.com/aeubanks created https://github.com/llvm/llvm-project/pull/66839
Error if not used with x86_64.
Warn if not used with the medium code model (can update if other code models end up using this).
Set TargetMachine option and add module flag.
>From 736baebaaced74c29826f2fb9ce09c8e579997d3 Mon Sep 17 00:00:00 2001
From: Arthur Eubanks <aeubanks at google.com>
Date: Tue, 19 Sep 2023 13:50:27 -0700
Subject: [PATCH] [clang] Add -mlarge-data-threshold for x86_64 medium code
model
Error if not used with x86_64.
Warn if not used with the medium code model (can update if other code models end up using this).
Set TargetMachine option and add module flag.
---
clang/include/clang/Basic/CodeGenOptions.h | 4 ++++
.../clang/Basic/DiagnosticDriverKinds.td | 3 +++
clang/include/clang/Basic/TargetOptions.h | 4 ++++
clang/include/clang/Driver/Options.td | 3 +++
clang/lib/CodeGen/BackendUtil.cpp | 1 +
clang/lib/CodeGen/CodeGenModule.cpp | 6 ++++++
clang/lib/Driver/ToolChains/Clang.cpp | 17 +++++++++++++++++
clang/lib/Frontend/CompilerInvocation.cpp | 1 +
clang/test/CodeGen/large-data-threshold.c | 19 +++++++++++++++++++
clang/test/Driver/large-data-threshold.c | 8 ++++++++
10 files changed, 66 insertions(+)
create mode 100644 clang/test/CodeGen/large-data-threshold.c
create mode 100644 clang/test/Driver/large-data-threshold.c
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index 08d4c103ce2453b..12be4e0025a7054 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -174,6 +174,10 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// The code model to use (-mcmodel).
std::string CodeModel;
+ /// The code model-specific large data threshold to use
+ /// (-mlarge-data-threshold).
+ uint64_t LargeDataThreshold;
+
/// The filename with path we use for coverage data files. The runtime
/// allows further manipulation with the GCOV_PREFIX and GCOV_PREFIX_STRIP
/// environment variables.
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 61ac792d6fda46a..c1381ccd2bd5d6b 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -453,6 +453,9 @@ def warn_unsupported_branch_protection: Warning <
"invalid branch protection option '%0' in '%1'">, InGroup<BranchProtection>;
def err_sls_hardening_arm_not_supported : Error<
"-mharden-sls is only supported on armv7-a or later">;
+def warn_drv_large_data_threshold_invalid_code_model: Warning<
+ "'%0' only applies to medium code model">,
+ InGroup<UnusedCommandLineArgument>;
def note_drv_command_failed_diag_msg : Note<
"diagnostic msg: %0">;
diff --git a/clang/include/clang/Basic/TargetOptions.h b/clang/include/clang/Basic/TargetOptions.h
index b192c856384b9ad..e2d2a2bd64240aa 100644
--- a/clang/include/clang/Basic/TargetOptions.h
+++ b/clang/include/clang/Basic/TargetOptions.h
@@ -109,6 +109,10 @@ class TargetOptions {
// code model.
std::string CodeModel;
+ // The large data threshold used for certain code models on certain
+ // architectures.
+ uint64_t LargeDataThreshold;
+
/// The version of the SDK which was used during the compilation.
/// The option is used for two different purposes:
/// * on darwin the version is propagated to LLVM where it's used
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 553c7928c4f949e..819d7a2b339965e 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4248,6 +4248,9 @@ def inline_asm_EQ : Joined<["-"], "inline-asm=">, Group<m_Group>,
def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>,
Visibility<[ClangOption, CC1Option]>,
MarshallingInfoString<TargetOpts<"CodeModel">, [{"default"}]>;
+def mlarge_data_threshold_EQ : Joined<["-"], "mlarge-data-threshold=">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ MarshallingInfoInt<TargetOpts<"LargeDataThreshold">>;
def mtls_size_EQ : Joined<["-"], "mtls-size=">, Group<m_Group>,
Flags<[NoXarchOption]>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Specify bit size of immediate TLS offsets (AArch64 ELF only): "
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index e2afc5d566281ab..ccaf1e97e8e1b4a 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -572,6 +572,7 @@ void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
return;
TM.reset(TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr,
Options, RM, CM, OptLevel));
+ TM->setLargeDataThreshold(CodeGenOpts.LargeDataThreshold);
}
bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 8b0c9340775cbe9..65cd8b7d98a2d67 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1145,6 +1145,12 @@ void CodeGenModule::Release() {
if (CM != ~0u) {
llvm::CodeModel::Model codeModel = static_cast<llvm::CodeModel::Model>(CM);
getModule().setCodeModel(codeModel);
+
+ if (CM == llvm::CodeModel::Medium &&
+ Context.getTargetInfo().getTriple().getArch() ==
+ llvm::Triple::x86_64) {
+ getModule().setLargeDataThreshold(getCodeGenOpts().LargeDataThreshold);
+ }
}
}
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 40e60585a8b8d6e..2a80d03c421e4b3 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5713,6 +5713,23 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
}
+ if (Arg *A = Args.getLastArg(options::OPT_mlarge_data_threshold_EQ)) {
+ if (!Triple.isX86()) {
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << A->getOption().getName() << TripleStr;
+ } else {
+ bool IsMediumCM = false;
+ if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ))
+ IsMediumCM = StringRef(A->getValue()) == "medium";
+ if (!IsMediumCM) {
+ D.Diag(diag::warn_drv_large_data_threshold_invalid_code_model)
+ << A->getOption().getRenderName();
+ } else {
+ A->render(Args, CmdArgs);
+ }
+ }
+ }
+
if (Arg *A = Args.getLastArg(options::OPT_mtls_size_EQ)) {
StringRef Value = A->getValue();
unsigned TLSSize = 0;
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index ffb4f30db0243ec..9d8e5221b25ecb3 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -574,6 +574,7 @@ static bool FixupInvocation(CompilerInvocation &Invocation,
llvm::Triple::ArchType Arch = T.getArch();
CodeGenOpts.CodeModel = TargetOpts.CodeModel;
+ CodeGenOpts.LargeDataThreshold = TargetOpts.LargeDataThreshold;
if (LangOpts.getExceptionHandling() !=
LangOptions::ExceptionHandlingKind::None &&
diff --git a/clang/test/CodeGen/large-data-threshold.c b/clang/test/CodeGen/large-data-threshold.c
new file mode 100644
index 000000000000000..650a7fbb0094e66
--- /dev/null
+++ b/clang/test/CodeGen/large-data-threshold.c
@@ -0,0 +1,19 @@
+// REQUIRES: x86-registered-target
+
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -mcmodel=medium | FileCheck %s --check-prefix=IR-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -mcmodel=medium -mlarge-data-threshold=200 | FileCheck %s --check-prefix=IR-CUSTOM
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S %s -o - -mcmodel=medium -mlarge-data-threshold=200 | FileCheck %s --check-prefix=ASM-SMALL
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S %s -o - -mcmodel=medium -mlarge-data-threshold=2 | FileCheck %s --check-prefix=ASM-LARGE
+
+// IR-DEFAULT: !{i32 1, !"Large Data Threshold", i64 0}
+// IR-CUSTOM: !{i32 1, !"Large Data Threshold", i64 200}
+
+// ASM-SMALL-NOT: movabsq
+// ASM-LARGE: movabsq
+
+static int i;
+
+int f() {
+ return i;
+}
+
diff --git a/clang/test/Driver/large-data-threshold.c b/clang/test/Driver/large-data-threshold.c
new file mode 100644
index 000000000000000..9914286701c6c12
--- /dev/null
+++ b/clang/test/Driver/large-data-threshold.c
@@ -0,0 +1,8 @@
+// RUN: %clang --target=x86_64 -### -c -mcmodel=medium -mlarge-data-threshold=200 %s 2>&1 | FileCheck --check-prefix=ARG %s
+// RUN: %clang --target=x86_64 -### -c -mcmodel=small -mlarge-data-threshold=200 %s 2>&1 | FileCheck --check-prefix=SMALL %s
+// RUN: not %clang --target=riscv32 -### -c -mcmodel=medium -mlarge-data-threshold=200 %s 2>&1 | FileCheck --check-prefix=ARCH %s
+
+// ARG: "-mlarge-data-threshold=200"
+
+// SMALL: 'mlarge-data-threshold=' only applies to medium code model
+// ARCH: unsupported option 'mlarge-data-threshold=' for target 'riscv32'
More information about the cfe-commits
mailing list