Skip to content

Commit

Permalink
Rollup merge of rust-lang#82376 - tmiasko:inline-options, r=oli-obk
Browse files Browse the repository at this point in the history
Add option to enable MIR inlining independently of mir-opt-level

Add `-Zinline-mir` option that enables MIR inlining independently of the
current MIR opt level. The primary use-case is enabling MIR inlining on the
default MIR opt level.

Turn inlining thresholds into optional values to make it possible to configure
different defaults depending on the current mir-opt-level (although thresholds
are yet to be used in such a manner).
  • Loading branch information
Dylan-DPC authored Feb 24, 2021
2 parents 5fdfc09 + 5c546be commit 936a488
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 21 deletions.
5 changes: 3 additions & 2 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,8 +557,9 @@ fn test_debugging_options_tracking_hash() {
tracked!(function_sections, Some(false));
tracked!(human_readable_cgu_names, true);
tracked!(inline_in_all_cgus, Some(true));
tracked!(inline_mir_threshold, 123);
tracked!(inline_mir_hint_threshold, 123);
tracked!(inline_mir, Some(true));
tracked!(inline_mir_threshold, Some(123));
tracked!(inline_mir_hint_threshold, Some(123));
tracked!(insert_sideeffect, true);
tracked!(instrument_coverage, true);
tracked!(instrument_mcount, true);
Expand Down
36 changes: 21 additions & 15 deletions compiler/rustc_mir/src/transform/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,27 @@ struct CallSite<'tcx> {
source_info: SourceInfo,
}

/// Returns true if MIR inlining is enabled in the current compilation session.
crate fn is_enabled(tcx: TyCtxt<'_>) -> bool {
if tcx.sess.opts.debugging_opts.instrument_coverage {
// Since `Inline` happens after `InstrumentCoverage`, the function-specific coverage
// counters can be invalidated, such as by merging coverage counter statements from
// a pre-inlined function into a different function. This kind of change is invalid,
// so inlining must be skipped. Note: This check is performed here so inlining can
// be disabled without preventing other optimizations (regardless of `mir_opt_level`).
return false;
}

if let Some(enabled) = tcx.sess.opts.debugging_opts.inline_mir {
return enabled;
}

tcx.sess.opts.debugging_opts.mir_opt_level >= 2
}

impl<'tcx> MirPass<'tcx> for Inline {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
// If you change this optimization level, also change the level in
// `mir_drops_elaborated_and_const_checked` for the call to `mir_inliner_callees`.
// Otherwise you will get an ICE about stolen MIR.
if tcx.sess.opts.debugging_opts.mir_opt_level < 2 {
return;
}

if tcx.sess.opts.debugging_opts.instrument_coverage {
// Since `Inline` happens after `InstrumentCoverage`, the function-specific coverage
// counters can be invalidated, such as by merging coverage counter statements from
// a pre-inlined function into a different function. This kind of change is invalid,
// so inlining must be skipped. Note: This check is performed here so inlining can
// be disabled without preventing other optimizations (regardless of `mir_opt_level`).
if !is_enabled(tcx) {
return;
}

Expand Down Expand Up @@ -310,9 +316,9 @@ impl Inliner<'tcx> {
}

let mut threshold = if hinted {
self.tcx.sess.opts.debugging_opts.inline_mir_hint_threshold
self.tcx.sess.opts.debugging_opts.inline_mir_hint_threshold.unwrap_or(100)
} else {
self.tcx.sess.opts.debugging_opts.inline_mir_threshold
self.tcx.sess.opts.debugging_opts.inline_mir_threshold.unwrap_or(50)
};

if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_mir/src/transform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,8 +428,7 @@ fn mir_drops_elaborated_and_const_checked<'tcx>(
let def = ty::WithOptConstParam::unknown(did);

// Do not compute the mir call graph without said call graph actually being used.
// Keep this in sync with the mir inliner's optimization level.
if tcx.sess.opts.debugging_opts.mir_opt_level >= 2 {
if inline::is_enabled(tcx) {
let _ = tcx.mir_inliner_callees(ty::InstanceDef::Item(def));
}
}
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -957,9 +957,11 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
(default: no)"),
incremental_verify_ich: bool = (false, parse_bool, [UNTRACKED],
"verify incr. comp. hashes of green query instances (default: no)"),
inline_mir_threshold: usize = (50, parse_uint, [TRACKED],
inline_mir: Option<bool> = (None, parse_opt_bool, [TRACKED],
"enable MIR inlining (default: no)"),
inline_mir_threshold: Option<usize> = (None, parse_opt_uint, [TRACKED],
"a default MIR inlining threshold (default: 50)"),
inline_mir_hint_threshold: usize = (100, parse_uint, [TRACKED],
inline_mir_hint_threshold: Option<usize> = (None, parse_opt_uint, [TRACKED],
"inlining threshold for functions with inline hint (default: 100)"),
inline_in_all_cgus: Option<bool> = (None, parse_opt_bool, [TRACKED],
"control whether `#[inline]` functions are in all CGUs"),
Expand Down

0 comments on commit 936a488

Please sign in to comment.