@@ -143,7 +143,7 @@ pub fn run_passes(
143143 instance : InstanceDef < ' tcx > ,
144144 promoted : Option < Promoted > ,
145145 mir_phase : MirPhase ,
146- passes : & [ & dyn MirPass < ' tcx > ] ,
146+ passes : & [ & [ & dyn MirPass < ' tcx > ] ] ,
147147) {
148148 let phase_index = mir_phase. phase_index ( ) ;
149149
@@ -171,8 +171,10 @@ pub fn run_passes(
171171 index += 1 ;
172172 } ;
173173
174- for pass in passes {
175- run_pass ( * pass) ;
174+ for pass_group in passes {
175+ for pass in * pass_group {
176+ run_pass ( * pass) ;
177+ }
176178 }
177179
178180 body. phase = mir_phase;
@@ -222,11 +224,11 @@ fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal<Body<'_>> {
222224 InstanceDef :: Item ( def_id) ,
223225 None ,
224226 MirPhase :: Const ,
225- & [
227+ & [ & [
226228 // What we need to do constant evaluation.
227229 & simplify:: SimplifyCfg :: new ( "initial" ) ,
228230 & rustc_peek:: SanityCheck ,
229- ] ,
231+ ] ] ,
230232 ) ;
231233 tcx. alloc_steal_mir ( body)
232234}
@@ -255,11 +257,11 @@ fn mir_validated(
255257 InstanceDef :: Item ( def_id) ,
256258 None ,
257259 MirPhase :: Validated ,
258- & [
260+ & [ & [
259261 // What we need to run borrowck etc.
260262 & promote_pass,
261263 & simplify:: SimplifyCfg :: new ( "qualify-consts" ) ,
262- ] ,
264+ ] ] ,
263265 ) ;
264266
265267 let promoted = promote_pass. promoted_fragments . into_inner ( ) ;
@@ -272,54 +274,83 @@ fn run_optimization_passes<'tcx>(
272274 def_id : DefId ,
273275 promoted : Option < Promoted > ,
274276) {
277+ let post_borrowck_cleanup: & [ & dyn MirPass < ' tcx > ] = & [
278+ // Remove all things only needed by analysis
279+ & no_landing_pads:: NoLandingPads :: new ( tcx) ,
280+ & simplify_branches:: SimplifyBranches :: new ( "initial" ) ,
281+ & remove_noop_landing_pads:: RemoveNoopLandingPads ,
282+ & cleanup_post_borrowck:: CleanupNonCodegenStatements ,
283+ & simplify:: SimplifyCfg :: new ( "early-opt" ) ,
284+ // These next passes must be executed together
285+ & add_call_guards:: CriticalCallEdges ,
286+ & elaborate_drops:: ElaborateDrops ,
287+ & no_landing_pads:: NoLandingPads :: new ( tcx) ,
288+ // AddMovesForPackedDrops needs to run after drop
289+ // elaboration.
290+ & add_moves_for_packed_drops:: AddMovesForPackedDrops ,
291+ // `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late,
292+ // but before optimizations begin.
293+ & add_retag:: AddRetag ,
294+ & simplify:: SimplifyCfg :: new ( "elaborate-drops" ) ,
295+ // No lifetime analysis based on borrowing can be done from here on out.
296+ ] ;
297+
298+ let optimizations: & [ & dyn MirPass < ' tcx > ] = & [
299+ & unreachable_prop:: UnreachablePropagation ,
300+ & uninhabited_enum_branching:: UninhabitedEnumBranching ,
301+ & simplify:: SimplifyCfg :: new ( "after-uninhabited-enum-branching" ) ,
302+ & inline:: Inline ,
303+ // Lowering generator control-flow and variables has to happen before we do anything else
304+ // to them. We do this inside the "optimizations" block so that it can benefit from
305+ // optimizations that run before, that might be harder to do on the state machine than MIR
306+ // with async primitives.
307+ & generator:: StateTransform ,
308+ & instcombine:: InstCombine ,
309+ & const_prop:: ConstProp ,
310+ & simplify_branches:: SimplifyBranches :: new ( "after-const-prop" ) ,
311+ // Run deaggregation here because:
312+ // 1. Some codegen backends require it
313+ // 2. It creates additional possibilities for some MIR optimizations to trigger
314+ // FIXME(#70073): Why is this done here and not in `post_borrowck_cleanup`?
315+ & deaggregator:: Deaggregator ,
316+ & copy_prop:: CopyPropagation ,
317+ & simplify_branches:: SimplifyBranches :: new ( "after-copy-prop" ) ,
318+ & remove_noop_landing_pads:: RemoveNoopLandingPads ,
319+ & simplify:: SimplifyCfg :: new ( "after-remove-noop-landing-pads" ) ,
320+ & simplify_try:: SimplifyArmIdentity ,
321+ & simplify_try:: SimplifyBranchSame ,
322+ & simplify:: SimplifyCfg :: new ( "final" ) ,
323+ & simplify:: SimplifyLocals ,
324+ ] ;
325+
326+ let no_optimizations: & [ & dyn MirPass < ' tcx > ] = & [
327+ // Even if we don't do optimizations, we still have to lower generators for codegen.
328+ & generator:: StateTransform ,
329+ // FIXME(#70073): This pass is responsible for both optimization as well as some lints.
330+ & const_prop:: ConstProp ,
331+ // Even if we don't do optimizations, still run deaggregation because some backends assume
332+ // that deaggregation always occurs.
333+ & deaggregator:: Deaggregator ,
334+ ] ;
335+
336+ let pre_codegen_cleanup: & [ & dyn MirPass < ' tcx > ] = & [
337+ & add_call_guards:: CriticalCallEdges ,
338+ // Dump the end result for testing and debugging purposes.
339+ & dump_mir:: Marker ( "PreCodegen" ) ,
340+ ] ;
341+
342+ let mir_opt_level = tcx. sess . opts . debugging_opts . mir_opt_level ;
343+
275344 run_passes (
276345 tcx,
277346 body,
278347 InstanceDef :: Item ( def_id) ,
279348 promoted,
280349 MirPhase :: Optimized ,
281350 & [
282- // Remove all things only needed by analysis
283- & no_landing_pads:: NoLandingPads :: new ( tcx) ,
284- & simplify_branches:: SimplifyBranches :: new ( "initial" ) ,
285- & remove_noop_landing_pads:: RemoveNoopLandingPads ,
286- & cleanup_post_borrowck:: CleanupNonCodegenStatements ,
287- & simplify:: SimplifyCfg :: new ( "early-opt" ) ,
288- // These next passes must be executed together
289- & add_call_guards:: CriticalCallEdges ,
290- & elaborate_drops:: ElaborateDrops ,
291- & no_landing_pads:: NoLandingPads :: new ( tcx) ,
292- // AddMovesForPackedDrops needs to run after drop
293- // elaboration.
294- & add_moves_for_packed_drops:: AddMovesForPackedDrops ,
295- // `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late,
296- // but before optimizations begin.
297- & add_retag:: AddRetag ,
298- & simplify:: SimplifyCfg :: new ( "elaborate-drops" ) ,
299- // No lifetime analysis based on borrowing can be done from here on out.
300-
301- // Optimizations begin.
302- & unreachable_prop:: UnreachablePropagation ,
303- & uninhabited_enum_branching:: UninhabitedEnumBranching ,
304- & simplify:: SimplifyCfg :: new ( "after-uninhabited-enum-branching" ) ,
305- & inline:: Inline ,
306- // Lowering generator control-flow and variables
307- // has to happen before we do anything else to them.
308- & generator:: StateTransform ,
309- & instcombine:: InstCombine ,
310- & const_prop:: ConstProp ,
311- & simplify_branches:: SimplifyBranches :: new ( "after-const-prop" ) ,
312- & deaggregator:: Deaggregator ,
313- & copy_prop:: CopyPropagation ,
314- & simplify_branches:: SimplifyBranches :: new ( "after-copy-prop" ) ,
315- & remove_noop_landing_pads:: RemoveNoopLandingPads ,
316- & simplify:: SimplifyCfg :: new ( "after-remove-noop-landing-pads" ) ,
317- & simplify_try:: SimplifyArmIdentity ,
318- & simplify_try:: SimplifyBranchSame ,
319- & simplify:: SimplifyCfg :: new ( "final" ) ,
320- & simplify:: SimplifyLocals ,
321- & add_call_guards:: CriticalCallEdges ,
322- & dump_mir:: Marker ( "PreCodegen" ) ,
351+ post_borrowck_cleanup,
352+ if mir_opt_level > 0 { optimizations } else { no_optimizations } ,
353+ pre_codegen_cleanup,
323354 ] ,
324355 ) ;
325356}
0 commit comments