Skip to content

Commit 42150ae

Browse files
committed
Add -Z small-data-threshold
This flag allows specifying the threshold size above which LLVM should not consider placing small objects in a .sdata or .sbss section.
1 parent 50be229 commit 42150ae

File tree

6 files changed

+112
-0
lines changed

6 files changed

+112
-0
lines changed

compiler/rustc_codegen_llvm/src/context.rs

+13
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,19 @@ pub unsafe fn create_module<'ll>(
351351
);
352352
}
353353

354+
if let Some(threshold) = sess.opts.unstable_opts.small_data_threshold {
355+
// Set up the small-data optimization limit for architectures that use
356+
// an LLVM module flag to control this.
357+
if sess.target.arch.starts_with("riscv") {
358+
llvm::LLVMRustAddModuleFlag(
359+
llmod,
360+
llvm::LLVMModFlagBehavior::Error,
361+
"SmallDataLimit\0".as_ptr().cast(),
362+
threshold as u32,
363+
)
364+
}
365+
}
366+
354367
// Insert `llvm.ident` metadata.
355368
//
356369
// On the wasm targets it will get hooked up to the "producer" sections

compiler/rustc_codegen_llvm/src/llvm_util.rs

+18
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,24 @@ unsafe fn configure_llvm(sess: &Session) {
118118
for arg in sess_args {
119119
add(&(*arg), true);
120120
}
121+
122+
if let Some(threshold) = sess.opts.unstable_opts.small_data_threshold {
123+
// Set up the small-data optimization limit for architectures that use
124+
// an LLVM argument to control this.
125+
match sess.target.arch.as_ref() {
126+
"hexagon" => add(&format!("--hexagon-small-data-threshold={threshold}"), false),
127+
// m68k accepts the --m68k-ssection-threshold argument but then
128+
// ignores it, so this currently has no effect on m68k
129+
"m68k" => add(&format!("--m68k-ssection-threshold={threshold}"), false),
130+
// There's currently no rustc support for the Lanai architecture, so this is untested
131+
"lanai" => add(&format!("--lanai-ssection-threshold={threshold}"), false),
132+
arch @ _ => {
133+
if arch.starts_with("mips") {
134+
add(&format!("--mips-ssection-threshold={threshold}"), false);
135+
}
136+
}
137+
}
138+
}
121139
}
122140

123141
if sess.opts.unstable_opts.llvm_time_trace {

compiler/rustc_interface/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,7 @@ fn test_codegen_options_tracking_hash() {
609609
tracked!(profile_generate, SwitchWithOptPath::Enabled(None));
610610
tracked!(profile_use, Some(PathBuf::from("abc")));
611611
tracked!(relocation_model, Some(RelocModel::Pic));
612+
tracked!(small_data_threshold, Some(16));
612613
tracked!(soft_float, true);
613614
tracked!(split_debuginfo, Some(SplitDebuginfo::Packed));
614615
tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0));

compiler/rustc_session/src/options.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1792,6 +1792,8 @@ written to standard error output)"),
17921792
simulate_remapped_rust_src_base: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
17931793
"simulate the effect of remap-debuginfo = true at bootstrapping by remapping path \
17941794
to rust's source base directory. only meant for testing purposes"),
1795+
small_data_threshold: Option<usize> = (None, parse_opt_number, [TRACKED],
1796+
"Set the threshold for objects to be stored in a \"small data\" section"),
17951797
span_debug: bool = (false, parse_bool, [UNTRACKED],
17961798
"forward proc_macro::Span's `Debug` impl to `Span`"),
17971799
/// o/w tests have closure@path
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# `small-data-threshold`
2+
3+
-----------------------
4+
5+
This flag controls the maximum static variable size that may be included in the
6+
"small data sections" (.sdata, .sbss) supported by some architectures (RISCV,
7+
MIPS, M68K, Hexagon). Can be set to `0` to disable the use of small data
8+
sections.
+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Test for -Z small_data_threshold=...
2+
// revisions: RISCV MIPS HEXAGON M68K
3+
// assembly-output: emit-asm
4+
// compile-flags: -Z small_data_threshold=4
5+
// [RISCV] compile-flags:--target=riscv32im-unknown-none-elf
6+
// [MIPS] compile-flags:--target=mips-unknown-linux-musl -C llvm-args=-relocation-model=static -C llvm-args=-membedded-data -C llvm-args=-mgpopt -C llvm-args=-target-abi=n64
7+
// [HEXAGON] compile-flags:--target=hexagon-unknown-linux-musl -C target-feature=+small-data -C llvm-args=--hexagon-statics-in-small-data
8+
// [M68K] compile-flags:--target=m68k-unknown-linux-gnu
9+
10+
#![feature(no_core, lang_items)]
11+
#![no_std]
12+
#![no_core]
13+
#![crate_type = "lib"]
14+
15+
#[lang = "sized"]
16+
trait Sized {}
17+
18+
#[lang = "drop_in_place"]
19+
fn drop_in_place<T>(_: *mut T) {}
20+
21+
#[used]
22+
#[no_mangle]
23+
// U is below the threshold, should be in sdata
24+
pub static mut U: u16 = 123;
25+
26+
#[used]
27+
#[no_mangle]
28+
// V is below the threshold, should be in sbss
29+
pub static mut V: u16 = 0;
30+
31+
#[used]
32+
#[no_mangle]
33+
// W is at the threshold, should be in sdata
34+
pub static mut W: u32 = 123;
35+
36+
#[used]
37+
#[no_mangle]
38+
// X is at the threshold, should be in sbss
39+
pub static mut X: u32 = 0;
40+
41+
#[used]
42+
#[no_mangle]
43+
// Y is over the threshold, should be in its own .data section
44+
pub static mut Y: u64 = 123;
45+
46+
#[used]
47+
#[no_mangle]
48+
/// Z is over the threshold, should be in its own .bss section
49+
pub static mut Z: u64 = 0;
50+
51+
// Currently, only RISCV successfully puts any objects in the small data
52+
// sections so the U/V/W/X tests are skipped on MIPS/Hexagon/M68K
53+
// RISCV: .section .sdata,
54+
// RISCV-NOT: .section
55+
// RISCV: U:
56+
// RISCV: .section .sbss
57+
// RISV-NOT: .section
58+
// RISCV: V:
59+
// RISCV .section .sdata
60+
// RISV-NOT: .section
61+
// RISCV: W:
62+
// RISCV: .section .sbss
63+
// RISV-NOT: .section
64+
// RISCV: X:
65+
// CHECK: .section .data.Y,
66+
// CHECK-NOT: .section
67+
// CHECK: Y:
68+
// CHECK: .section .bss.Z,
69+
// CHECK-NOT: .section
70+
// CHECK: Z:

0 commit comments

Comments
 (0)