@@ -27,15 +27,15 @@ use rustc_hir::def_id::{DefId, LocalDefId};
2727use rustc_hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
2828use rustc_index:: vec:: IndexVec ;
2929use rustc_middle:: mir:: visit:: Visitor as _;
30- use rustc_middle:: mir:: { dump_mir , traversal, Body , ConstQualifs , MirPass , MirPhase , Promoted } ;
30+ use rustc_middle:: mir:: { traversal, Body , ConstQualifs , MirPass , MirPhase , Promoted } ;
3131use rustc_middle:: ty:: query:: Providers ;
3232use rustc_middle:: ty:: { self , TyCtxt , TypeFoldable } ;
3333use rustc_span:: { Span , Symbol } ;
3434
3535#[ macro_use]
3636mod pass_manager;
3737
38- use pass_manager:: { Lint , MirLint } ;
38+ use pass_manager:: { self as pm , Lint , MirLint } ;
3939
4040mod abort_unwinding_calls;
4141mod add_call_guards;
@@ -174,66 +174,6 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxHashSet<LocalDefId> {
174174 set
175175}
176176
177- fn run_passes (
178- tcx : TyCtxt < ' tcx > ,
179- body : & mut Body < ' tcx > ,
180- mir_phase : MirPhase ,
181- passes : & [ & [ & dyn MirPass < ' tcx > ] ] ,
182- ) {
183- let phase_index = mir_phase. phase_index ( ) ;
184- let validate = tcx. sess . opts . debugging_opts . validate_mir ;
185-
186- if body. phase >= mir_phase {
187- return ;
188- }
189-
190- if validate {
191- validate:: Validator { when : format ! ( "input to phase {:?}" , mir_phase) , mir_phase }
192- . run_pass ( tcx, body) ;
193- }
194-
195- let mut index = 0 ;
196- let mut run_pass = |pass : & dyn MirPass < ' tcx > | {
197- let run_hooks = |body : & _ , index, is_after| {
198- let disambiguator = if is_after { "after" } else { "before" } ;
199- dump_mir (
200- tcx,
201- Some ( & format_args ! ( "{:03}-{:03}" , phase_index, index) ) ,
202- & pass. name ( ) ,
203- & disambiguator,
204- body,
205- |_, _| Ok ( ( ) ) ,
206- ) ;
207- } ;
208- run_hooks ( body, index, false ) ;
209- pass. run_pass ( tcx, body) ;
210- run_hooks ( body, index, true ) ;
211-
212- if validate {
213- validate:: Validator {
214- when : format ! ( "after {} in phase {:?}" , pass. name( ) , mir_phase) ,
215- mir_phase,
216- }
217- . run_pass ( tcx, body) ;
218- }
219-
220- index += 1 ;
221- } ;
222-
223- for pass_group in passes {
224- for pass in * pass_group {
225- run_pass ( * pass) ;
226- }
227- }
228-
229- body. phase = mir_phase;
230-
231- if mir_phase == MirPhase :: Optimization {
232- validate:: Validator { when : format ! ( "end of phase {:?}" , mir_phase) , mir_phase }
233- . run_pass ( tcx, body) ;
234- }
235- }
236-
237177fn mir_const_qualif ( tcx : TyCtxt < ' _ > , def : ty:: WithOptConstParam < LocalDefId > ) -> ConstQualifs {
238178 let const_kind = tcx. hir ( ) . body_const_context ( def. did ) ;
239179
@@ -285,19 +225,19 @@ fn mir_const<'tcx>(
285225
286226 rustc_middle:: mir:: dump_mir ( tcx, None , "mir_map" , & 0 , & body, |_, _| Ok ( ( ) ) ) ;
287227
288- run_passes (
228+ pm :: run_passes (
289229 tcx,
290230 & mut body,
291- MirPhase :: Const ,
292- & [ & [
231+ & [
293232 // MIR-level lints.
294233 & Lint ( check_packed_ref:: CheckPackedRef ) ,
295234 & Lint ( check_const_item_mutation:: CheckConstItemMutation ) ,
296235 & Lint ( function_item_references:: FunctionItemReferences ) ,
297236 // What we need to do constant evaluation.
298237 & simplify:: SimplifyCfg :: new ( "initial" ) ,
299238 & rustc_peek:: SanityCheck , // Just a lint
300- ] ] ,
239+ & marker:: PhaseChange ( MirPhase :: Const ) ,
240+ ] ,
301241 ) ;
302242 tcx. alloc_steal_mir ( body)
303243}
@@ -324,17 +264,17 @@ fn mir_promoted(
324264 }
325265 body. required_consts = required_consts;
326266
267+ // What we need to run borrowck etc.
327268 let promote_pass = promote_consts:: PromoteTemps :: default ( ) ;
328- let promote: & [ & dyn MirPass < ' tcx > ] = & [
329- // What we need to run borrowck etc.
330- & promote_pass,
331- & simplify:: SimplifyCfg :: new ( "promote-consts" ) ,
332- ] ;
333-
334- let opt_coverage: & [ & dyn MirPass < ' tcx > ] =
335- if tcx. sess . instrument_coverage ( ) { & [ & coverage:: InstrumentCoverage ] } else { & [ ] } ;
336-
337- run_passes ( tcx, & mut body, MirPhase :: ConstPromotion , & [ promote, opt_coverage] ) ;
269+ pm:: run_passes (
270+ tcx,
271+ & mut body,
272+ & [
273+ & promote_pass,
274+ & simplify:: SimplifyCfg :: new ( "promote-consts" ) ,
275+ & coverage:: InstrumentCoverage ,
276+ ] ,
277+ ) ;
338278
339279 let promoted = promote_pass. promoted_fragments . into_inner ( ) ;
340280 ( tcx. alloc_steal_mir ( body) , tcx. alloc_steal_promoted ( promoted) )
@@ -396,19 +336,10 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -
396336 // Technically we want to not run on regular const items, but oli-obk doesn't know how to
397337 // conveniently detect that at this point without looking at the HIR.
398338 hir:: ConstContext :: Const => {
399- #[ rustfmt:: skip]
400- let optimizations: & [ & dyn MirPass < ' _ > ] = & [
401- & const_prop:: ConstProp ,
402- ] ;
403-
404- #[ rustfmt:: skip]
405- run_passes (
339+ pm:: run_passes (
406340 tcx,
407341 & mut body,
408- MirPhase :: Optimization ,
409- & [
410- optimizations,
411- ] ,
342+ & [ & const_prop:: ConstProp , & marker:: PhaseChange ( MirPhase :: Optimization ) ] ,
412343 ) ;
413344 }
414345 }
@@ -453,19 +384,23 @@ fn mir_drops_elaborated_and_const_checked<'tcx>(
453384 let mut body = body. steal ( ) ;
454385
455386 // IMPORTANT
456- remove_false_edges :: RemoveFalseEdges . run_pass ( tcx, & mut body) ;
387+ pm :: run_passes ( tcx, & mut body, & [ & remove_false_edges :: RemoveFalseEdges ] ) ;
457388
458389 // Do a little drop elaboration before const-checking if `const_precise_live_drops` is enabled.
459- //
460- // FIXME: Can't use `run_passes` for these, since `run_passes` SILENTLY DOES NOTHING IF THE MIR
461- // PHASE DOESN'T CHANGE.
462390 if check_consts:: post_drop_elaboration:: checking_enabled ( & ConstCx :: new ( tcx, & body) ) {
463- simplify:: SimplifyCfg :: new ( "remove-false-edges" ) . run_pass ( tcx, & mut body) ;
464- remove_uninit_drops:: RemoveUninitDrops . run_pass ( tcx, & mut body) ;
465- check_consts:: post_drop_elaboration:: check_live_drops ( tcx, & body) ;
391+ pm:: run_passes (
392+ tcx,
393+ & mut body,
394+ & [
395+ & simplify:: SimplifyCfg :: new ( "remove-false-edges" ) ,
396+ & remove_uninit_drops:: RemoveUninitDrops ,
397+ ] ,
398+ ) ;
399+ check_consts:: post_drop_elaboration:: check_live_drops ( tcx, & body) ; // FIXME: make this a MIR lint
466400 }
467401
468402 run_post_borrowck_cleanup_passes ( tcx, & mut body) ;
403+ assert ! ( body. phase == MirPhase :: DropLowering ) ;
469404 tcx. alloc_steal_mir ( body)
470405}
471406
@@ -499,95 +434,65 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc
499434 & deaggregator:: Deaggregator ,
500435 ] ;
501436
502- run_passes ( tcx, body, MirPhase :: DropLowering , & [ post_borrowck_cleanup] ) ;
437+ pm :: run_passes ( tcx, body, post_borrowck_cleanup) ;
503438}
504439
505440fn run_optimization_passes < ' tcx > ( tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
506- let mir_opt_level = tcx. sess . mir_opt_level ( ) ;
507-
508441 // Lowering generator control-flow and variables has to happen before we do anything else
509442 // to them. We run some optimizations before that, because they may be harder to do on the state
510443 // machine than on MIR with async primitives.
511- let optimizations_with_generators: & [ & dyn MirPass < ' tcx > ] = & [
512- & reveal_all:: RevealAll , // has to be done before inlining, since inlined code is in RevealAll mode.
513- & lower_slice_len:: LowerSliceLenCalls , // has to be done before inlining, otherwise actual call will be almost always inlined. Also simple, so can just do first
514- & normalize_array_len:: NormalizeArrayLen , // has to run after `slice::len` lowering
515- & unreachable_prop:: UnreachablePropagation ,
516- & uninhabited_enum_branching:: UninhabitedEnumBranching ,
517- & simplify:: SimplifyCfg :: new ( "after-uninhabited-enum-branching" ) ,
518- & inline:: Inline ,
519- & generator:: StateTransform ,
520- ] ;
521-
522- // Even if we don't do optimizations, we still have to lower generators for codegen.
523- let no_optimizations_with_generators: & [ & dyn MirPass < ' tcx > ] = & [ & generator:: StateTransform ] ;
524-
525- // The main optimizations that we do on MIR.
526- let optimizations: & [ & dyn MirPass < ' tcx > ] = & [
527- & remove_storage_markers:: RemoveStorageMarkers ,
528- & remove_zsts:: RemoveZsts ,
529- & const_goto:: ConstGoto ,
530- & remove_unneeded_drops:: RemoveUnneededDrops ,
531- & match_branches:: MatchBranchSimplification ,
532- // inst combine is after MatchBranchSimplification to clean up Ne(_1, false)
533- & multiple_return_terminators:: MultipleReturnTerminators ,
534- & instcombine:: InstCombine ,
535- & separate_const_switch:: SeparateConstSwitch ,
536- & const_prop:: ConstProp ,
537- & simplify_branches:: SimplifyConstCondition :: new ( "after-const-prop" ) ,
538- & early_otherwise_branch:: EarlyOtherwiseBranch ,
539- & simplify_comparison_integral:: SimplifyComparisonIntegral ,
540- & simplify_try:: SimplifyArmIdentity ,
541- & simplify_try:: SimplifyBranchSame ,
542- & dest_prop:: DestinationPropagation ,
543- & simplify_branches:: SimplifyConstCondition :: new ( "final" ) ,
544- & remove_noop_landing_pads:: RemoveNoopLandingPads ,
545- & simplify:: SimplifyCfg :: new ( "final" ) ,
546- & nrvo:: RenameReturnPlace ,
547- & const_debuginfo:: ConstDebugInfo ,
548- & simplify:: SimplifyLocals ,
549- & multiple_return_terminators:: MultipleReturnTerminators ,
550- & deduplicate_blocks:: DeduplicateBlocks ,
551- ] ;
552-
553- // Optimizations to run even if mir optimizations have been disabled.
554- let no_optimizations: & [ & dyn MirPass < ' tcx > ] = & [
555- // FIXME(#70073): This pass is responsible for both optimization as well as some lints.
556- & const_prop:: ConstProp ,
557- ] ;
558-
559- // Some cleanup necessary at least for LLVM and potentially other codegen backends.
560- let pre_codegen_cleanup: & [ & dyn MirPass < ' tcx > ] = & [
561- & add_call_guards:: CriticalCallEdges ,
562- // Dump the end result for testing and debugging purposes.
563- & dump_mir:: Marker ( "PreCodegen" ) ,
564- ] ;
565-
566- // End of pass declarations, now actually run the passes.
567- // Generator Lowering
568- #[ rustfmt:: skip]
569- run_passes (
444+ pm:: run_passes (
570445 tcx,
571446 body,
572- MirPhase :: GeneratorLowering ,
573447 & [
574- if mir_opt_level > 0 {
575- optimizations_with_generators
576- } else {
577- no_optimizations_with_generators
578- }
448+ & reveal_all:: RevealAll , // has to be done before inlining, since inlined code is in RevealAll mode.
449+ & lower_slice_len:: LowerSliceLenCalls , // has to be done before inlining, otherwise actual call will be almost always inlined. Also simple, so can just do first
450+ & normalize_array_len:: NormalizeArrayLen , // has to run after `slice::len` lowering
451+ & unreachable_prop:: UnreachablePropagation ,
452+ & uninhabited_enum_branching:: UninhabitedEnumBranching ,
453+ & simplify:: SimplifyCfg :: new ( "after-uninhabited-enum-branching" ) ,
454+ & inline:: Inline ,
455+ & generator:: StateTransform ,
579456 ] ,
580457 ) ;
581458
582- // Main optimization passes
583- #[ rustfmt:: skip]
584- run_passes (
459+ assert ! ( body. phase == MirPhase :: GeneratorLowering ) ;
460+
461+ // The main optimizations that we do on MIR.
462+ pm:: run_passes (
585463 tcx,
586464 body,
587- MirPhase :: Optimization ,
588465 & [
589- if mir_opt_level > 0 { optimizations } else { no_optimizations } ,
590- pre_codegen_cleanup,
466+ & remove_storage_markers:: RemoveStorageMarkers ,
467+ & remove_zsts:: RemoveZsts ,
468+ & const_goto:: ConstGoto ,
469+ & remove_unneeded_drops:: RemoveUnneededDrops ,
470+ & match_branches:: MatchBranchSimplification ,
471+ // inst combine is after MatchBranchSimplification to clean up Ne(_1, false)
472+ & multiple_return_terminators:: MultipleReturnTerminators ,
473+ & instcombine:: InstCombine ,
474+ & separate_const_switch:: SeparateConstSwitch ,
475+ // FIXME(#70073): This pass is responsible for both optimization as well as some lints.
476+ & const_prop:: ConstProp ,
477+ & simplify_branches:: SimplifyBranches :: new ( "after-const-prop" ) ,
478+ & early_otherwise_branch:: EarlyOtherwiseBranch ,
479+ & simplify_comparison_integral:: SimplifyComparisonIntegral ,
480+ & simplify_try:: SimplifyArmIdentity ,
481+ & simplify_try:: SimplifyBranchSame ,
482+ & dest_prop:: DestinationPropagation ,
483+ & simplify_branches:: SimplifyBranches :: new ( "final" ) ,
484+ & remove_noop_landing_pads:: RemoveNoopLandingPads ,
485+ & simplify:: SimplifyCfg :: new ( "final" ) ,
486+ & nrvo:: RenameReturnPlace ,
487+ & const_debuginfo:: ConstDebugInfo ,
488+ & simplify:: SimplifyLocals ,
489+ & multiple_return_terminators:: MultipleReturnTerminators ,
490+ & deduplicate_blocks:: DeduplicateBlocks ,
491+ // Some cleanup necessary at least for LLVM and potentially other codegen backends.
492+ & add_call_guards:: CriticalCallEdges ,
493+ & marker:: PhaseChange ( MirPhase :: Optimization ) ,
494+ // Dump the end result for testing and debugging purposes.
495+ & dump_mir:: Marker ( "PreCodegen" ) ,
591496 ] ,
592497 ) ;
593498}
0 commit comments