Rollup merge of #82736 - spastorino:mir-opt-level-perf-changes, r=oli-obk
Bump optimization from mir_opt_level 2 to 3 and 3 to 4 and make "release" be level 2 by default r? `@oli-obk`
This commit is contained in:
commit
15c148b4f2
85 changed files with 117 additions and 109 deletions
|
@ -566,7 +566,7 @@ fn test_debugging_options_tracking_hash() {
|
|||
tracked!(link_only, true);
|
||||
tracked!(merge_functions, Some(MergeFunctions::Disabled));
|
||||
tracked!(mir_emit_retag, true);
|
||||
tracked!(mir_opt_level, 3);
|
||||
tracked!(mir_opt_level, Some(4));
|
||||
tracked!(mutable_noalias, true);
|
||||
tracked!(new_llvm_pass_manager, true);
|
||||
tracked!(no_codegen, true);
|
||||
|
|
|
@ -28,7 +28,7 @@ pub struct ConstGoto;
|
|||
|
||||
impl<'tcx> MirPass<'tcx> for ConstGoto {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
if tcx.sess.opts.debugging_opts.mir_opt_level < 3 {
|
||||
if tcx.sess.mir_opt_level() < 4 {
|
||||
return;
|
||||
}
|
||||
trace!("Running ConstGoto on {:?}", body.source);
|
||||
|
|
|
@ -725,7 +725,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
return None;
|
||||
}
|
||||
|
||||
if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 3 {
|
||||
if self.tcx.sess.mir_opt_level() >= 4 {
|
||||
self.eval_rvalue_with_identities(rvalue, place)
|
||||
} else {
|
||||
self.use_ecx(|this| this.ecx.eval_rvalue_into_place(rvalue, place))
|
||||
|
@ -903,7 +903,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
|
||||
/// Returns `true` if and only if this `op` should be const-propagated into.
|
||||
fn should_const_prop(&mut self, op: &OpTy<'tcx>) -> bool {
|
||||
let mir_opt_level = self.tcx.sess.opts.debugging_opts.mir_opt_level;
|
||||
let mir_opt_level = self.tcx.sess.mir_opt_level();
|
||||
|
||||
if mir_opt_level == 0 {
|
||||
return false;
|
||||
|
@ -1071,9 +1071,9 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
|
|||
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) {
|
||||
self.super_operand(operand, location);
|
||||
|
||||
// Only const prop copies and moves on `mir_opt_level=2` as doing so
|
||||
// Only const prop copies and moves on `mir_opt_level=3` as doing so
|
||||
// currently slightly increases compile time in some cases.
|
||||
if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2 {
|
||||
if self.tcx.sess.mir_opt_level() >= 3 {
|
||||
self.propagate_operand(operand)
|
||||
}
|
||||
}
|
||||
|
@ -1253,7 +1253,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
|
|||
TerminatorKind::SwitchInt { ref mut discr, .. } => {
|
||||
// FIXME: This is currently redundant with `visit_operand`, but sadly
|
||||
// always visiting operands currently causes a perf regression in LLVM codegen, so
|
||||
// `visit_operand` currently only runs for propagates places for `mir_opt_level=3`.
|
||||
// `visit_operand` currently only runs for propagates places for `mir_opt_level=4`.
|
||||
self.propagate_operand(discr)
|
||||
}
|
||||
// None of these have Operands to const-propagate.
|
||||
|
@ -1272,7 +1272,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
|
|||
// Every argument in our function calls have already been propagated in `visit_operand`.
|
||||
//
|
||||
// NOTE: because LLVM codegen gives slight performance regressions with it, so this is
|
||||
// gated on `mir_opt_level=2`.
|
||||
// gated on `mir_opt_level=3`.
|
||||
TerminatorKind::Call { .. } => {}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ pub struct DeduplicateBlocks;
|
|||
|
||||
impl<'tcx> MirPass<'tcx> for DeduplicateBlocks {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
if tcx.sess.opts.debugging_opts.mir_opt_level < 3 {
|
||||
if tcx.sess.mir_opt_level() < 4 {
|
||||
return;
|
||||
}
|
||||
debug!("Running DeduplicateBlocks on `{:?}`", body.source);
|
||||
|
|
|
@ -127,9 +127,9 @@ pub struct DestinationPropagation;
|
|||
|
||||
impl<'tcx> MirPass<'tcx> for DestinationPropagation {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
// Only run at mir-opt-level=2 or higher for now (we don't fix up debuginfo and remove
|
||||
// Only run at mir-opt-level=3 or higher for now (we don't fix up debuginfo and remove
|
||||
// storage statements at the moment).
|
||||
if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 {
|
||||
if tcx.sess.mir_opt_level() < 3 {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ pub struct EarlyOtherwiseBranch;
|
|||
|
||||
impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
if tcx.sess.opts.debugging_opts.mir_opt_level < 2 {
|
||||
if tcx.sess.mir_opt_level() < 3 {
|
||||
return;
|
||||
}
|
||||
trace!("running EarlyOtherwiseBranch on {:?}", body.source);
|
||||
|
|
|
@ -52,7 +52,7 @@ crate fn is_enabled(tcx: TyCtxt<'_>) -> bool {
|
|||
return enabled;
|
||||
}
|
||||
|
||||
tcx.sess.opts.debugging_opts.mir_opt_level >= 2
|
||||
tcx.sess.mir_opt_level() >= 3
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for Inline {
|
||||
|
|
|
@ -40,7 +40,7 @@ pub struct MatchBranchSimplification;
|
|||
|
||||
impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 {
|
||||
if tcx.sess.mir_opt_level() < 3 {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -475,7 +475,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc
|
|||
}
|
||||
|
||||
fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let mir_opt_level = tcx.sess.opts.debugging_opts.mir_opt_level;
|
||||
let mir_opt_level = tcx.sess.mir_opt_level();
|
||||
|
||||
// Lowering generator control-flow and variables has to happen before we do anything else
|
||||
// to them. We run some optimizations before that, because they may be harder to do on the state
|
||||
|
|
|
@ -10,7 +10,7 @@ pub struct MultipleReturnTerminators;
|
|||
|
||||
impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
if tcx.sess.opts.debugging_opts.mir_opt_level < 3 {
|
||||
if tcx.sess.mir_opt_level() < 4 {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ pub struct RenameReturnPlace;
|
|||
|
||||
impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut mir::Body<'tcx>) {
|
||||
if tcx.sess.opts.debugging_opts.mir_opt_level == 0 {
|
||||
if tcx.sess.mir_opt_level() == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ pub struct UnreachablePropagation;
|
|||
|
||||
impl MirPass<'_> for UnreachablePropagation {
|
||||
fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
if tcx.sess.opts.debugging_opts.mir_opt_level < 3 {
|
||||
// Enable only under -Zmir-opt-level=3 as in some cases (check the deeply-nested-opt
|
||||
if tcx.sess.mir_opt_level() < 4 {
|
||||
// Enable only under -Zmir-opt-level=4 as in some cases (check the deeply-nested-opt
|
||||
// perf benchmark) LLVM may spend quite a lot of time optimizing the generated code.
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1938,21 +1938,23 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
|||
Some(SymbolManglingVersion::V0) => {}
|
||||
}
|
||||
|
||||
if debugging_opts.mir_opt_level > 1 {
|
||||
// Functions inlined during MIR transform can, at best, make it impossible to
|
||||
// effectively cover inlined functions, and, at worst, break coverage map generation
|
||||
// during LLVM codegen. For example, function counter IDs are only unique within a
|
||||
// function. Inlining after these counters are injected can produce duplicate counters,
|
||||
// resulting in an invalid coverage map (and ICE); so this option combination is not
|
||||
// allowed.
|
||||
early_warn(
|
||||
error_format,
|
||||
&format!(
|
||||
"`-Z mir-opt-level={}` (or any level > 1) enables function inlining, which \
|
||||
if let Some(mir_opt_level) = debugging_opts.mir_opt_level {
|
||||
if mir_opt_level > 1 {
|
||||
// Functions inlined during MIR transform can, at best, make it impossible to
|
||||
// effectively cover inlined functions, and, at worst, break coverage map generation
|
||||
// during LLVM codegen. For example, function counter IDs are only unique within a
|
||||
// function. Inlining after these counters are injected can produce duplicate counters,
|
||||
// resulting in an invalid coverage map (and ICE); so this option combination is not
|
||||
// allowed.
|
||||
early_warn(
|
||||
error_format,
|
||||
&format!(
|
||||
"`-Z mir-opt-level={}` (or any level > 1) enables function inlining, which \
|
||||
is incompatible with `-Z instrument-coverage`. Inlining will be disabled.",
|
||||
debugging_opts.mir_opt_level,
|
||||
),
|
||||
);
|
||||
mir_opt_level,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -999,8 +999,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
|
|||
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
|
||||
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
|
||||
(default: no)"),
|
||||
mir_opt_level: usize = (1, parse_uint, [TRACKED],
|
||||
"MIR optimization level (0-3; default: 1)"),
|
||||
mir_opt_level: Option<usize> = (None, parse_opt_uint, [TRACKED],
|
||||
"MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"),
|
||||
mutable_noalias: bool = (false, parse_bool, [TRACKED],
|
||||
"emit noalias metadata for mutable references (default: no)"),
|
||||
new_llvm_pass_manager: bool = (false, parse_bool, [TRACKED],
|
||||
|
|
|
@ -640,6 +640,12 @@ impl Session {
|
|||
pub fn binary_dep_depinfo(&self) -> bool {
|
||||
self.opts.debugging_opts.binary_dep_depinfo
|
||||
}
|
||||
pub fn mir_opt_level(&self) -> usize {
|
||||
self.opts
|
||||
.debugging_opts
|
||||
.mir_opt_level
|
||||
.unwrap_or_else(|| if self.opts.optimize != config::OptLevel::No { 2 } else { 1 })
|
||||
}
|
||||
|
||||
/// Gets the features enabled for the current compilation session.
|
||||
/// DO NOT USE THIS METHOD if there is a TyCtxt available, as it circumvents
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue