@@ -95,6 +95,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
95
95
96
96
let mut start = START_BLOCK ;
97
97
98
+ let mut merged_blocks = Vec :: new ( ) ;
98
99
loop {
99
100
let mut changed = false ;
100
101
@@ -118,10 +119,23 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
118
119
while inner_changed {
119
120
inner_changed = false ;
120
121
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) ;
122
123
changed |= inner_changed;
123
124
}
124
125
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
+
125
139
self . basic_blocks [ bb] . terminator = Some ( terminator) ;
126
140
127
141
changed |= inner_changed;
@@ -196,7 +210,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
196
210
// merge a block with 1 `goto` predecessor to its parent
197
211
fn merge_successor (
198
212
& mut self ,
199
- merge_into : BasicBlock ,
213
+ merged_blocks : & mut Vec < BasicBlock > ,
200
214
terminator : & mut Terminator < ' tcx > ,
201
215
) -> bool {
202
216
let target = match terminator. kind {
@@ -214,8 +228,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
214
228
}
215
229
} ;
216
230
217
- let ( from, to) = self . basic_blocks . pick2_mut ( target, merge_into) ;
218
- to. statements . append ( & mut from. statements ) ;
231
+ merged_blocks. push ( target) ;
219
232
self . pred_count [ target] = 0 ;
220
233
221
234
true
0 commit comments