[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