Skip to content

Commit dec8d6e

Browse files
Rollup merge of rust-lang#150780 - fzakaria:fzakaria/section-threshold, r=jackh726
Add -Z large-data-threshold This flag allows specifying the threshold size for placing static data in large data sections when using the medium code model on x86-64. When using -Ccode-model=medium, data smaller than this threshold uses RIP-relative addressing (32-bit offsets), while larger data uses absolute 64-bit addressing. This allows the compiler to generate more efficient code for smaller data while still supporting data larger than 2GB. This mirrors the -mlarge-data-threshold flag available in GCC and Clang. The default threshold is 65536 bytes (64KB) if not specified, matching LLVM's default behavior.
2 parents ae31dd7 + 93f2e80 commit dec8d6e

7 files changed

Lines changed: 115 additions & 1 deletion

File tree

compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ impl OwnedTargetMachine {
3939
debug_info_compression: llvm::CompressionKind,
4040
use_emulated_tls: bool,
4141
use_wasm_eh: bool,
42+
large_data_threshold: u64,
4243
) -> Result<Self, LlvmError<'static>> {
4344
// SAFETY: llvm::LLVMRustCreateTargetMachine copies pointed to data
4445
let tm_ptr = unsafe {
@@ -65,6 +66,7 @@ impl OwnedTargetMachine {
6566
debug_info_compression,
6667
use_emulated_tls,
6768
use_wasm_eh,
69+
large_data_threshold,
6870
)
6971
};
7072

compiler/rustc_codegen_llvm/src/back/write.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,8 @@ pub(crate) fn target_machine_factory(
275275

276276
let use_wasm_eh = wants_wasm_eh(sess);
277277

278+
let large_data_threshold = sess.opts.unstable_opts.large_data_threshold.unwrap_or(0);
279+
278280
let prof = SelfProfilerRef::clone(&sess.prof);
279281
Arc::new(move |config: TargetMachineFactoryConfig| {
280282
// Self-profile timer for invoking a factory to create a target machine.
@@ -316,6 +318,7 @@ pub(crate) fn target_machine_factory(
316318
debuginfo_compression,
317319
use_emulated_tls,
318320
use_wasm_eh,
321+
large_data_threshold,
319322
)
320323
})
321324
}

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2347,6 +2347,7 @@ unsafe extern "C" {
23472347
DebugInfoCompression: CompressionKind,
23482348
UseEmulatedTls: bool,
23492349
UseWasmEH: bool,
2350+
LargeDataThreshold: u64,
23502351
) -> *mut TargetMachine;
23512352

23522353
pub(crate) fn LLVMRustAddLibraryInfo<'a>(

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
305305
bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray,
306306
const char *SplitDwarfFile, const char *OutputObjFile,
307307
LLVMRustCompressionKind DebugInfoCompression, bool UseEmulatedTls,
308-
bool UseWasmEH) {
308+
bool UseWasmEH, uint64_t LargeDataThreshold) {
309309

310310
auto OptLevel = fromRust(RustOptLevel);
311311
auto RM = fromRust(RustReloc);
@@ -381,6 +381,11 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
381381
TargetMachine *TM = TheTarget->createTargetMachine(
382382
Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel);
383383
#endif
384+
385+
if (LargeDataThreshold != 0) {
386+
TM->setLargeDataThreshold(LargeDataThreshold);
387+
}
388+
384389
return wrap(TM);
385390
}
386391

compiler/rustc_session/src/options.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2426,6 +2426,9 @@ options! {
24262426
`=skip-entry`
24272427
`=skip-exit`
24282428
Multiple options can be combined with commas."),
2429+
large_data_threshold: Option<u64> = (None, parse_opt_number, [TRACKED],
2430+
"set the threshold for objects to be stored in a \"large data\" section \
2431+
(only effective with -Ccode-model=medium, default: 65536)"),
24292432
layout_seed: Option<u64> = (None, parse_opt_number, [TRACKED],
24302433
"seed layout randomization"),
24312434
link_directives: bool = (true, parse_bool, [TRACKED],
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# `large-data-threshold`
2+
3+
-----------------------
4+
5+
This flag controls the threshold for static data to be placed in large data
6+
sections when using the `medium` code model on x86-64.
7+
8+
When using `-Ccode-model=medium`, static data smaller than this threshold will
9+
use RIP-relative addressing (32-bit offsets), while larger data will use
10+
absolute 64-bit addressing. This allows the compiler to generate more efficient
11+
code for smaller data while still supporting data larger than 2GB.
12+
13+
The default threshold is 65536 bytes (64KB) if not specified.
14+
15+
## Example
16+
17+
```sh
18+
rustc -Ccode-model=medium -Zlarge-data-threshold=1024 main.rs
19+
```
20+
21+
This sets the threshold to 1KB, meaning only data smaller than 1024 bytes will
22+
use RIP-relative addressing.
23+
24+
## Platform Support
25+
26+
This flag is only effective on x86-64 targets when using `-Ccode-model=medium`.
27+
On other architectures or with other code models, this flag has no effect.
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Test for -Z large_data_threshold=...
2+
// This test verifies that with the medium code model, data above the threshold
3+
// is placed in large data sections (.ldata, .lbss, .lrodata).
4+
//@ assembly-output: emit-asm
5+
//@ compile-flags: -Ccode-model=medium -Zlarge-data-threshold=4
6+
//@ compile-flags: --target=x86_64-unknown-linux-gnu
7+
//@ needs-llvm-components: x86
8+
9+
#![feature(no_core, lang_items)]
10+
#![no_std]
11+
#![no_core]
12+
#![crate_type = "lib"]
13+
14+
#[lang = "pointee_sized"]
15+
pub trait PointeeSized {}
16+
17+
#[lang = "meta_sized"]
18+
pub trait MetaSized: PointeeSized {}
19+
20+
#[lang = "sized"]
21+
pub trait Sized: MetaSized {}
22+
23+
#[lang = "drop_in_place"]
24+
fn drop_in_place<T>(_: *mut T) {}
25+
26+
#[used]
27+
#[no_mangle]
28+
// U is below the threshold, should be in .data
29+
static mut U: u16 = 123;
30+
31+
#[used]
32+
#[no_mangle]
33+
// V is below the threshold, should be in .bss
34+
static mut V: u16 = 0;
35+
36+
#[used]
37+
#[no_mangle]
38+
// W is at the threshold, should be in .data
39+
static mut W: u32 = 123;
40+
41+
#[used]
42+
#[no_mangle]
43+
// X is at the threshold, should be in .bss
44+
static mut X: u32 = 0;
45+
46+
#[used]
47+
#[no_mangle]
48+
// Y is over the threshold, should be in .ldata
49+
static mut Y: u64 = 123;
50+
51+
#[used]
52+
#[no_mangle]
53+
// Z is over the threshold, should be in .lbss
54+
static mut Z: u64 = 0;
55+
56+
// CHECK: .section .data.U,
57+
// CHECK-NOT: .section
58+
// CHECK: U:
59+
// CHECK: .section .bss.V,
60+
// CHECK-NOT: .section
61+
// CHECK: V:
62+
// CHECK: .section .data.W,
63+
// CHECK-NOT: .section
64+
// CHECK: W:
65+
// CHECK: .section .bss.X,
66+
// CHECK-NOT: .section
67+
// CHECK: X:
68+
// CHECK: .section .ldata.Y,
69+
// CHECK-NOT: .section
70+
// CHECK: Y:
71+
// CHECK: .section .lbss.Z,
72+
// CHECK-NOT: .section
73+
// CHECK: Z:

0 commit comments

Comments
 (0)