22
33use rustc_attr as attr;
44use rustc_index:: bit_set:: BitSet ;
5- use rustc_index:: vec:: { Idx , IndexVec } ;
5+ use rustc_index:: vec:: Idx ;
66use rustc_middle:: middle:: codegen_fn_attrs:: { CodegenFnAttrFlags , CodegenFnAttrs } ;
77use rustc_middle:: mir:: visit:: * ;
88use rustc_middle:: mir:: * ;
@@ -14,6 +14,7 @@ use super::simplify::{remove_dead_blocks, CfgSimplifier};
1414use crate :: transform:: MirPass ;
1515use std:: collections:: VecDeque ;
1616use std:: iter;
17+ use std:: ops:: RangeFrom ;
1718
1819const DEFAULT_THRESHOLD : usize = 50 ;
1920const HINT_THRESHOLD : usize = 100 ;
@@ -477,26 +478,24 @@ impl Inliner<'tcx> {
477478 // Copy the arguments if needed.
478479 let args: Vec < _ > = self . make_call_args ( args, & callsite, caller_body, return_block) ;
479480
480- let bb_len = caller_body. basic_blocks ( ) . len ( ) ;
481481 let mut integrator = Integrator {
482- block_idx : bb_len,
483482 args : & args,
484- local_map : IndexVec :: with_capacity ( callee_body. local_decls . len ( ) ) ,
485- scope_map : IndexVec :: with_capacity ( callee_body. source_scopes . len ( ) ) ,
483+ new_locals : Local :: new ( caller_body. local_decls . len ( ) ) ..,
484+ new_scopes : SourceScope :: new ( caller_body. source_scopes . len ( ) ) ..,
485+ new_blocks : BasicBlock :: new ( caller_body. basic_blocks ( ) . len ( ) ) ..,
486486 destination : dest,
487487 return_block,
488488 cleanup_block : cleanup,
489489 in_cleanup_block : false ,
490490 tcx : self . tcx ,
491491 } ;
492492
493- for mut scope in callee_body. source_scopes . iter ( ) . cloned ( ) {
494- // Map the callee scopes into the caller.
495- // FIXME(eddyb) this may ICE if the scopes are out of order.
496- scope. parent_scope = scope. parent_scope . map ( |s| integrator. scope_map [ s] ) ;
497- scope. inlined_parent_scope =
498- scope. inlined_parent_scope . map ( |s| integrator. scope_map [ s] ) ;
493+ // Map all `Local`s, `SourceScope`s and `BasicBlock`s to new ones
494+ // (or existing ones, in a few special cases) in the caller.
495+ integrator. visit_body ( & mut callee_body) ;
499496
497+ for scope in & mut callee_body. source_scopes {
498+ // FIXME(eddyb) move this into a `fn visit_scope_data` in `Integrator`.
500499 if scope. parent_scope . is_none ( ) {
501500 let callsite_scope = & caller_body. source_scopes [ callsite. source_info . scope ] ;
502501
@@ -516,38 +515,26 @@ impl Inliner<'tcx> {
516515 } else if scope. inlined_parent_scope . is_none ( ) {
517516 // Make it easy to find the scope with `inlined` set above.
518517 scope. inlined_parent_scope =
519- Some ( integrator. scope_map [ OUTERMOST_SOURCE_SCOPE ] ) ;
518+ Some ( integrator. map_scope ( OUTERMOST_SOURCE_SCOPE ) ) ;
520519 }
521-
522- let idx = caller_body. source_scopes . push ( scope) ;
523- integrator. scope_map . push ( idx) ;
524- }
525-
526- for loc in callee_body. vars_and_temps_iter ( ) {
527- let mut local = callee_body. local_decls [ loc] . clone ( ) ;
528-
529- local. source_info . scope = integrator. scope_map [ local. source_info . scope ] ;
530-
531- let idx = caller_body. local_decls . push ( local) ;
532- integrator. local_map . push ( idx) ;
533- }
534-
535- for mut var_debug_info in callee_body. var_debug_info . drain ( ..) {
536- integrator. visit_var_debug_info ( & mut var_debug_info) ;
537- caller_body. var_debug_info . push ( var_debug_info) ;
538520 }
539521
540- for ( bb, mut block) in callee_body. basic_blocks_mut ( ) . drain_enumerated ( ..) {
541- integrator. visit_basic_block_data ( bb, & mut block) ;
542- caller_body. basic_blocks_mut ( ) . push ( block) ;
543- }
522+ // Insert all of the (mapped) parts of the callee body into the caller.
523+ caller_body. local_decls . extend (
524+ // FIXME(eddyb) make `Range<Local>` iterable so that we can use
525+ // `callee_body.local_decls.drain(callee_body.vars_and_temps())`
526+ callee_body
527+ . vars_and_temps_iter ( )
528+ . map ( |local| callee_body. local_decls [ local] . clone ( ) ) ,
529+ ) ;
530+ caller_body. source_scopes . extend ( callee_body. source_scopes . drain ( ..) ) ;
531+ caller_body. var_debug_info . extend ( callee_body. var_debug_info . drain ( ..) ) ;
532+ caller_body. basic_blocks_mut ( ) . extend ( callee_body. basic_blocks_mut ( ) . drain ( ..) ) ;
544533
545- let terminator = Terminator {
534+ caller_body [ callsite . bb ] . terminator = Some ( Terminator {
546535 source_info : callsite. source_info ,
547- kind : TerminatorKind :: Goto { target : BasicBlock :: new ( bb_len) } ,
548- } ;
549-
550- caller_body[ callsite. bb ] . terminator = Some ( terminator) ;
536+ kind : TerminatorKind :: Goto { target : integrator. map_block ( START_BLOCK ) } ,
537+ } ) ;
551538
552539 true
553540 }
@@ -703,10 +690,10 @@ fn type_size_of<'tcx>(
703690 * stuff.
704691*/
705692struct Integrator < ' a , ' tcx > {
706- block_idx : usize ,
707693 args : & ' a [ Local ] ,
708- local_map : IndexVec < Local , Local > ,
709- scope_map : IndexVec < SourceScope , SourceScope > ,
694+ new_locals : RangeFrom < Local > ,
695+ new_scopes : RangeFrom < SourceScope > ,
696+ new_blocks : RangeFrom < BasicBlock > ,
710697 destination : Place < ' tcx > ,
711698 return_block : BasicBlock ,
712699 cleanup_block : Option < BasicBlock > ,
@@ -715,23 +702,31 @@ struct Integrator<'a, 'tcx> {
715702}
716703
717704impl < ' a , ' tcx > Integrator < ' a , ' tcx > {
718- fn update_target ( & self , tgt : BasicBlock ) -> BasicBlock {
719- let new = BasicBlock :: new ( tgt. index ( ) + self . block_idx ) ;
720- debug ! ( "updating target `{:?}`, new: `{:?}`" , tgt, new) ;
705+ fn map_local ( & self , local : Local ) -> Local {
706+ let new = if local == RETURN_PLACE {
707+ self . destination . local
708+ } else {
709+ let idx = local. index ( ) - 1 ;
710+ if idx < self . args . len ( ) {
711+ self . args [ idx]
712+ } else {
713+ Local :: new ( self . new_locals . start . index ( ) + ( idx - self . args . len ( ) ) )
714+ }
715+ } ;
716+ debug ! ( "mapping local `{:?}` to `{:?}`" , local, new) ;
721717 new
722718 }
723719
724- fn make_integrate_local ( & self , local : Local ) -> Local {
725- if local == RETURN_PLACE {
726- return self . destination . local ;
727- }
728-
729- let idx = local. index ( ) - 1 ;
730- if idx < self . args . len ( ) {
731- return self . args [ idx] ;
732- }
720+ fn map_scope ( & self , scope : SourceScope ) -> SourceScope {
721+ let new = SourceScope :: new ( self . new_scopes . start . index ( ) + scope. index ( ) ) ;
722+ debug ! ( "mapping scope `{:?}` to `{:?}`" , scope, new) ;
723+ new
724+ }
733725
734- self . local_map [ Local :: new ( idx - self . args . len ( ) ) ]
726+ fn map_block ( & self , block : BasicBlock ) -> BasicBlock {
727+ let new = BasicBlock :: new ( self . new_blocks . start . index ( ) + block. index ( ) ) ;
728+ debug ! ( "mapping block `{:?}` to `{:?}`" , block, new) ;
729+ new
735730 }
736731}
737732
@@ -741,7 +736,11 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
741736 }
742737
743738 fn visit_local ( & mut self , local : & mut Local , _ctxt : PlaceContext , _location : Location ) {
744- * local = self . make_integrate_local ( * local) ;
739+ * local = self . map_local ( * local) ;
740+ }
741+
742+ fn visit_source_scope ( & mut self , scope : & mut SourceScope ) {
743+ * scope = self . map_scope ( * scope) ;
745744 }
746745
747746 fn visit_place ( & mut self , place : & mut Place < ' tcx > , context : PlaceContext , location : Location ) {
@@ -785,18 +784,18 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
785784 match terminator. kind {
786785 TerminatorKind :: GeneratorDrop | TerminatorKind :: Yield { .. } => bug ! ( ) ,
787786 TerminatorKind :: Goto { ref mut target } => {
788- * target = self . update_target ( * target) ;
787+ * target = self . map_block ( * target) ;
789788 }
790789 TerminatorKind :: SwitchInt { ref mut targets, .. } => {
791790 for tgt in targets. all_targets_mut ( ) {
792- * tgt = self . update_target ( * tgt) ;
791+ * tgt = self . map_block ( * tgt) ;
793792 }
794793 }
795794 TerminatorKind :: Drop { ref mut target, ref mut unwind, .. }
796795 | TerminatorKind :: DropAndReplace { ref mut target, ref mut unwind, .. } => {
797- * target = self . update_target ( * target) ;
796+ * target = self . map_block ( * target) ;
798797 if let Some ( tgt) = * unwind {
799- * unwind = Some ( self . update_target ( tgt) ) ;
798+ * unwind = Some ( self . map_block ( tgt) ) ;
800799 } else if !self . in_cleanup_block {
801800 // Unless this drop is in a cleanup block, add an unwind edge to
802801 // the original call's cleanup block
@@ -805,20 +804,20 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
805804 }
806805 TerminatorKind :: Call { ref mut destination, ref mut cleanup, .. } => {
807806 if let Some ( ( _, ref mut tgt) ) = * destination {
808- * tgt = self . update_target ( * tgt) ;
807+ * tgt = self . map_block ( * tgt) ;
809808 }
810809 if let Some ( tgt) = * cleanup {
811- * cleanup = Some ( self . update_target ( tgt) ) ;
810+ * cleanup = Some ( self . map_block ( tgt) ) ;
812811 } else if !self . in_cleanup_block {
813812 // Unless this call is in a cleanup block, add an unwind edge to
814813 // the original call's cleanup block
815814 * cleanup = self . cleanup_block ;
816815 }
817816 }
818817 TerminatorKind :: Assert { ref mut target, ref mut cleanup, .. } => {
819- * target = self . update_target ( * target) ;
818+ * target = self . map_block ( * target) ;
820819 if let Some ( tgt) = * cleanup {
821- * cleanup = Some ( self . update_target ( tgt) ) ;
820+ * cleanup = Some ( self . map_block ( tgt) ) ;
822821 } else if !self . in_cleanup_block {
823822 // Unless this assert is in a cleanup block, add an unwind edge to
824823 // the original call's cleanup block
@@ -836,8 +835,8 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
836835 TerminatorKind :: Abort => { }
837836 TerminatorKind :: Unreachable => { }
838837 TerminatorKind :: FalseEdge { ref mut real_target, ref mut imaginary_target } => {
839- * real_target = self . update_target ( * real_target) ;
840- * imaginary_target = self . update_target ( * imaginary_target) ;
838+ * real_target = self . map_block ( * real_target) ;
839+ * imaginary_target = self . map_block ( * imaginary_target) ;
841840 }
842841 TerminatorKind :: FalseUnwind { real_target : _, unwind : _ } =>
843842 // see the ordering of passes in the optimized_mir query.
@@ -846,13 +845,9 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
846845 }
847846 TerminatorKind :: InlineAsm { ref mut destination, .. } => {
848847 if let Some ( ref mut tgt) = * destination {
849- * tgt = self . update_target ( * tgt) ;
848+ * tgt = self . map_block ( * tgt) ;
850849 }
851850 }
852851 }
853852 }
854-
855- fn visit_source_scope ( & mut self , scope : & mut SourceScope ) {
856- * scope = self . scope_map [ * scope] ;
857- }
858853}
0 commit comments