From f895f1c35a99eed6a173d4e699a71abc1b9823ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sun, 21 Feb 2021 00:00:00 +0000 Subject: [PATCH 1/2] Add option enabling MIR inlining independently of mir-opt-level --- compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_mir/src/transform/inline.rs | 32 +++++++++++++--------- compiler/rustc_mir/src/transform/mod.rs | 3 +- compiler/rustc_session/src/options.rs | 2 ++ 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index a2e96146568..c0816b10ebb 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -557,6 +557,7 @@ 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, Some(true)); tracked!(inline_mir_threshold, 123); tracked!(inline_mir_hint_threshold, 123); tracked!(insert_sideeffect, true); diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index 16279040a1c..daf91c676a1 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -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; } diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs index a79f855965a..56a7d337e0b 100644 --- a/compiler/rustc_mir/src/transform/mod.rs +++ b/compiler/rustc_mir/src/transform/mod.rs @@ -429,8 +429,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)); } } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index d439753d042..55691463a1f 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -957,6 +957,8 @@ 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: Option = (None, parse_opt_bool, [TRACKED], + "enable MIR inlining (default: no)"), inline_mir_threshold: usize = (50, parse_uint, [TRACKED], "a default MIR inlining threshold (default: 50)"), inline_mir_hint_threshold: usize = (100, parse_uint, [TRACKED], From 500aeccc5b3135cc5a400faa3b739abaed87d722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sun, 21 Feb 2021 00:00:00 +0000 Subject: [PATCH 2/2] Use optional values for inlining thresholds Turn inlining threshold into optional values to make it possible to configure different defaults depending on the current mir-opt-level. --- compiler/rustc_interface/src/tests.rs | 4 ++-- compiler/rustc_mir/src/transform/inline.rs | 4 ++-- compiler/rustc_session/src/options.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index c0816b10ebb..9a11b534887 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -558,8 +558,8 @@ fn test_debugging_options_tracking_hash() { tracked!(human_readable_cgu_names, true); tracked!(inline_in_all_cgus, Some(true)); tracked!(inline_mir, Some(true)); - tracked!(inline_mir_threshold, 123); - tracked!(inline_mir_hint_threshold, 123); + 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); diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index daf91c676a1..16410175bd2 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -349,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, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 55691463a1f..e2b6b1dc243 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -959,9 +959,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "verify incr. comp. hashes of green query instances (default: no)"), inline_mir: Option = (None, parse_opt_bool, [TRACKED], "enable MIR inlining (default: no)"), - inline_mir_threshold: usize = (50, parse_uint, [TRACKED], + inline_mir_threshold: Option = (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 = (None, parse_opt_uint, [TRACKED], "inlining threshold for functions with inline hint (default: 100)"), inline_in_all_cgus: Option = (None, parse_opt_bool, [TRACKED], "control whether `#[inline]` functions are in all CGUs"),