@@ -140,7 +140,7 @@ pub fn run_passes(
140140 instance : InstanceDef < ' tcx > ,
141141 promoted : Option < Promoted > ,
142142 mir_phase : MirPhase ,
143- passes : & [ & dyn MirPass < ' tcx > ] ,
143+ passes : & [ & [ & dyn MirPass < ' tcx > ] ] ,
144144) {
145145 let phase_index = mir_phase. phase_index ( ) ;
146146
@@ -168,8 +168,10 @@ pub fn run_passes(
168168 index += 1 ;
169169 } ;
170170
171- for pass in passes {
172- run_pass ( * pass) ;
171+ for pass_group in passes {
172+ for pass in * pass_group {
173+ run_pass ( * pass) ;
174+ }
173175 }
174176
175177 body. phase = mir_phase;
@@ -219,11 +221,11 @@ fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal<Body<'_>> {
219221 InstanceDef :: Item ( def_id) ,
220222 None ,
221223 MirPhase :: Const ,
222- & [
224+ & [ & [
223225 // What we need to do constant evaluation.
224226 & simplify:: SimplifyCfg :: new ( "initial" ) ,
225227 & rustc_peek:: SanityCheck ,
226- ] ,
228+ ] ] ,
227229 ) ;
228230 tcx. alloc_steal_mir ( body)
229231}
@@ -244,11 +246,11 @@ fn mir_validated(
244246 InstanceDef :: Item ( def_id) ,
245247 None ,
246248 MirPhase :: Validated ,
247- & [
249+ & [ & [
248250 // What we need to run borrowck etc.
249251 & promote_pass,
250252 & simplify:: SimplifyCfg :: new ( "qualify-consts" ) ,
251- ] ,
253+ ] ] ,
252254 ) ;
253255
254256 let promoted = promote_pass. promoted_fragments . into_inner ( ) ;
@@ -261,54 +263,83 @@ fn run_optimization_passes<'tcx>(
261263 def_id : DefId ,
262264 promoted : Option < Promoted > ,
263265) {
266+ let post_borrowck_cleanup: & [ & dyn MirPass < ' tcx > ] = & [
267+ // Remove all things only needed by analysis
268+ & no_landing_pads:: NoLandingPads :: new ( tcx) ,
269+ & simplify_branches:: SimplifyBranches :: new ( "initial" ) ,
270+ & remove_noop_landing_pads:: RemoveNoopLandingPads ,
271+ & cleanup_post_borrowck:: CleanupNonCodegenStatements ,
272+ & simplify:: SimplifyCfg :: new ( "early-opt" ) ,
273+ // These next passes must be executed together
274+ & add_call_guards:: CriticalCallEdges ,
275+ & elaborate_drops:: ElaborateDrops ,
276+ & no_landing_pads:: NoLandingPads :: new ( tcx) ,
277+ // AddMovesForPackedDrops needs to run after drop
278+ // elaboration.
279+ & add_moves_for_packed_drops:: AddMovesForPackedDrops ,
280+ // `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late,
281+ // but before optimizations begin.
282+ & add_retag:: AddRetag ,
283+ & simplify:: SimplifyCfg :: new ( "elaborate-drops" ) ,
284+ // No lifetime analysis based on borrowing can be done from here on out.
285+ ] ;
286+
287+ let optimizations: & [ & dyn MirPass < ' tcx > ] = & [
288+ & unreachable_prop:: UnreachablePropagation ,
289+ & uninhabited_enum_branching:: UninhabitedEnumBranching ,
290+ & simplify:: SimplifyCfg :: new ( "after-uninhabited-enum-branching" ) ,
291+ & inline:: Inline ,
292+ // Lowering generator control-flow and variables has to happen before we do anything else
293+ // to them. We do this inside the "optimizations" block so that it can benefit from
294+ // optimizations that run before, that might be harder to do on the state machine than MIR
295+ // with async primitives.
296+ & generator:: StateTransform ,
297+ & instcombine:: InstCombine ,
298+ & const_prop:: ConstProp ,
299+ & simplify_branches:: SimplifyBranches :: new ( "after-const-prop" ) ,
300+ // Run deaggregation here because:
301+ // 1. Some codegen backends require it
302+ // 2. It creates additional possibilities for some MIR optimizations to trigger
303+ // FIXME(#70073): Why is this done here and not in `post_borrowck_cleanup`?
304+ & deaggregator:: Deaggregator ,
305+ & copy_prop:: CopyPropagation ,
306+ & simplify_branches:: SimplifyBranches :: new ( "after-copy-prop" ) ,
307+ & remove_noop_landing_pads:: RemoveNoopLandingPads ,
308+ & simplify:: SimplifyCfg :: new ( "after-remove-noop-landing-pads" ) ,
309+ & simplify_try:: SimplifyArmIdentity ,
310+ & simplify_try:: SimplifyBranchSame ,
311+ & simplify:: SimplifyCfg :: new ( "final" ) ,
312+ & simplify:: SimplifyLocals ,
313+ ] ;
314+
315+ let no_optimizations: & [ & dyn MirPass < ' tcx > ] = & [
316+ // Even if we don't do optimizations, we still have to lower generators for codegen.
317+ & generator:: StateTransform ,
318+ // FIXME(#70073): This pass is responsible for both optimization as well as some lints.
319+ & const_prop:: ConstProp ,
320+ // Even if we don't do optimizations, still run deaggregation because some backends assume
321+ // that deaggregation always occurs.
322+ & deaggregator:: Deaggregator ,
323+ ] ;
324+
325+ let pre_codegen_cleanup: & [ & dyn MirPass < ' tcx > ] = & [
326+ & add_call_guards:: CriticalCallEdges ,
327+ // Dump the end result for testing and debugging purposes.
328+ & dump_mir:: Marker ( "PreCodegen" ) ,
329+ ] ;
330+
331+ let mir_opt_level = tcx. sess . opts . debugging_opts . mir_opt_level ;
332+
264333 run_passes (
265334 tcx,
266335 body,
267336 InstanceDef :: Item ( def_id) ,
268337 promoted,
269338 MirPhase :: Optimized ,
270339 & [
271- // Remove all things only needed by analysis
272- & no_landing_pads:: NoLandingPads :: new ( tcx) ,
273- & simplify_branches:: SimplifyBranches :: new ( "initial" ) ,
274- & remove_noop_landing_pads:: RemoveNoopLandingPads ,
275- & cleanup_post_borrowck:: CleanupNonCodegenStatements ,
276- & simplify:: SimplifyCfg :: new ( "early-opt" ) ,
277- // These next passes must be executed together
278- & add_call_guards:: CriticalCallEdges ,
279- & elaborate_drops:: ElaborateDrops ,
280- & no_landing_pads:: NoLandingPads :: new ( tcx) ,
281- // AddMovesForPackedDrops needs to run after drop
282- // elaboration.
283- & add_moves_for_packed_drops:: AddMovesForPackedDrops ,
284- // `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late,
285- // but before optimizations begin.
286- & add_retag:: AddRetag ,
287- & simplify:: SimplifyCfg :: new ( "elaborate-drops" ) ,
288- // No lifetime analysis based on borrowing can be done from here on out.
289-
290- // Optimizations begin.
291- & unreachable_prop:: UnreachablePropagation ,
292- & uninhabited_enum_branching:: UninhabitedEnumBranching ,
293- & simplify:: SimplifyCfg :: new ( "after-uninhabited-enum-branching" ) ,
294- & inline:: Inline ,
295- // Lowering generator control-flow and variables
296- // has to happen before we do anything else to them.
297- & generator:: StateTransform ,
298- & instcombine:: InstCombine ,
299- & const_prop:: ConstProp ,
300- & simplify_branches:: SimplifyBranches :: new ( "after-const-prop" ) ,
301- & deaggregator:: Deaggregator ,
302- & copy_prop:: CopyPropagation ,
303- & simplify_branches:: SimplifyBranches :: new ( "after-copy-prop" ) ,
304- & remove_noop_landing_pads:: RemoveNoopLandingPads ,
305- & simplify:: SimplifyCfg :: new ( "after-remove-noop-landing-pads" ) ,
306- & simplify_try:: SimplifyArmIdentity ,
307- & simplify_try:: SimplifyBranchSame ,
308- & simplify:: SimplifyCfg :: new ( "final" ) ,
309- & simplify:: SimplifyLocals ,
310- & add_call_guards:: CriticalCallEdges ,
311- & dump_mir:: Marker ( "PreCodegen" ) ,
340+ post_borrowck_cleanup,
341+ if mir_opt_level > 0 { optimizations } else { no_optimizations } ,
342+ pre_codegen_cleanup,
312343 ] ,
313344 ) ;
314345}
0 commit comments