https://gcc.gnu.org/g:52165aa6b1d1a6f80bef6c90370a3b0f1a4124f6
commit r16-5256-g52165aa6b1d1a6f80bef6c90370a3b0f1a4124f6 Author: Andrew Pinski <[email protected]> Date: Tue Nov 11 00:38:25 2025 -0800 mergephi: extend copy_phi_arg_into_existing_phi and use it for remove_forwarder_block_with_phi copy_phi_arg_into_existing_phi was added in r14-477-g78b0eea7802698 and used in remove_forwarder_block but since remove_forwarder_block_with_phi needed to use the redirect edge var map, it was not moved over. This extends copy_phi_arg_into_existing_phi to have the ability to optional use the mapper. This also makes remove_forwarder_block_with_phi and remove_forwarder_block closer to one another. There is a few other changes needed to be able to do both from the same function. Bootstrapped and tested on x86_64-linux-gnu. gcc/ChangeLog: * tree-cfg.cc (copy_phi_arg_into_existing_phi): New use_map argument. * tree-cfg.h (copy_phi_arg_into_existing_phi): Update declaration. * tree-cfgcleanup.cc (remove_forwarder_block_with_phi): Use copy_phi_arg_into_existing_phi instead of inlining it. Signed-off-by: Andrew Pinski <[email protected]> Diff: --- gcc/tree-cfg.cc | 30 ++++++++++++++++++++++++++++-- gcc/tree-cfg.h | 2 +- gcc/tree-cfgcleanup.cc | 39 +-------------------------------------- 3 files changed, 30 insertions(+), 41 deletions(-) diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index 62513045c6f0..5a082eee5243 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -6791,10 +6791,12 @@ bb_part_of_region_p (basic_block bb, basic_block* bbs, unsigned n_region) /* For each PHI in BB, copy the argument associated with SRC_E to TGT_E. - Assuming the argument exists, just does not have a value. */ + Assuming the argument exists, just does not have a value. + If USE_MAP is true, then use the redirect edge var map of TGT_E + for the new arguments; clearing the map afterwards. */ void -copy_phi_arg_into_existing_phi (edge src_e, edge tgt_e) +copy_phi_arg_into_existing_phi (edge src_e, edge tgt_e, bool use_map) { int src_idx = src_e->dest_idx; int tgt_idx = tgt_e->dest_idx; @@ -6810,9 +6812,33 @@ copy_phi_arg_into_existing_phi (edge src_e, edge tgt_e) tree val = gimple_phi_arg_def (src_phi, src_idx); location_t locus = gimple_phi_arg_location (src_phi, src_idx); + if (use_map && TREE_CODE (val) == SSA_NAME) + { + /* If DEF is one of the results of PHI nodes removed during + redirection, replace it with the PHI argument that used + to be on E. */ + vec<edge_var_map> *head = redirect_edge_var_map_vector (tgt_e); + size_t length = head ? head->length () : 0; + for (size_t i = 0; i < length; i++) + { + edge_var_map *vm = &(*head)[i]; + tree old_arg = redirect_edge_var_map_result (vm); + tree new_arg = redirect_edge_var_map_def (vm); + + if (val == old_arg) + { + val = new_arg; + locus = redirect_edge_var_map_location (vm); + break; + } + } + } + SET_PHI_ARG_DEF (dest_phi, tgt_idx, val); gimple_phi_arg_set_location (dest_phi, tgt_idx, locus); } + if (use_map) + redirect_edge_var_map_clear (tgt_e); } /* Duplicates REGION consisting of N_REGION blocks. The new blocks diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h index 611d9225e1e7..520bb3aefbd1 100644 --- a/gcc/tree-cfg.h +++ b/gcc/tree-cfg.h @@ -113,7 +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_arg_into_existing_phi (edge, edge); +extern void copy_phi_arg_into_existing_phi (edge, edge, bool = false); /* Return true if the LHS of a call should be removed. */ diff --git a/gcc/tree-cfgcleanup.cc b/gcc/tree-cfgcleanup.cc index bac68f1533d5..803d8599b577 100644 --- a/gcc/tree-cfgcleanup.cc +++ b/gcc/tree-cfgcleanup.cc @@ -1307,7 +1307,6 @@ remove_forwarder_block_with_phi (basic_block bb) for (edge_iterator ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); ) { edge s; - gphi_iterator gsi; s = find_edge (e->src, dest); if (s) @@ -1345,43 +1344,7 @@ remove_forwarder_block_with_phi (basic_block bb) /* redirect_edge_and_branch must not create a new edge. */ gcc_assert (s == e); - - /* Add to the PHI nodes at DEST each PHI argument removed at the - destination of E. */ - for (gsi = gsi_start_phis (dest); - !gsi_end_p (gsi); - gsi_next (&gsi)) - { - gphi *phi = gsi.phi (); - tree def = gimple_phi_arg_def (phi, succ->dest_idx); - location_t locus = gimple_phi_arg_location_from_edge (phi, succ); - - if (TREE_CODE (def) == SSA_NAME) - { - /* If DEF is one of the results of PHI nodes removed during - redirection, replace it with the PHI argument that used - to be on E. */ - vec<edge_var_map> *head = redirect_edge_var_map_vector (e); - size_t length = head ? head->length () : 0; - for (size_t i = 0; i < length; i++) - { - edge_var_map *vm = &(*head)[i]; - tree old_arg = redirect_edge_var_map_result (vm); - tree new_arg = redirect_edge_var_map_def (vm); - - if (def == old_arg) - { - def = new_arg; - locus = redirect_edge_var_map_location (vm); - break; - } - } - } - - add_phi_arg (phi, def, s, locus); - } - - redirect_edge_var_map_clear (e); + copy_phi_arg_into_existing_phi (succ, s, true); } /* Move debug statements. Reset them if the destination does not
