Skip to content

Commit

Permalink
[clang] Add -mlarge-data-threshold for x86_64 medium code model (#66839)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
aeubanks authored Sep 26, 2023
1 parent c1afed9 commit a42787d
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 0 deletions.
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/CodeGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticDriverKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,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">;
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/TargetOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -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): "
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,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);
}
}
}

Expand Down
17 changes: 17 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5714,6 +5714,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;
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand Down
19 changes: 19 additions & 0 deletions clang/test/CodeGen/large-data-threshold.c
Original file line number Diff line number Diff line change
@@ -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;
}

8 changes: 8 additions & 0 deletions clang/test/Driver/large-data-threshold.c
Original file line number Diff line number Diff line change
@@ -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'

0 comments on commit a42787d

Please sign in to comment.