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

Reply via email to