Skip to content

Commit 497794d

Browse files
committed
add -Zmin-function-alignment
1 parent 9c707a8 commit 497794d

File tree

5 files changed

+58
-1
lines changed

5 files changed

+58
-1
lines changed

compiler/rustc_codegen_llvm/src/attributes.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,11 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
480480
let allocated_pointer = AttributeKind::AllocatedPointer.create_attr(cx.llcx);
481481
attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), &[allocated_pointer]);
482482
}
483-
if let Some(align) = codegen_fn_attrs.alignment {
483+
// function alignment can be set globally with the `-Zmin-function-alignment=<n>` flag;
484+
// the alignment from a `#[repr(align(<n>))]` is used if it specifies a higher alignment.
485+
if let Some(align) =
486+
Ord::max(cx.tcx.sess.opts.unstable_opts.min_function_alignment, codegen_fn_attrs.alignment)
487+
{
484488
llvm::set_alignment(llfn, align);
485489
}
486490
if let Some(backchain) = backchain_attr(cx) {

compiler/rustc_interface/src/tests.rs

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use rustc_span::edition::{DEFAULT_EDITION, Edition};
2525
use rustc_span::source_map::{RealFileLoader, SourceMapInputs};
2626
use rustc_span::symbol::sym;
2727
use rustc_span::{FileName, SourceFileHashAlgorithm};
28+
use rustc_target::abi::Align;
2829
use rustc_target::spec::{
2930
CodeModel, FramePointer, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy,
3031
RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel, WasmCAbi,
@@ -803,6 +804,7 @@ fn test_unstable_options_tracking_hash() {
803804
tracked!(location_detail, LocationDetail { file: true, line: false, column: false });
804805
tracked!(maximal_hir_to_mir_coverage, true);
805806
tracked!(merge_functions, Some(MergeFunctions::Disabled));
807+
tracked!(min_function_alignment, Some(Align::EIGHT));
806808
tracked!(mir_emit_retag, true);
807809
tracked!(mir_enable_passes, vec![("DestProp".to_string(), false)]);
808810
tracked!(mir_keep_place_mention, true);

compiler/rustc_session/src/config.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2884,6 +2884,7 @@ pub(crate) mod dep_tracking {
28842884
use std::num::NonZero;
28852885
use std::path::PathBuf;
28862886

2887+
use rustc_abi::Align;
28872888
use rustc_data_structures::fx::FxIndexMap;
28882889
use rustc_data_structures::stable_hasher::Hash64;
28892890
use rustc_errors::LanguageIdentifier;
@@ -3003,6 +3004,7 @@ pub(crate) mod dep_tracking {
30033004
InliningThreshold,
30043005
FunctionReturn,
30053006
WasmCAbi,
3007+
Align,
30063008
);
30073009

30083010
impl<T1, T2> DepTrackingHash for (T1, T2)

compiler/rustc_session/src/options.rs

+19
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::num::{IntErrorKind, NonZero};
44
use std::path::PathBuf;
55
use std::str;
66

7+
use rustc_abi::Align;
78
use rustc_data_structures::fx::FxIndexMap;
89
use rustc_data_structures::profiling::TimePassesFormat;
910
use rustc_data_structures::stable_hasher::Hash64;
@@ -453,6 +454,7 @@ mod desc {
453454
pub(crate) const parse_wasm_c_abi: &str = "`legacy` or `spec`";
454455
pub(crate) const parse_mir_include_spans: &str =
455456
"either a boolean (`yes`, `no`, `on`, `off`, etc), or `nll` (default: `nll`)";
457+
pub(crate) const parse_align: &str = "a number that is a power of 2 between 1 and 2^29";
456458
}
457459

458460
pub mod parse {
@@ -1521,6 +1523,21 @@ pub mod parse {
15211523

15221524
true
15231525
}
1526+
1527+
pub(crate) fn parse_align(slot: &mut Option<Align>, v: Option<&str>) -> bool {
1528+
let mut bytes = 0u64;
1529+
if !parse_number(&mut bytes, v) {
1530+
return false;
1531+
}
1532+
1533+
let Ok(align) = Align::from_bytes(bytes) else {
1534+
return false;
1535+
};
1536+
1537+
*slot = Some(align);
1538+
1539+
true
1540+
}
15241541
}
15251542

15261543
options! {
@@ -1876,6 +1893,8 @@ options! {
18761893
"gather metadata statistics (default: no)"),
18771894
metrics_dir: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
18781895
"the directory metrics emitted by rustc are dumped into (implicitly enables default set of metrics)"),
1896+
min_function_alignment: Option<Align> = (None, parse_align, [TRACKED],
1897+
"align all functions to at least this many bytes. Must be a power of 2"),
18791898
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
18801899
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
18811900
(default: no)"),
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 -Zmin-function-alignment=16
2+
3+
#![crate_type = "lib"]
4+
#![feature(fn_align)]
5+
6+
// functions without explicit alignment use the global minimum
7+
//
8+
// CHECK: align 16
9+
#[no_mangle]
10+
pub fn no_explicit_align() {}
11+
12+
// CHECK: align 16
13+
#[no_mangle]
14+
#[repr(align(8))]
15+
pub fn lower_align() {}
16+
17+
// CHECK: align 32
18+
#[no_mangle]
19+
#[repr(align(32))]
20+
pub fn higher_align() {}
21+
22+
// cold functions follow the same rules as other functions
23+
//
24+
// in GCC, the `-falign-functions` does not apply to cold functions, but
25+
// `-Zmin-function-alignment` applies to all functions.
26+
//
27+
// CHECK: align 16
28+
#[no_mangle]
29+
#[cold]
30+
pub fn no_explicit_align_cold() {}

0 commit comments

Comments
 (0)