@@ -143,7 +143,7 @@ pub fn run_passes(
143
143
instance : InstanceDef < ' tcx > ,
144
144
promoted : Option < Promoted > ,
145
145
mir_phase : MirPhase ,
146
- passes : & [ & dyn MirPass < ' tcx > ] ,
146
+ passes : & [ & [ & dyn MirPass < ' tcx > ] ] ,
147
147
) {
148
148
let phase_index = mir_phase. phase_index ( ) ;
149
149
@@ -171,8 +171,10 @@ pub fn run_passes(
171
171
index += 1 ;
172
172
} ;
173
173
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
+ }
176
178
}
177
179
178
180
body. phase = mir_phase;
@@ -222,11 +224,11 @@ fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal<Body<'_>> {
222
224
InstanceDef :: Item ( def_id) ,
223
225
None ,
224
226
MirPhase :: Const ,
225
- & [
227
+ & [ & [
226
228
// What we need to do constant evaluation.
227
229
& simplify:: SimplifyCfg :: new ( "initial" ) ,
228
230
& rustc_peek:: SanityCheck ,
229
- ] ,
231
+ ] ] ,
230
232
) ;
231
233
tcx. alloc_steal_mir ( body)
232
234
}
@@ -255,11 +257,11 @@ fn mir_validated(
255
257
InstanceDef :: Item ( def_id) ,
256
258
None ,
257
259
MirPhase :: Validated ,
258
- & [
260
+ & [ & [
259
261
// What we need to run borrowck etc.
260
262
& promote_pass,
261
263
& simplify:: SimplifyCfg :: new ( "qualify-consts" ) ,
262
- ] ,
264
+ ] ] ,
263
265
) ;
264
266
265
267
let promoted = promote_pass. promoted_fragments . into_inner ( ) ;
@@ -272,54 +274,83 @@ fn run_optimization_passes<'tcx>(
272
274
def_id : DefId ,
273
275
promoted : Option < Promoted > ,
274
276
) {
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
+
275
344
run_passes (
276
345
tcx,
277
346
body,
278
347
InstanceDef :: Item ( def_id) ,
279
348
promoted,
280
349
MirPhase :: Optimized ,
281
350
& [
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,
323
354
] ,
324
355
) ;
325
356
}
0 commit comments