Rollup merge of #82376 - tmiasko:inline-options, r=oli-obk

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).
This commit is contained in:
Yuki Okushi 2021-03-02 21:23:14 +09:00 committed by GitHub
commit ae5e024194
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 21 deletions

View File

@ -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);

View File

@ -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;
}
@ -343,9 +349,9 @@ impl Inliner<'tcx> {
let tcx = self.tcx;
let mut threshold = if callee_attrs.requests_inline() {
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)
};
// Give a bonus functions with a small number of blocks,

View File

@ -430,8 +430,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));
}
}

View File

@ -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"),