@@ -95,6 +95,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
9595
9696 let mut start = START_BLOCK ;
9797
98+ let mut merged_blocks = Vec :: new ( ) ;
9899 loop {
99100 let mut changed = false ;
100101
@@ -118,10 +119,23 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
118119 while inner_changed {
119120 inner_changed = false ;
120121 inner_changed |= self . simplify_branch ( & mut terminator) ;
121- inner_changed |= self . merge_successor ( bb , & mut terminator) ;
122+ inner_changed |= self . merge_successor ( & mut merged_blocks , & mut terminator) ;
122123 changed |= inner_changed;
123124 }
124125
126+ let merged_block_count =
127+ merged_blocks. iter ( ) . map ( |& i| self . basic_blocks [ i] . statements . len ( ) ) . sum ( ) ;
128+
129+ if merged_block_count > 0 {
130+ let mut statements = std:: mem:: take ( & mut self . basic_blocks [ bb] . statements ) ;
131+ statements. reserve ( merged_block_count) ;
132+ for & from in & merged_blocks {
133+ statements. append ( & mut self . basic_blocks [ from] . statements ) ;
134+ }
135+ self . basic_blocks [ bb] . statements = statements;
136+ }
137+ merged_blocks. clear ( ) ;
138+
125139 self . basic_blocks [ bb] . terminator = Some ( terminator) ;
126140
127141 changed |= inner_changed;
@@ -196,7 +210,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
196210 // merge a block with 1 `goto` predecessor to its parent
197211 fn merge_successor (
198212 & mut self ,
199- merge_into : BasicBlock ,
213+ merged_blocks : & mut Vec < BasicBlock > ,
200214 terminator : & mut Terminator < ' tcx > ,
201215 ) -> bool {
202216 let target = match terminator. kind {
@@ -214,8 +228,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
214228 }
215229 } ;
216230
217- let ( from, to) = self . basic_blocks . pick2_mut ( target, merge_into) ;
218- to. statements . append ( & mut from. statements ) ;
231+ merged_blocks. push ( target) ;
219232 self . pred_count [ target] = 0 ;
220233
221234 true
0 commit comments