Skip to content

Commit

Permalink
Auto merge of #70073 - wesleywiser:mir_opt_level_0, r=oli-obk
Browse files Browse the repository at this point in the history
Don't run various MIR optimizations at mir-opt-level=0

Add missing checks for mir-opt-level to non-essential MIR passes.

I verified that this can still bootstrap even with these passes disabled.

r? @oli-obk cc @RalfJung
  • Loading branch information
bors committed Apr 27, 2020
2 parents ef71df1 + f4dfb99 commit d81f559
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 55 deletions.
4 changes: 2 additions & 2 deletions src/librustc_mir/shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,13 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
instance,
None,
MirPhase::Const,
&[
&[&[
&add_moves_for_packed_drops::AddMovesForPackedDrops,
&no_landing_pads::NoLandingPads::new(tcx),
&remove_noop_landing_pads::RemoveNoopLandingPads,
&simplify::SimplifyCfg::new("make_shim"),
&add_call_guards::CriticalCallEdges,
],
]],
);

debug!("make_shim({:?}) = {:?}", instance, result);
Expand Down
5 changes: 0 additions & 5 deletions src/librustc_mir/transform/instcombine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ pub struct InstCombine;

impl<'tcx> MirPass<'tcx> for InstCombine {
fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) {
// We only run when optimizing MIR (at any level).
if tcx.sess.opts.debugging_opts.mir_opt_level == 0 {
return;
}

// First, find optimization opportunities. This is done in a pre-pass to keep the MIR
// read-only so that we can do global analyses on the MIR in the process (e.g.
// `Place::ty()`).
Expand Down
127 changes: 79 additions & 48 deletions src/librustc_mir/transform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ pub fn run_passes(
instance: InstanceDef<'tcx>,
promoted: Option<Promoted>,
mir_phase: MirPhase,
passes: &[&dyn MirPass<'tcx>],
passes: &[&[&dyn MirPass<'tcx>]],
) {
let phase_index = mir_phase.phase_index();

Expand Down Expand Up @@ -171,8 +171,10 @@ pub fn run_passes(
index += 1;
};

for pass in passes {
run_pass(*pass);
for pass_group in passes {
for pass in *pass_group {
run_pass(*pass);
}
}

body.phase = mir_phase;
Expand Down Expand Up @@ -222,11 +224,11 @@ fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal<Body<'_>> {
InstanceDef::Item(def_id),
None,
MirPhase::Const,
&[
&[&[
// What we need to do constant evaluation.
&simplify::SimplifyCfg::new("initial"),
&rustc_peek::SanityCheck,
],
]],
);
tcx.alloc_steal_mir(body)
}
Expand Down Expand Up @@ -255,11 +257,11 @@ fn mir_validated(
InstanceDef::Item(def_id),
None,
MirPhase::Validated,
&[
&[&[
// What we need to run borrowck etc.
&promote_pass,
&simplify::SimplifyCfg::new("qualify-consts"),
],
]],
);

let promoted = promote_pass.promoted_fragments.into_inner();
Expand All @@ -272,54 +274,83 @@ fn run_optimization_passes<'tcx>(
def_id: DefId,
promoted: Option<Promoted>,
) {
let post_borrowck_cleanup: &[&dyn MirPass<'tcx>] = &[
// Remove all things only needed by analysis
&no_landing_pads::NoLandingPads::new(tcx),
&simplify_branches::SimplifyBranches::new("initial"),
&remove_noop_landing_pads::RemoveNoopLandingPads,
&cleanup_post_borrowck::CleanupNonCodegenStatements,
&simplify::SimplifyCfg::new("early-opt"),
// These next passes must be executed together
&add_call_guards::CriticalCallEdges,
&elaborate_drops::ElaborateDrops,
&no_landing_pads::NoLandingPads::new(tcx),
// AddMovesForPackedDrops needs to run after drop
// elaboration.
&add_moves_for_packed_drops::AddMovesForPackedDrops,
// `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late,
// but before optimizations begin.
&add_retag::AddRetag,
&simplify::SimplifyCfg::new("elaborate-drops"),
// No lifetime analysis based on borrowing can be done from here on out.
];

let optimizations: &[&dyn MirPass<'tcx>] = &[
&unreachable_prop::UnreachablePropagation,
&uninhabited_enum_branching::UninhabitedEnumBranching,
&simplify::SimplifyCfg::new("after-uninhabited-enum-branching"),
&inline::Inline,
// Lowering generator control-flow and variables has to happen before we do anything else
// to them. We do this inside the "optimizations" block so that it can benefit from
// optimizations that run before, that might be harder to do on the state machine than MIR
// with async primitives.
&generator::StateTransform,
&instcombine::InstCombine,
&const_prop::ConstProp,
&simplify_branches::SimplifyBranches::new("after-const-prop"),
// Run deaggregation here because:
// 1. Some codegen backends require it
// 2. It creates additional possibilities for some MIR optimizations to trigger
// FIXME(#70073): Why is this done here and not in `post_borrowck_cleanup`?
&deaggregator::Deaggregator,
&copy_prop::CopyPropagation,
&simplify_branches::SimplifyBranches::new("after-copy-prop"),
&remove_noop_landing_pads::RemoveNoopLandingPads,
&simplify::SimplifyCfg::new("after-remove-noop-landing-pads"),
&simplify_try::SimplifyArmIdentity,
&simplify_try::SimplifyBranchSame,
&simplify::SimplifyCfg::new("final"),
&simplify::SimplifyLocals,
];

let no_optimizations: &[&dyn MirPass<'tcx>] = &[
// Even if we don't do optimizations, we still have to lower generators for codegen.
&generator::StateTransform,
// FIXME(#70073): This pass is responsible for both optimization as well as some lints.
&const_prop::ConstProp,
// Even if we don't do optimizations, still run deaggregation because some backends assume
// that deaggregation always occurs.
&deaggregator::Deaggregator,
];

let pre_codegen_cleanup: &[&dyn MirPass<'tcx>] = &[
&add_call_guards::CriticalCallEdges,
// Dump the end result for testing and debugging purposes.
&dump_mir::Marker("PreCodegen"),
];

let mir_opt_level = tcx.sess.opts.debugging_opts.mir_opt_level;

run_passes(
tcx,
body,
InstanceDef::Item(def_id),
promoted,
MirPhase::Optimized,
&[
// Remove all things only needed by analysis
&no_landing_pads::NoLandingPads::new(tcx),
&simplify_branches::SimplifyBranches::new("initial"),
&remove_noop_landing_pads::RemoveNoopLandingPads,
&cleanup_post_borrowck::CleanupNonCodegenStatements,
&simplify::SimplifyCfg::new("early-opt"),
// These next passes must be executed together
&add_call_guards::CriticalCallEdges,
&elaborate_drops::ElaborateDrops,
&no_landing_pads::NoLandingPads::new(tcx),
// AddMovesForPackedDrops needs to run after drop
// elaboration.
&add_moves_for_packed_drops::AddMovesForPackedDrops,
// `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late,
// but before optimizations begin.
&add_retag::AddRetag,
&simplify::SimplifyCfg::new("elaborate-drops"),
// No lifetime analysis based on borrowing can be done from here on out.

// Optimizations begin.
&unreachable_prop::UnreachablePropagation,
&uninhabited_enum_branching::UninhabitedEnumBranching,
&simplify::SimplifyCfg::new("after-uninhabited-enum-branching"),
&inline::Inline,
// Lowering generator control-flow and variables
// has to happen before we do anything else to them.
&generator::StateTransform,
&instcombine::InstCombine,
&const_prop::ConstProp,
&simplify_branches::SimplifyBranches::new("after-const-prop"),
&deaggregator::Deaggregator,
&copy_prop::CopyPropagation,
&simplify_branches::SimplifyBranches::new("after-copy-prop"),
&remove_noop_landing_pads::RemoveNoopLandingPads,
&simplify::SimplifyCfg::new("after-remove-noop-landing-pads"),
&simplify_try::SimplifyArmIdentity,
&simplify_try::SimplifyBranchSame,
&simplify::SimplifyCfg::new("final"),
&simplify::SimplifyLocals,
&add_call_guards::CriticalCallEdges,
&dump_mir::Marker("PreCodegen"),
post_borrowck_cleanup,
if mir_opt_level > 0 { optimizations } else { no_optimizations },
pre_codegen_cleanup,
],
);
}
Expand Down

0 comments on commit d81f559

Please sign in to comment.