@@ -158,17 +158,9 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
158
158
let mut terminator =
159
159
self . basic_blocks [ bb] . terminator . take ( ) . expect ( "invalid terminator state" ) ;
160
160
161
- let identical_succ = terminator. identical_successor ( ) ;
162
161
terminator. successors_mut ( |successor| {
163
162
self . collapse_goto_chain ( successor, & mut changed) ;
164
163
} ) ;
165
- if changed && let Some ( identical_succ) = identical_succ {
166
- // Add debugging information from the goto chain only when all successors are identical,
167
- // otherwise, we may provide misleading debugging information within a branch.
168
- let mut succ_debuginfos =
169
- self . basic_blocks [ identical_succ] . after_last_stmt_debuginfos . clone ( ) ;
170
- self . basic_blocks [ bb] . after_last_stmt_debuginfos . append ( & mut succ_debuginfos) ;
171
- }
172
164
173
165
let mut inner_changed = true ;
174
166
merged_blocks. clear ( ) ;
@@ -236,28 +228,36 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
236
228
// goto chains. We should probably benchmark different sizes.
237
229
let mut terminators: SmallVec < [ _ ; 1 ] > = Default :: default ( ) ;
238
230
let mut current = * start;
231
+ // If each successor has only one predecessor, it's a trivial goto chain.
232
+ // We can move all debuginfos to the last basic block.
233
+ let mut trivial_goto_chain = true ;
239
234
while let Some ( terminator) = self . take_terminator_if_simple_goto ( current) {
240
235
let Terminator { kind : TerminatorKind :: Goto { target } , .. } = terminator else {
241
236
unreachable ! ( ) ;
242
237
} ;
238
+ trivial_goto_chain &= self . pred_count [ target] == 1 ;
243
239
terminators. push ( ( current, terminator) ) ;
244
240
current = target;
245
241
}
246
242
let last = current;
247
243
* changed |= * start != last;
248
244
* start = last;
249
- let mut succ = last;
250
245
while let Some ( ( current, mut terminator) ) = terminators. pop ( ) {
251
246
let Terminator { kind : TerminatorKind :: Goto { ref mut target } , .. } = terminator
252
247
else {
253
248
unreachable ! ( ) ;
254
249
} ;
255
- if * target != last {
256
- let mut succ_debuginfos =
257
- self . basic_blocks [ succ] . after_last_stmt_debuginfos . clone ( ) ;
258
- self . basic_blocks [ current] . after_last_stmt_debuginfos . extend ( & mut succ_debuginfos) ;
250
+ if trivial_goto_chain {
251
+ let mut pred_debuginfos =
252
+ std:: mem:: take ( & mut self . basic_blocks [ current] . after_last_stmt_debuginfos ) ;
253
+ let debuginfos = if let Some ( stmt) = self . basic_blocks [ last] . statements . first_mut ( )
254
+ {
255
+ & mut stmt. debuginfos
256
+ } else {
257
+ & mut self . basic_blocks [ last] . after_last_stmt_debuginfos
258
+ } ;
259
+ debuginfos. prepend ( & mut pred_debuginfos) ;
259
260
}
260
- succ = current;
261
261
* changed |= * target != last;
262
262
* target = last;
263
263
debug ! ( "collapsing goto chain from {:?} to {:?}" , current, target) ;
0 commit comments