Skip to content

Commit 8198864

Browse files
authored
Rollup merge of #117650 - saethlin:inline-me-please, r=davidtwco
Add -Zcross-crate-inline-threshold=yes ``@thomcc`` says this would be useful for > seeing if it makes a difference in some code if i do it when building the sysroot, since -Zbuild-std + lto helps more than it seems like it should And I've changed the possible values as a reference to ``@Manishearth`` saying > LLVM's inlining heuristic is "yes".
2 parents ba7ec56 + fcdd99e commit 8198864

File tree

10 files changed

+161
-13
lines changed

10 files changed

+161
-13
lines changed

compiler/rustc_interface/src/tests.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ use rustc_data_structures::profiling::TimePassesFormat;
44
use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
55
use rustc_session::config::{
66
build_configuration, build_session_options, rustc_optgroups, BranchProtection, CFGuard, Cfg,
7-
DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs, Input,
8-
InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli,
9-
MirSpanview, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet,
10-
Passes, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion,
11-
TraitSolver, WasiExecModel,
7+
DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs,
8+
InliningThreshold, Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained,
9+
LinkerPluginLto, LocationDetail, LtoCli, MirSpanview, OomStrategy, Options, OutFileName,
10+
OutputType, OutputTypes, PAuthKey, PacRet, Passes, Polonius, ProcMacroExecutionStrategy, Strip,
11+
SwitchWithOptPath, SymbolManglingVersion, TraitSolver, WasiExecModel,
1212
};
1313
use rustc_session::lint::Level;
1414
use rustc_session::search_paths::SearchPath;
@@ -748,7 +748,7 @@ fn test_unstable_options_tracking_hash() {
748748
);
749749
tracked!(codegen_backend, Some("abc".to_string()));
750750
tracked!(crate_attr, vec!["abc".to_string()]);
751-
tracked!(cross_crate_inline_threshold, Some(200));
751+
tracked!(cross_crate_inline_threshold, InliningThreshold::Always);
752752
tracked!(debug_info_for_profiling, true);
753753
tracked!(debug_macros, true);
754754
tracked!(dep_info_omit_d_target, true);

compiler/rustc_mir_transform/src/cross_crate_inline.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_middle::mir::visit::Visitor;
77
use rustc_middle::mir::*;
88
use rustc_middle::query::Providers;
99
use rustc_middle::ty::TyCtxt;
10+
use rustc_session::config::InliningThreshold;
1011
use rustc_session::config::OptLevel;
1112

1213
pub fn provide(providers: &mut Providers) {
@@ -54,15 +55,20 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
5455
return false;
5556
}
5657

58+
let threshold = match tcx.sess.opts.unstable_opts.cross_crate_inline_threshold {
59+
InliningThreshold::Always => return true,
60+
InliningThreshold::Sometimes(threshold) => threshold,
61+
InliningThreshold::Never => return false,
62+
};
63+
5764
let mir = tcx.optimized_mir(def_id);
5865
let mut checker =
5966
CostChecker { tcx, callee_body: mir, calls: 0, statements: 0, landing_pads: 0, resumes: 0 };
6067
checker.visit_body(mir);
6168
checker.calls == 0
6269
&& checker.resumes == 0
6370
&& checker.landing_pads == 0
64-
&& checker.statements
65-
<= tcx.sess.opts.unstable_opts.cross_crate_inline_threshold.unwrap_or(100)
71+
&& checker.statements <= threshold
6672
}
6773

6874
struct CostChecker<'b, 'tcx> {

compiler/rustc_session/src/config.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -3161,10 +3161,10 @@ impl PpMode {
31613161
pub(crate) mod dep_tracking {
31623162
use super::{
31633163
BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, DebugInfoCompression,
3164-
ErrorOutputType, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
3165-
LtoCli, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes, Polonius,
3166-
RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind,
3167-
SwitchWithOptPath, SymbolManglingVersion, TraitSolver, TrimmedDefPaths,
3164+
ErrorOutputType, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto,
3165+
LocationDetail, LtoCli, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes,
3166+
Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm,
3167+
SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, TraitSolver, TrimmedDefPaths,
31683168
};
31693169
use crate::lint;
31703170
use crate::options::WasiExecModel;
@@ -3270,6 +3270,7 @@ pub(crate) mod dep_tracking {
32703270
LanguageIdentifier,
32713271
TraitSolver,
32723272
Polonius,
3273+
InliningThreshold,
32733274
);
32743275

32753276
impl<T1, T2> DepTrackingHash for (T1, T2)
@@ -3435,3 +3436,16 @@ impl Polonius {
34353436
matches!(self, Polonius::Next)
34363437
}
34373438
}
3439+
3440+
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
3441+
pub enum InliningThreshold {
3442+
Always,
3443+
Sometimes(usize),
3444+
Never,
3445+
}
3446+
3447+
impl Default for InliningThreshold {
3448+
fn default() -> Self {
3449+
Self::Sometimes(100)
3450+
}
3451+
}

compiler/rustc_session/src/options.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,8 @@ mod desc {
428428
"one of supported execution strategies (`same-thread`, or `cross-thread`)";
429429
pub const parse_dump_solver_proof_tree: &str = "one of: `always`, `on-request`, `on-error`";
430430
pub const parse_remap_path_scope: &str = "comma separated list of scopes: `macro`, `diagnostics`, `unsplit-debuginfo`, `split-debuginfo`, `split-debuginfo-path`, `object`, `all`";
431+
pub const parse_inlining_threshold: &str =
432+
"either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
431433
}
432434

433435
mod parse {
@@ -1310,6 +1312,26 @@ mod parse {
13101312
};
13111313
true
13121314
}
1315+
1316+
pub(crate) fn parse_inlining_threshold(slot: &mut InliningThreshold, v: Option<&str>) -> bool {
1317+
match v {
1318+
Some("always" | "yes") => {
1319+
*slot = InliningThreshold::Always;
1320+
}
1321+
Some("never") => {
1322+
*slot = InliningThreshold::Never;
1323+
}
1324+
Some(v) => {
1325+
if let Ok(threshold) = v.parse() {
1326+
*slot = InliningThreshold::Sometimes(threshold);
1327+
} else {
1328+
return false;
1329+
}
1330+
}
1331+
None => return false,
1332+
}
1333+
true
1334+
}
13131335
}
13141336

13151337
options! {
@@ -1479,7 +1501,7 @@ options! {
14791501
"combine CGUs into a single one"),
14801502
crate_attr: Vec<String> = (Vec::new(), parse_string_push, [TRACKED],
14811503
"inject the given attribute in the crate"),
1482-
cross_crate_inline_threshold: Option<usize> = (None, parse_opt_number, [TRACKED],
1504+
cross_crate_inline_threshold: InliningThreshold = (InliningThreshold::Sometimes(100), parse_inlining_threshold, [TRACKED],
14831505
"threshold to allow cross crate inlining of functions"),
14841506
debug_info_for_profiling: bool = (false, parse_bool, [TRACKED],
14851507
"emit discriminators and other data necessary for AutoFDO"),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// compile-flags: -O
2+
// aux-build:always.rs
3+
4+
#![crate_type = "lib"]
5+
6+
extern crate always;
7+
8+
// Check that we inline a cross-crate call, even though it isn't a leaf
9+
#[no_mangle]
10+
pub fn outer() -> String {
11+
// CHECK-NOT: call {{.*}}stem_fn
12+
always::stem_fn()
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// compile-flags: -O -Zcross-crate-inline-threshold=always
2+
3+
#![crate_type = "lib"]
4+
5+
// This function *looks* like it contains a call, but that call will be optimized out by MIR
6+
// optimizations.
7+
pub fn leaf_fn() -> String {
8+
String::new()
9+
}
10+
11+
// This function contains a call, even after MIR optimizations. It is only eligible for
12+
// cross-crate-inlining with "always".
13+
pub fn stem_fn() -> String {
14+
inner()
15+
}
16+
17+
#[inline(never)]
18+
fn inner() -> String {
19+
String::from("test")
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// compile-flags: -O
2+
3+
#![crate_type = "lib"]
4+
5+
// This function *looks* like it contains a call, but that call will be optimized out by MIR
6+
// optimizations.
7+
pub fn leaf_fn() -> String {
8+
String::new()
9+
}
10+
11+
// This function contains a call, even after MIR optimizations. It is only eligible for
12+
// cross-crate-inlining with "always".
13+
pub fn stem_fn() -> String {
14+
inner()
15+
}
16+
17+
#[inline(never)]
18+
fn inner() -> String {
19+
String::from("test")
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// compile-flags: -O -Zcross-crate-inline-threshold=never
2+
3+
#![crate_type = "lib"]
4+
5+
// This function *looks* like it contains a call, but that call will be optimized out by MIR
6+
// optimizations.
7+
pub fn leaf_fn() -> String {
8+
String::new()
9+
}
10+
11+
// This function contains a call, even after MIR optimizations. It is only eligible for
12+
// cross-crate-inlining with "always".
13+
pub fn stem_fn() -> String {
14+
inner()
15+
}
16+
17+
#[inline(never)]
18+
fn inner() -> String {
19+
String::from("test")
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// compile-flags: -O -Zcross-crate-inline-threshold=yes
2+
// aux-build:leaf.rs
3+
4+
#![crate_type = "lib"]
5+
6+
extern crate leaf;
7+
8+
// Check that we inline a leaf cross-crate call
9+
#[no_mangle]
10+
pub fn leaf_outer() -> String {
11+
// CHECK-NOT: call {{.*}}leaf_fn
12+
leaf::leaf_fn()
13+
}
14+
15+
// Check that we do not inline a non-leaf cross-crate call
16+
#[no_mangle]
17+
pub fn stem_outer() -> String {
18+
// CHECK: call {{.*}}stem_fn
19+
leaf::stem_fn()
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// compile-flags: -O
2+
// aux-build:never.rs
3+
4+
#![crate_type = "lib"]
5+
6+
extern crate never;
7+
8+
// Check that we do not inline a cross-crate call, even though it is a leaf
9+
#[no_mangle]
10+
pub fn outer() -> String {
11+
// CHECK: call {{.*}}leaf_fn
12+
never::leaf_fn()
13+
}

0 commit comments

Comments
 (0)