Skip to content

Commit

Permalink
add -Zmin-function-alignment
Browse files Browse the repository at this point in the history
  • Loading branch information
folkertdev committed Dec 8, 2024
1 parent 9c707a8 commit 497794d
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 1 deletion.
6 changes: 5 additions & 1 deletion compiler/rustc_codegen_llvm/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,11 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
let allocated_pointer = AttributeKind::AllocatedPointer.create_attr(cx.llcx);
attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), &[allocated_pointer]);
}
if let Some(align) = codegen_fn_attrs.alignment {
// function alignment can be set globally with the `-Zmin-function-alignment=<n>` flag;
// the alignment from a `#[repr(align(<n>))]` is used if it specifies a higher alignment.
if let Some(align) =
Ord::max(cx.tcx.sess.opts.unstable_opts.min_function_alignment, codegen_fn_attrs.alignment)
{
llvm::set_alignment(llfn, align);
}
if let Some(backchain) = backchain_attr(cx) {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use rustc_span::edition::{DEFAULT_EDITION, Edition};
use rustc_span::source_map::{RealFileLoader, SourceMapInputs};
use rustc_span::symbol::sym;
use rustc_span::{FileName, SourceFileHashAlgorithm};
use rustc_target::abi::Align;
use rustc_target::spec::{
CodeModel, FramePointer, LinkerFlavorCli, MergeFunctions, OnBrokenPipe, PanicStrategy,
RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel, WasmCAbi,
Expand Down Expand Up @@ -803,6 +804,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(location_detail, LocationDetail { file: true, line: false, column: false });
tracked!(maximal_hir_to_mir_coverage, true);
tracked!(merge_functions, Some(MergeFunctions::Disabled));
tracked!(min_function_alignment, Some(Align::EIGHT));
tracked!(mir_emit_retag, true);
tracked!(mir_enable_passes, vec![("DestProp".to_string(), false)]);
tracked!(mir_keep_place_mention, true);
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2884,6 +2884,7 @@ pub(crate) mod dep_tracking {
use std::num::NonZero;
use std::path::PathBuf;

use rustc_abi::Align;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::stable_hasher::Hash64;
use rustc_errors::LanguageIdentifier;
Expand Down Expand Up @@ -3003,6 +3004,7 @@ pub(crate) mod dep_tracking {
InliningThreshold,
FunctionReturn,
WasmCAbi,
Align,
);

impl<T1, T2> DepTrackingHash for (T1, T2)
Expand Down
19 changes: 19 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::num::{IntErrorKind, NonZero};
use std::path::PathBuf;
use std::str;

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

pub mod parse {
Expand Down Expand Up @@ -1521,6 +1523,21 @@ pub mod parse {

true
}

pub(crate) fn parse_align(slot: &mut Option<Align>, v: Option<&str>) -> bool {
let mut bytes = 0u64;
if !parse_number(&mut bytes, v) {
return false;
}

let Ok(align) = Align::from_bytes(bytes) else {
return false;
};

*slot = Some(align);

true
}
}

options! {
Expand Down Expand Up @@ -1876,6 +1893,8 @@ options! {
"gather metadata statistics (default: no)"),
metrics_dir: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
"the directory metrics emitted by rustc are dumped into (implicitly enables default set of metrics)"),
min_function_alignment: Option<Align> = (None, parse_align, [TRACKED],
"align all functions to at least this many bytes. Must be a power of 2"),
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
(default: no)"),
Expand Down
30 changes: 30 additions & 0 deletions tests/codegen/min-function-alignment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 -Zmin-function-alignment=16

#![crate_type = "lib"]
#![feature(fn_align)]

// functions without explicit alignment use the global minimum
//
// CHECK: align 16
#[no_mangle]
pub fn no_explicit_align() {}

// CHECK: align 16
#[no_mangle]
#[repr(align(8))]
pub fn lower_align() {}

// CHECK: align 32
#[no_mangle]
#[repr(align(32))]
pub fn higher_align() {}

// cold functions follow the same rules as other functions
//
// in GCC, the `-falign-functions` does not apply to cold functions, but
// `-Zmin-function-alignment` applies to all functions.
//
// CHECK: align 16
#[no_mangle]
#[cold]
pub fn no_explicit_align_cold() {}

0 comments on commit 497794d

Please sign in to comment.