Skip to content

Commit a42787d

Browse files
authored
[clang] Add -mlarge-data-threshold for x86_64 medium code model (#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.
1 parent c1afed9 commit a42787d

File tree

10 files changed

+66
-0
lines changed

10 files changed

+66
-0
lines changed

clang/include/clang/Basic/CodeGenOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ class CodeGenOptions : public CodeGenOptionsBase {
174174
/// The code model to use (-mcmodel).
175175
std::string CodeModel;
176176

177+
/// The code model-specific large data threshold to use
178+
/// (-mlarge-data-threshold).
179+
uint64_t LargeDataThreshold;
180+
177181
/// The filename with path we use for coverage data files. The runtime
178182
/// allows further manipulation with the GCOV_PREFIX and GCOV_PREFIX_STRIP
179183
/// environment variables.

clang/include/clang/Basic/DiagnosticDriverKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,9 @@ def warn_unsupported_branch_protection: Warning <
456456
"invalid branch protection option '%0' in '%1'">, InGroup<BranchProtection>;
457457
def err_sls_hardening_arm_not_supported : Error<
458458
"-mharden-sls is only supported on armv7-a or later">;
459+
def warn_drv_large_data_threshold_invalid_code_model: Warning<
460+
"'%0' only applies to medium code model">,
461+
InGroup<UnusedCommandLineArgument>;
459462

460463
def note_drv_command_failed_diag_msg : Note<
461464
"diagnostic msg: %0">;

clang/include/clang/Basic/TargetOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ class TargetOptions {
109109
// code model.
110110
std::string CodeModel;
111111

112+
// The large data threshold used for certain code models on certain
113+
// architectures.
114+
uint64_t LargeDataThreshold;
115+
112116
/// The version of the SDK which was used during the compilation.
113117
/// The option is used for two different purposes:
114118
/// * on darwin the version is propagated to LLVM where it's used

clang/include/clang/Driver/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4248,6 +4248,9 @@ def inline_asm_EQ : Joined<["-"], "inline-asm=">, Group<m_Group>,
42484248
def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>,
42494249
Visibility<[ClangOption, CC1Option]>,
42504250
MarshallingInfoString<TargetOpts<"CodeModel">, [{"default"}]>;
4251+
def mlarge_data_threshold_EQ : Joined<["-"], "mlarge-data-threshold=">, Group<m_Group>,
4252+
Visibility<[ClangOption, CC1Option]>,
4253+
MarshallingInfoInt<TargetOpts<"LargeDataThreshold">>;
42514254
def mtls_size_EQ : Joined<["-"], "mtls-size=">, Group<m_Group>,
42524255
Flags<[NoXarchOption]>, Visibility<[ClangOption, CC1Option]>,
42534256
HelpText<"Specify bit size of immediate TLS offsets (AArch64 ELF only): "

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,7 @@ void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
572572
return;
573573
TM.reset(TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr,
574574
Options, RM, CM, OptLevel));
575+
TM->setLargeDataThreshold(CodeGenOpts.LargeDataThreshold);
575576
}
576577

577578
bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,6 +1146,12 @@ void CodeGenModule::Release() {
11461146
if (CM != ~0u) {
11471147
llvm::CodeModel::Model codeModel = static_cast<llvm::CodeModel::Model>(CM);
11481148
getModule().setCodeModel(codeModel);
1149+
1150+
if (CM == llvm::CodeModel::Medium &&
1151+
Context.getTargetInfo().getTriple().getArch() ==
1152+
llvm::Triple::x86_64) {
1153+
getModule().setLargeDataThreshold(getCodeGenOpts().LargeDataThreshold);
1154+
}
11491155
}
11501156
}
11511157

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5714,6 +5714,23 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
57145714
}
57155715
}
57165716

5717+
if (Arg *A = Args.getLastArg(options::OPT_mlarge_data_threshold_EQ)) {
5718+
if (!Triple.isX86()) {
5719+
D.Diag(diag::err_drv_unsupported_opt_for_target)
5720+
<< A->getOption().getName() << TripleStr;
5721+
} else {
5722+
bool IsMediumCM = false;
5723+
if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ))
5724+
IsMediumCM = StringRef(A->getValue()) == "medium";
5725+
if (!IsMediumCM) {
5726+
D.Diag(diag::warn_drv_large_data_threshold_invalid_code_model)
5727+
<< A->getOption().getRenderName();
5728+
} else {
5729+
A->render(Args, CmdArgs);
5730+
}
5731+
}
5732+
}
5733+
57175734
if (Arg *A = Args.getLastArg(options::OPT_mtls_size_EQ)) {
57185735
StringRef Value = A->getValue();
57195736
unsigned TLSSize = 0;

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,7 @@ static bool FixupInvocation(CompilerInvocation &Invocation,
574574
llvm::Triple::ArchType Arch = T.getArch();
575575

576576
CodeGenOpts.CodeModel = TargetOpts.CodeModel;
577+
CodeGenOpts.LargeDataThreshold = TargetOpts.LargeDataThreshold;
577578

578579
if (LangOpts.getExceptionHandling() !=
579580
LangOptions::ExceptionHandlingKind::None &&
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// REQUIRES: x86-registered-target
2+
3+
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -mcmodel=medium | FileCheck %s --check-prefix=IR-DEFAULT
4+
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - -mcmodel=medium -mlarge-data-threshold=200 | FileCheck %s --check-prefix=IR-CUSTOM
5+
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S %s -o - -mcmodel=medium -mlarge-data-threshold=200 | FileCheck %s --check-prefix=ASM-SMALL
6+
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S %s -o - -mcmodel=medium -mlarge-data-threshold=2 | FileCheck %s --check-prefix=ASM-LARGE
7+
8+
// IR-DEFAULT: !{i32 1, !"Large Data Threshold", i64 0}
9+
// IR-CUSTOM: !{i32 1, !"Large Data Threshold", i64 200}
10+
11+
// ASM-SMALL-NOT: movabsq
12+
// ASM-LARGE: movabsq
13+
14+
static int i;
15+
16+
int f() {
17+
return i;
18+
}
19+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %clang --target=x86_64 -### -c -mcmodel=medium -mlarge-data-threshold=200 %s 2>&1 | FileCheck --check-prefix=ARG %s
2+
// RUN: %clang --target=x86_64 -### -c -mcmodel=small -mlarge-data-threshold=200 %s 2>&1 | FileCheck --check-prefix=SMALL %s
3+
// RUN: not %clang --target=riscv32 -### -c -mcmodel=medium -mlarge-data-threshold=200 %s 2>&1 | FileCheck --check-prefix=ARCH %s
4+
5+
// ARG: "-mlarge-data-threshold=200"
6+
7+
// SMALL: 'mlarge-data-threshold=' only applies to medium code model
8+
// ARCH: unsupported option 'mlarge-data-threshold=' for target 'riscv32'

0 commit comments

Comments
 (0)