@@ -30,7 +30,7 @@ use rustc_middle::mir::{
30
30
MirPhase , Operand , Place , ProjectionElem , Promoted , RuntimePhase , Rvalue , START_BLOCK ,
31
31
SourceInfo , Statement , StatementKind , TerminatorKind ,
32
32
} ;
33
- use rustc_middle:: ty:: { self , TyCtxt , TypeVisitableExt } ;
33
+ use rustc_middle:: ty:: { self , Instance , TyCtxt , TypeVisitableExt } ;
34
34
use rustc_middle:: util:: Providers ;
35
35
use rustc_middle:: { bug, query, span_bug} ;
36
36
use rustc_span:: source_map:: Spanned ;
@@ -136,6 +136,7 @@ pub fn provide(providers: &mut Providers) {
136
136
promoted_mir,
137
137
deduced_param_attrs : deduce_param_attrs:: deduced_param_attrs,
138
138
coroutine_by_move_body_def_id : coroutine:: coroutine_by_move_body_def_id,
139
+ build_codegen_mir,
139
140
..providers. queries
140
141
} ;
141
142
}
@@ -564,11 +565,11 @@ fn run_runtime_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
564
565
}
565
566
}
566
567
567
- fn run_optimization_passes < ' tcx > ( tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
568
- fn o1 < T > ( x : T ) -> WithMinOptLevel < T > {
569
- WithMinOptLevel ( 1 , x)
570
- }
568
+ fn o1 < T > ( x : T ) -> WithMinOptLevel < T > {
569
+ WithMinOptLevel ( 1 , x)
570
+ }
571
571
572
+ fn run_optimization_passes < ' tcx > ( tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
572
573
// The main optimizations that we do on MIR.
573
574
pm:: run_passes (
574
575
tcx,
@@ -609,7 +610,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
609
610
& instsimplify:: InstSimplify :: AfterSimplifyCfg ,
610
611
& simplify:: SimplifyLocals :: BeforeConstProp ,
611
612
& dead_store_elimination:: DeadStoreElimination :: Initial ,
612
- & gvn:: GVN ,
613
+ & gvn:: GVN :: Polymorphic ,
613
614
& simplify:: SimplifyLocals :: AfterGVN ,
614
615
& dataflow_const_prop:: DataflowConstProp ,
615
616
& single_use_consts:: SingleUseConsts ,
@@ -628,8 +629,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
628
629
& multiple_return_terminators:: MultipleReturnTerminators ,
629
630
& deduplicate_blocks:: DeduplicateBlocks ,
630
631
& large_enums:: EnumSizeOpt { discrepancy : 128 } ,
631
- // Some cleanup necessary at least for LLVM and potentially other codegen backends.
632
- & add_call_guards:: CriticalCallEdges ,
633
632
// Cleanup for human readability, off by default.
634
633
& prettify:: ReorderBasicBlocks ,
635
634
& prettify:: ReorderLocals ,
@@ -689,6 +688,38 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
689
688
body
690
689
}
691
690
691
+ pub fn build_codegen_mir < ' tcx > ( tcx : TyCtxt < ' tcx > , instance : Instance < ' tcx > ) -> & ' tcx Body < ' tcx > {
692
+ let body = tcx. instance_mir ( instance. def ) ;
693
+ let mut body = instance. instantiate_mir_and_normalize_erasing_regions (
694
+ tcx,
695
+ ty:: ParamEnv :: reveal_all ( ) ,
696
+ ty:: EarlyBinder :: bind ( body. clone ( ) ) ,
697
+ ) ;
698
+ pm:: run_passes (
699
+ tcx,
700
+ & mut body,
701
+ & [
702
+ // Validation calls layout::fn_can_unwind to figure out if a function can unwind, which
703
+ // always returns false if the current crate is compiled with -Cpanic=abort. So when
704
+ // a crate with panic=abort compiles MIR from a panic=unwind crate, we get validation
705
+ // failures. So we rely on the fact that validation only runs after passes? It's
706
+ // probably better to just delete that validation check.
707
+ & abort_unwinding_calls:: AbortUnwindingCalls ,
708
+ & o1 ( gvn:: GVN :: PostMono ) ,
709
+ // FIXME: Enabling this InstSimplify is required to fix the MIR from the
710
+ // unreachable_unchecked precondition check that UnreachablePropagation creates, but
711
+ // also enabling it breaks tests/codegen/issues/issue-122600-ptr-discriminant-update.rs
712
+ // LLVM appears to handle switches on i64 better than it handles icmp eq + br.
713
+ & o1 ( instsimplify:: InstSimplify :: PostMono ) ,
714
+ & o1 ( simplify_branches:: SimplifyConstCondition :: PostMono ) ,
715
+ & o1 ( simplify:: SimplifyCfg :: PostMono ) ,
716
+ & add_call_guards:: CriticalCallEdges ,
717
+ ] ,
718
+ Some ( MirPhase :: Runtime ( RuntimePhase :: Codegen ) ) ,
719
+ ) ;
720
+ tcx. arena . alloc ( body)
721
+ }
722
+
692
723
/// Fetch all the promoteds of an item and prepare their MIR bodies to be ready for
693
724
/// constant evaluation once all generic parameters become known.
694
725
fn promoted_mir ( tcx : TyCtxt < ' _ > , def : LocalDefId ) -> & IndexVec < Promoted , Body < ' _ > > {
0 commit comments