Skip to content

Commit a618f74

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 d9d89fd commit a618f74

File tree

6 files changed

+134
-0
lines changed

6 files changed

+134
-0
lines changed

compiler/rustc_codegen_llvm/src/context.rs

+13
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,19 @@ pub unsafe fn create_module<'ll>(
357357
)
358358
}
359359

360+
if let Some(threshold) = sess.opts.unstable_opts.small_data_threshold {
361+
// Set up the small-data optimization limit for architectures that use
362+
// an LLVM module flag to control this.
363+
if sess.target.arch.starts_with("riscv") {
364+
llvm::LLVMRustAddModuleFlag(
365+
llmod,
366+
llvm::LLVMModFlagBehavior::Error,
367+
"SmallDataLimit\0".as_ptr().cast(),
368+
threshold as u32,
369+
)
370+
}
371+
}
372+
360373
// Insert `llvm.ident` metadata.
361374
//
362375
// 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
@@ -116,6 +116,24 @@ unsafe fn configure_llvm(sess: &Session) {
116116
for arg in sess_args {
117117
add(&(*arg), true);
118118
}
119+
120+
if let Some(threshold) = sess.opts.unstable_opts.small_data_threshold {
121+
// Set up the small-data optimization limit for architectures that use
122+
// an LLVM argument to control this.
123+
match sess.target.arch.as_ref() {
124+
"hexagon" => add(&format!("--hexagon-small-data-threshold={threshold}"), false),
125+
// m68k accepts the --m68k-ssection-threshold argument but then
126+
// ignores it, so this currently has no effect on m68k
127+
"m68k" => add(&format!("--m68k-ssection-threshold={threshold}"), false),
128+
// There's currently no rustc support for the Lanai architecture, so this is untested
129+
"lanai" => add(&format!("--lanai-ssection-threshold={threshold}"), false),
130+
arch @ _ => {
131+
if arch.starts_with("mips") {
132+
add(&format!("--mips-ssection-threshold={threshold}"), false);
133+
}
134+
}
135+
}
136+
}
119137
}
120138

121139
if sess.opts.unstable_opts.llvm_time_trace {

compiler/rustc_interface/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,7 @@ fn test_unstable_options_tracking_hash() {
816816
tracked!(share_generics, Some(true));
817817
tracked!(show_span, Some(String::from("abc")));
818818
tracked!(simulate_remapped_rust_src_base, Some(PathBuf::from("/rustc/abc")));
819+
tracked!(small_data_threshold, Some(16));
819820
tracked!(split_lto_unit, Some(true));
820821
tracked!(src_hash_algorithm, Some(SourceFileHashAlgorithm::Sha1));
821822
tracked!(stack_protector, StackProtector::All);

compiler/rustc_session/src/options.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1870,6 +1870,8 @@ written to standard error output)"),
18701870
simulate_remapped_rust_src_base: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
18711871
"simulate the effect of remap-debuginfo = true at bootstrapping by remapping path \
18721872
to rust's source base directory. only meant for testing purposes"),
1873+
small_data_threshold: Option<usize> = (None, parse_opt_number, [TRACKED],
1874+
"Set the threshold for objects to be stored in a \"small data\" section"),
18731875
span_debug: bool = (false, parse_bool, [UNTRACKED],
18741876
"forward proc_macro::Span's `Debug` impl to `Span`"),
18751877
/// 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.
+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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+
// [RISCV] needs-llvm-components: riscv
7+
// [MIPS] compile-flags: --target=mips-unknown-linux-uclibc -C relocation-model=static
8+
// [MIPS] compile-flags: -C llvm-args=-mgpopt -C llvm-args=-mlocal-sdata
9+
// [MIPS] compile-flags: -C target-feature=+noabicalls
10+
// [MIPS] needs-llvm-components: mips
11+
// [HEXAGON] compile-flags: --target=hexagon-unknown-linux-musl -C target-feature=+small-data
12+
// [HEXAGON] compile-flags: -C llvm-args=--hexagon-statics-in-small-data
13+
// [HEXAGON] needs-llvm-components: hexagon
14+
// [M68K] compile-flags: --target=m68k-unknown-linux-gnu
15+
// [M68K] needs-llvm-components: m68k
16+
17+
#![feature(no_core, lang_items)]
18+
#![no_std]
19+
#![no_core]
20+
#![crate_type = "lib"]
21+
22+
#[lang = "sized"]
23+
trait Sized {}
24+
25+
#[lang = "drop_in_place"]
26+
fn drop_in_place<T>(_: *mut T) {}
27+
28+
#[used]
29+
#[no_mangle]
30+
// U is below the threshold, should be in sdata
31+
static mut U: u16 = 123;
32+
33+
#[used]
34+
#[no_mangle]
35+
// V is below the threshold, should be in sbss
36+
static mut V: u16 = 0;
37+
38+
#[used]
39+
#[no_mangle]
40+
// W is at the threshold, should be in sdata
41+
static mut W: u32 = 123;
42+
43+
#[used]
44+
#[no_mangle]
45+
// X is at the threshold, should be in sbss
46+
static mut X: u32 = 0;
47+
48+
#[used]
49+
#[no_mangle]
50+
// Y is over the threshold, should be in its own .data section
51+
static mut Y: u64 = 123;
52+
53+
#[used]
54+
#[no_mangle]
55+
/// Z is over the threshold, should be in its own .bss section
56+
static mut Z: u64 = 0;
57+
58+
// Currently, only MIPS and RISCV successfully put any objects in the small data
59+
// sections so the U/V/W/X tests are skipped on Hexagon and M68K
60+
61+
// RISCV: .section .sdata,
62+
// RISCV-NOT: .section
63+
// RISCV: U:
64+
// RISCV: .section .sbss
65+
// RISV-NOT: .section
66+
// RISCV: V:
67+
// RISCV .section .sdata
68+
// RISV-NOT: .section
69+
// RISCV: W:
70+
// RISCV: .section .sbss
71+
// RISV-NOT: .section
72+
// RISCV: X:
73+
74+
// MIPS: .section .sdata,
75+
// MIPS-NOT: .section
76+
// MIPS: U:
77+
// MIPS: .section .sbss
78+
// RISV-NOT: .section
79+
// MIPS: V:
80+
// MIPS .section .sdata
81+
// RISV-NOT: .section
82+
// MIPS: W:
83+
// MIPS: .section .sbss
84+
// RISV-NOT: .section
85+
// MIPS: X:
86+
87+
// CHECK: .section .data.Y,
88+
// CHECK-NOT: .section
89+
// CHECK: Y:
90+
// CHECK: .section .bss.Z,
91+
// CHECK-NOT: .section
92+
// CHECK: Z:

0 commit comments

Comments
 (0)