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]>
---
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 62513045c6f..5a082eee524 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 611d9225e1e..520bb3aefbd 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 bac68f1533d..803d8599b57 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
--
2.43.0