@@ -140,7 +140,7 @@ pub fn run_passes(
140
140
instance : InstanceDef < ' tcx > ,
141
141
promoted : Option < Promoted > ,
142
142
mir_phase : MirPhase ,
143
- passes : & [ & dyn MirPass < ' tcx > ] ,
143
+ passes : & [ & [ & dyn MirPass < ' tcx > ] ] ,
144
144
) {
145
145
let phase_index = mir_phase. phase_index ( ) ;
146
146
@@ -168,8 +168,10 @@ pub fn run_passes(
168
168
index += 1 ;
169
169
} ;
170
170
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
+ }
173
175
}
174
176
175
177
body. phase = mir_phase;
@@ -219,11 +221,11 @@ fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal<Body<'_>> {
219
221
InstanceDef :: Item ( def_id) ,
220
222
None ,
221
223
MirPhase :: Const ,
222
- & [
224
+ & [ & [
223
225
// What we need to do constant evaluation.
224
226
& simplify:: SimplifyCfg :: new ( "initial" ) ,
225
227
& rustc_peek:: SanityCheck ,
226
- ] ,
228
+ ] ] ,
227
229
) ;
228
230
tcx. alloc_steal_mir ( body)
229
231
}
@@ -244,11 +246,11 @@ fn mir_validated(
244
246
InstanceDef :: Item ( def_id) ,
245
247
None ,
246
248
MirPhase :: Validated ,
247
- & [
249
+ & [ & [
248
250
// What we need to run borrowck etc.
249
251
& promote_pass,
250
252
& simplify:: SimplifyCfg :: new ( "qualify-consts" ) ,
251
- ] ,
253
+ ] ] ,
252
254
) ;
253
255
254
256
let promoted = promote_pass. promoted_fragments . into_inner ( ) ;
@@ -261,54 +263,83 @@ fn run_optimization_passes<'tcx>(
261
263
def_id : DefId ,
262
264
promoted : Option < Promoted > ,
263
265
) {
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
+
264
333
run_passes (
265
334
tcx,
266
335
body,
267
336
InstanceDef :: Item ( def_id) ,
268
337
promoted,
269
338
MirPhase :: Optimized ,
270
339
& [
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,
312
343
] ,
313
344
) ;
314
345
}
0 commit comments