@@ -158,17 +158,9 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
158158 let mut terminator =
159159 self . basic_blocks [ bb] . terminator . take ( ) . expect ( "invalid terminator state" ) ;
160160
161- let identical_succ = terminator. identical_successor ( ) ;
162161 terminator. successors_mut ( |successor| {
163162 self . collapse_goto_chain ( successor, & mut changed) ;
164163 } ) ;
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- }
172164
173165 let mut inner_changed = true ;
174166 merged_blocks. clear ( ) ;
@@ -236,28 +228,36 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
236228 // goto chains. We should probably benchmark different sizes.
237229 let mut terminators: SmallVec < [ _ ; 1 ] > = Default :: default ( ) ;
238230 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 ;
239234 while let Some ( terminator) = self . take_terminator_if_simple_goto ( current) {
240235 let Terminator { kind : TerminatorKind :: Goto { target } , .. } = terminator else {
241236 unreachable ! ( ) ;
242237 } ;
238+ trivial_goto_chain &= self . pred_count [ target] == 1 ;
243239 terminators. push ( ( current, terminator) ) ;
244240 current = target;
245241 }
246242 let last = current;
247243 * changed |= * start != last;
248244 * start = last;
249- let mut succ = last;
250245 while let Some ( ( current, mut terminator) ) = terminators. pop ( ) {
251246 let Terminator { kind : TerminatorKind :: Goto { ref mut target } , .. } = terminator
252247 else {
253248 unreachable ! ( ) ;
254249 } ;
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) ;
259260 }
260- succ = current;
261261 * changed |= * target != last;
262262 * target = last;
263263 debug ! ( "collapsing goto chain from {:?} to {:?}" , current, target) ;
0 commit comments