Jakub Jelinek <ja...@redhat.com> writes: > On Fri, Jun 13, 2025 at 10:05:14AM +0200, Jakub Jelinek wrote: >> On Fri, Jun 13, 2025 at 08:52:55AM +0100, Richard Sandiford wrote: >> > > 2025-06-12 Jakub Jelinek <ja...@redhat.com> >> > > >> > > * cfgexpand.cc (construct_init_block): If first_block isn't BB_RTL, >> > > has any PHI nodes and false_edge->dest_idx before redirection is >> > > different from make_single_succ_edge result's dest_idx, swap the >> > > latter with the former last pred edge and their dest_idx members. >> > >> > OK, thanks. But now that there are two instances, I wonder if it would >> > be worth hiding this detail in a helper function? >> >> Will try to come up with something incrementally if that is ok. > > Here it is, so far lightly tested. Ok for trunk if it passes full > bootstrap/regtest? > > 2025-06-13 Jakub Jelinek <ja...@redhat.com> > > PR middle-end/120629 > * cfgexpand.cc (expand_split_edge): New function. > (expand_gimple_cond, construct_init_block): Use it.
OK. Thanks for doing this! Richard > --- gcc/cfgexpand.cc.jj 2025-06-13 14:01:15.168637257 +0200 > +++ gcc/cfgexpand.cc 2025-06-13 14:17:14.896303981 +0200 > @@ -2830,6 +2830,31 @@ expand_remove_edge (edge e) > remove_edge (e); > } > > +/* Split edge E during expansion and instead of creating a new > + bb on that edge, add there BB. FLAGS should be flags on the > + new edge from BB to former E->dest. */ > + > +static void > +expand_split_edge (edge e, basic_block bb, int flags) > +{ > + unsigned int dest_idx = e->dest_idx; > + basic_block dest = e->dest; > + redirect_edge_succ (e, bb); > + e = make_single_succ_edge (bb, dest, flags); > + if ((dest->flags & BB_RTL) == 0 > + && phi_nodes (dest) > + && e->dest_idx != dest_idx) > + { > + /* If there are any PHI nodes on dest, swap the new succ edge > + with the one moved into false_edge's former position, so that > + PHI arguments don't need adjustment. */ > + edge e2 = EDGE_PRED (dest, dest_idx); > + std::swap (e->dest_idx, e2->dest_idx); > + std::swap (EDGE_PRED (dest, e->dest_idx), > + EDGE_PRED (dest, e2->dest_idx)); > + } > +} > + > > /* A subroutine of expand_gimple_cond. Given E, a fallthrough edge > of a basic block where we just expanded the conditional at the end, > @@ -3013,8 +3038,7 @@ expand_gimple_cond (basic_block bb, gcon > > new_bb = create_basic_block (NEXT_INSN (last), get_last_insn (), bb); > dest = false_edge->dest; > - unsigned int dest_idx = false_edge->dest_idx; > - redirect_edge_succ (false_edge, new_bb); > + expand_split_edge (false_edge, new_bb, 0); > false_edge->flags |= EDGE_FALLTHRU; > new_bb->count = false_edge->count (); > loop_p loop = find_common_loop (bb->loop_father, dest->loop_father); > @@ -3022,19 +3046,6 @@ expand_gimple_cond (basic_block bb, gcon > if (loop->latch == bb > && loop->header == dest) > loop->latch = new_bb; > - edge e = make_single_succ_edge (new_bb, dest, 0); > - if ((dest->flags & BB_RTL) == 0 > - && phi_nodes (dest) > - && e->dest_idx != dest_idx) > - { > - /* If there are any PHI nodes on dest, swap the new succ edge > - with the one moved into false_edge's former position, so that > - PHI arguments don't need adjustment. */ > - edge e2 = EDGE_PRED (dest, dest_idx); > - std::swap (e->dest_idx, e2->dest_idx); > - std::swap (EDGE_PRED (dest, e->dest_idx), > - EDGE_PRED (dest, e2->dest_idx)); > - } > if (BARRIER_P (BB_END (new_bb))) > BB_END (new_bb) = PREV_INSN (BB_END (new_bb)); > update_bb_for_insn (new_bb); > @@ -6538,7 +6549,7 @@ expand_gimple_basic_block (basic_block b > static basic_block > construct_init_block (void) > { > - basic_block init_block, first_block; > + basic_block init_block; > edge e = NULL; > int flags; > > @@ -6569,24 +6580,7 @@ construct_init_block (void) > init_block->count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count; > add_bb_to_loop (init_block, ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father); > if (e) > - { > - unsigned int dest_idx = e->dest_idx; > - first_block = e->dest; > - redirect_edge_succ (e, init_block); > - e = make_single_succ_edge (init_block, first_block, flags); > - if ((first_block->flags & BB_RTL) == 0 > - && phi_nodes (first_block) > - && e->dest_idx != dest_idx) > - { > - /* If there are any PHI nodes on dest, swap the new succ edge > - with the one moved into false_edge's former position, so that > - PHI arguments don't need adjustment. */ > - edge e2 = EDGE_PRED (first_block, dest_idx); > - std::swap (e->dest_idx, e2->dest_idx); > - std::swap (EDGE_PRED (first_block, e->dest_idx), > - EDGE_PRED (first_block, e2->dest_idx)); > - } > - } > + expand_split_edge (e, init_block, flags); > else > make_single_succ_edge (init_block, EXIT_BLOCK_PTR_FOR_FN (cfun), > EDGE_FALLTHRU); > > > Jakub