While improving replace_phi_edge_with_variable for the diamond formed bb case, I needed a new function, copy_phi_args and then I went to search for similar code and noticed both gimple_duplicate_sese_tail and remove_forwarder_block have the same code I need. So I decided it would be best if I factor it out into a new function into a common area and call it from those two places (and will use it for phiopt too).
OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. gcc/ChangeLog: * tree-cfg.cc (copy_phi_args): New function (gimple_duplicate_sese_tail): Use it instead of doing it inline. * tree-cfg.h (copy_phi_args): New declaration. * tree-cfgcleanup.cc (remove_forwarder_block): Use copy_phi_args instead of implementing it inline. --- gcc/tree-cfg.cc | 29 ++++++++++++++++++----------- gcc/tree-cfg.h | 1 + gcc/tree-cfgcleanup.cc | 10 +--------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index 4927fc0a8d9..3f24d9c5b1c 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -6802,6 +6802,23 @@ bb_part_of_region_p (basic_block bb, basic_block* bbs, unsigned n_region) return false; } +/* For each PHI in BB, copy the PHI argument associated with SRC_E to TGT_E. */ + +void +copy_phi_args (basic_block bb, edge src_e, edge tgt_e) +{ + gphi_iterator gsi; + int src_indx = src_e->dest_idx; + + for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gphi *phi = gsi.phi (); + tree def = gimple_phi_arg_def (phi, src_indx); + location_t locus = gimple_phi_arg_location (phi, src_indx); + add_phi_arg (phi, unshare_expr (def), tgt_e, locus); + } +} + /* Duplicates REGION consisting of N_REGION blocks. The new blocks are stored to REGION_COPY in the same order in that they appear in REGION, if REGION_COPY is not NULL. ENTRY is the entry to @@ -6847,9 +6864,6 @@ gimple_duplicate_sese_tail (edge entry, edge exit, gimple_stmt_iterator gsi; edge sorig, snew; basic_block exit_bb; - gphi_iterator psi; - gphi *phi; - tree def; class loop *target, *aloop, *cloop; gcc_assert (EDGE_COUNT (exit->src->succs) == 2); @@ -6947,14 +6961,7 @@ gimple_duplicate_sese_tail (edge entry, edge exit, gcc_assert (single_succ_edge (region_copy[i])); e = redirect_edge_and_branch (single_succ_edge (region_copy[i]), exit_bb); PENDING_STMT (e) = NULL; - for (psi = gsi_start_phis (exit_bb); - !gsi_end_p (psi); - gsi_next (&psi)) - { - phi = psi.phi (); - def = PHI_ARG_DEF (phi, nexits[0]->dest_idx); - add_phi_arg (phi, def, e, gimple_phi_arg_location_from_edge (phi, e)); - } + copy_phi_args (exit_bb, nexits[0], e); } e = redirect_edge_and_branch (nexits[1], nexits[0]->dest); PENDING_STMT (e) = NULL; diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h index 9b56a68fe9d..7ec3f812a76 100644 --- a/gcc/tree-cfg.h +++ b/gcc/tree-cfg.h @@ -113,6 +113,7 @@ extern basic_block gimple_switch_default_bb (function *, gswitch *); extern edge gimple_switch_edge (function *, gswitch *, unsigned); extern edge gimple_switch_default_edge (function *, gswitch *); extern bool cond_only_block_p (basic_block); +extern void copy_phi_args (basic_block, edge, edge); /* Return true if the LHS of a call should be removed. */ diff --git a/gcc/tree-cfgcleanup.cc b/gcc/tree-cfgcleanup.cc index 42b25312122..f3582e5ce52 100644 --- a/gcc/tree-cfgcleanup.cc +++ b/gcc/tree-cfgcleanup.cc @@ -612,15 +612,7 @@ remove_forwarder_block (basic_block bb) { /* Create arguments for the phi nodes, since the edge was not here before. */ - for (gphi_iterator psi = gsi_start_phis (dest); - !gsi_end_p (psi); - gsi_next (&psi)) - { - gphi *phi = psi.phi (); - location_t l = gimple_phi_arg_location_from_edge (phi, succ); - tree def = gimple_phi_arg_def (phi, succ->dest_idx); - add_phi_arg (phi, unshare_expr (def), s, l); - } + copy_phi_args (dest, succ, s); } } -- 2.39.1