@@ -554,80 +554,82 @@ fn run_runtime_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
554
554
}
555
555
556
556
fn run_optimization_passes < ' tcx > ( tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
557
- if body. optimization_disabled {
558
- return ;
559
- }
560
-
561
557
fn o1 < T > ( x : T ) -> WithMinOptLevel < T > {
562
558
WithMinOptLevel ( 1 , x)
563
559
}
564
560
561
+ let passes: [ & dyn MirPass < ' tcx > ; 40 ] = [
562
+ // Add some UB checks before any UB gets optimized away.
563
+ & check_alignment:: CheckAlignment as & dyn MirPass < ' _ > ,
564
+ // Before inlining: trim down MIR with passes to reduce inlining work.
565
+
566
+ // Has to be done before inlining, otherwise actual call will be almost always inlined.
567
+ // Also simple, so can just do first
568
+ & lower_slice_len:: LowerSliceLenCalls ,
569
+ // Perform instsimplify before inline to eliminate some trivial calls (like clone shims).
570
+ & instsimplify:: InstSimplify :: BeforeInline ,
571
+ // Perform inlining, which may add a lot of code.
572
+ & inline:: Inline ,
573
+ // Code from other crates may have storage markers, so this needs to happen after inlining.
574
+ & remove_storage_markers:: RemoveStorageMarkers ,
575
+ // Inlining and instantiation may introduce ZST and useless drops.
576
+ & remove_zsts:: RemoveZsts ,
577
+ & remove_unneeded_drops:: RemoveUnneededDrops ,
578
+ // Type instantiation may create uninhabited enums.
579
+ // Also eliminates some unreachable branches based on variants of enums.
580
+ & unreachable_enum_branching:: UnreachableEnumBranching ,
581
+ & unreachable_prop:: UnreachablePropagation ,
582
+ & o1 ( simplify:: SimplifyCfg :: AfterUnreachableEnumBranching ) ,
583
+ // Inlining may have introduced a lot of redundant code and a large move pattern.
584
+ // Now, we need to shrink the generated MIR.
585
+ & ref_prop:: ReferencePropagation ,
586
+ & sroa:: ScalarReplacementOfAggregates ,
587
+ & match_branches:: MatchBranchSimplification ,
588
+ // inst combine is after MatchBranchSimplification to clean up Ne(_1, false)
589
+ & multiple_return_terminators:: MultipleReturnTerminators ,
590
+ // After simplifycfg, it allows us to discover new opportunities for peephole optimizations.
591
+ & instsimplify:: InstSimplify :: AfterSimplifyCfg ,
592
+ & simplify:: SimplifyLocals :: BeforeConstProp ,
593
+ & dead_store_elimination:: DeadStoreElimination :: Initial ,
594
+ & gvn:: GVN ,
595
+ & simplify:: SimplifyLocals :: AfterGVN ,
596
+ & dataflow_const_prop:: DataflowConstProp ,
597
+ & single_use_consts:: SingleUseConsts ,
598
+ & o1 ( simplify_branches:: SimplifyConstCondition :: AfterConstProp ) ,
599
+ & jump_threading:: JumpThreading ,
600
+ & early_otherwise_branch:: EarlyOtherwiseBranch ,
601
+ & simplify_comparison_integral:: SimplifyComparisonIntegral ,
602
+ & dest_prop:: DestinationPropagation ,
603
+ & o1 ( simplify_branches:: SimplifyConstCondition :: Final ) ,
604
+ & o1 ( remove_noop_landing_pads:: RemoveNoopLandingPads ) ,
605
+ & o1 ( simplify:: SimplifyCfg :: Final ) ,
606
+ & copy_prop:: CopyProp ,
607
+ & dead_store_elimination:: DeadStoreElimination :: Final ,
608
+ & nrvo:: RenameReturnPlace ,
609
+ & simplify:: SimplifyLocals :: Final ,
610
+ & multiple_return_terminators:: MultipleReturnTerminators ,
611
+ & deduplicate_blocks:: DeduplicateBlocks ,
612
+ & large_enums:: EnumSizeOpt { discrepancy : 128 } ,
613
+ // Some cleanup necessary at least for LLVM and potentially other codegen backends.
614
+ & add_call_guards:: CriticalCallEdges ,
615
+ // Cleanup for human readability, off by default.
616
+ & prettify:: ReorderBasicBlocks ,
617
+ & prettify:: ReorderLocals ,
618
+ // Dump the end result for testing and debugging purposes.
619
+ & dump_mir:: Marker ( "PreCodegen" ) ,
620
+ ] ;
621
+
622
+ let mut passes = passes. to_vec ( ) ;
623
+ let def_id = body. source . def_id ( ) ;
624
+ if tcx. def_kind ( def_id) . has_codegen_attrs ( )
625
+ && let Some ( ref attrs) = tcx. codegen_fn_attrs ( def_id) . optimize
626
+ && attrs. do_not_optimize ( )
627
+ {
628
+ passes. retain ( |pass| pass. min_mir_opt_level ( ) <= 1 ) ;
629
+ }
630
+
565
631
// The main optimizations that we do on MIR.
566
- pm:: run_passes (
567
- tcx,
568
- body,
569
- & [
570
- // Add some UB checks before any UB gets optimized away.
571
- & check_alignment:: CheckAlignment ,
572
- // Before inlining: trim down MIR with passes to reduce inlining work.
573
-
574
- // Has to be done before inlining, otherwise actual call will be almost always inlined.
575
- // Also simple, so can just do first
576
- & lower_slice_len:: LowerSliceLenCalls ,
577
- // Perform instsimplify before inline to eliminate some trivial calls (like clone shims).
578
- & instsimplify:: InstSimplify :: BeforeInline ,
579
- // Perform inlining, which may add a lot of code.
580
- & inline:: Inline ,
581
- // Code from other crates may have storage markers, so this needs to happen after inlining.
582
- & remove_storage_markers:: RemoveStorageMarkers ,
583
- // Inlining and instantiation may introduce ZST and useless drops.
584
- & remove_zsts:: RemoveZsts ,
585
- & remove_unneeded_drops:: RemoveUnneededDrops ,
586
- // Type instantiation may create uninhabited enums.
587
- // Also eliminates some unreachable branches based on variants of enums.
588
- & unreachable_enum_branching:: UnreachableEnumBranching ,
589
- & unreachable_prop:: UnreachablePropagation ,
590
- & o1 ( simplify:: SimplifyCfg :: AfterUnreachableEnumBranching ) ,
591
- // Inlining may have introduced a lot of redundant code and a large move pattern.
592
- // Now, we need to shrink the generated MIR.
593
- & ref_prop:: ReferencePropagation ,
594
- & sroa:: ScalarReplacementOfAggregates ,
595
- & match_branches:: MatchBranchSimplification ,
596
- // inst combine is after MatchBranchSimplification to clean up Ne(_1, false)
597
- & multiple_return_terminators:: MultipleReturnTerminators ,
598
- // After simplifycfg, it allows us to discover new opportunities for peephole optimizations.
599
- & instsimplify:: InstSimplify :: AfterSimplifyCfg ,
600
- & simplify:: SimplifyLocals :: BeforeConstProp ,
601
- & dead_store_elimination:: DeadStoreElimination :: Initial ,
602
- & gvn:: GVN ,
603
- & simplify:: SimplifyLocals :: AfterGVN ,
604
- & dataflow_const_prop:: DataflowConstProp ,
605
- & single_use_consts:: SingleUseConsts ,
606
- & o1 ( simplify_branches:: SimplifyConstCondition :: AfterConstProp ) ,
607
- & jump_threading:: JumpThreading ,
608
- & early_otherwise_branch:: EarlyOtherwiseBranch ,
609
- & simplify_comparison_integral:: SimplifyComparisonIntegral ,
610
- & dest_prop:: DestinationPropagation ,
611
- & o1 ( simplify_branches:: SimplifyConstCondition :: Final ) ,
612
- & o1 ( remove_noop_landing_pads:: RemoveNoopLandingPads ) ,
613
- & o1 ( simplify:: SimplifyCfg :: Final ) ,
614
- & copy_prop:: CopyProp ,
615
- & dead_store_elimination:: DeadStoreElimination :: Final ,
616
- & nrvo:: RenameReturnPlace ,
617
- & simplify:: SimplifyLocals :: Final ,
618
- & multiple_return_terminators:: MultipleReturnTerminators ,
619
- & deduplicate_blocks:: DeduplicateBlocks ,
620
- & large_enums:: EnumSizeOpt { discrepancy : 128 } ,
621
- // Some cleanup necessary at least for LLVM and potentially other codegen backends.
622
- & add_call_guards:: CriticalCallEdges ,
623
- // Cleanup for human readability, off by default.
624
- & prettify:: ReorderBasicBlocks ,
625
- & prettify:: ReorderLocals ,
626
- // Dump the end result for testing and debugging purposes.
627
- & dump_mir:: Marker ( "PreCodegen" ) ,
628
- ] ,
629
- Some ( MirPhase :: Runtime ( RuntimePhase :: Optimized ) ) ,
630
- ) ;
632
+ pm:: run_passes ( tcx, body, & passes, Some ( MirPhase :: Runtime ( RuntimePhase :: Optimized ) ) ) ;
631
633
}
632
634
633
635
/// Optimize the MIR and prepare it for codegen.
0 commit comments