This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] O(1) PHI argument look-up - Part 2/n


Hi,

Attached is a patch to part 2 of my O(1) PHI argument look-up patch.

When a PHI array is lined up with its corresponding edge vector in
near future, we won't need to keep edges in the PHI array as they will
be redundant, which means that PHI_ARG_EDGE will go away.  We could
keep it for compatibility reasons if we redefine it as

#define PHI_ARG_EDGE(NODE, I) (EDGE_PRED (bb_for_stmt ((NODE)), (I)))

but, in any case, write access to PHI_ARG_EDGE does not make any
sense.

The patch removes write access to PHI_ARG_EDGE in tree_split_edge.  We
let redirect_edge_and_branch construct PENDING_STMT and use that to
reinstall PHI arguments to the edge from the new basic block and the
destination of the original critical edge.

Tested on i686-pc-linux-gnu.  OK to apply?

Kazu Hirata

2004-11-18  Kazu Hirata  <kazu@cs.umass.edu>

	* tree-cfg.c (reinstall_phi_args): New.
	(tree_split_edge): Use it after redirecting an edge.  Don't
	modify PHI_ARG_EDGE.

Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-cfg.c,v
retrieving revision 2.111
diff -u -d -p -r2.111 tree-cfg.c
--- tree-cfg.c	17 Nov 2004 21:09:59 -0000	2.111
+++ tree-cfg.c	18 Nov 2004 06:50:22 -0000
@@ -3113,6 +3113,31 @@ bsi_insert_on_edge_immediate (edge e, tr
 	     Tree specific functions for CFG manipulation
 ---------------------------------------------------------------------------*/
 
+/* Reinstall those PHI arguments queued in OLD_EDGE to NEW_EDGE.  */
+
+static void
+reinstall_phi_args (edge new_edge, edge old_edge)
+{
+  tree var, phi;
+
+  if (!PENDING_STMT (old_edge))
+    return;
+  
+  for (var = PENDING_STMT (old_edge), phi = phi_nodes (new_edge->dest);
+       var && phi;
+       var = TREE_CHAIN (var), phi = PHI_CHAIN (phi))
+    {
+      tree result = TREE_PURPOSE (var);
+      tree arg = TREE_VALUE (var);
+
+      gcc_assert (result == PHI_RESULT (phi));
+
+      add_phi_arg (&phi, arg, new_edge);
+    }
+
+  PENDING_STMT (old_edge) = NULL;
+}
+
 /* Split a (typically critical) edge EDGE_IN.  Return the new block.
    Abort on abnormal edges.  */
 
@@ -3121,8 +3146,6 @@ tree_split_edge (edge edge_in)
 {
   basic_block new_bb, after_bb, dest, src;
   edge new_edge, e;
-  tree phi;
-  int i, num_elem;
   edge_iterator ei;
 
   /* Abnormal edges cannot be split.  */
@@ -3149,23 +3172,9 @@ tree_split_edge (edge edge_in)
   new_edge->probability = REG_BR_PROB_BASE;
   new_edge->count = edge_in->count;
 
-  /* Find all the PHI arguments on the original edge, and change them to
-     the new edge.  Do it before redirection, so that the argument does not
-     get removed.  */
-  for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
-    {
-      num_elem = PHI_NUM_ARGS (phi);
-      for (i = 0; i < num_elem; i++)
-	if (PHI_ARG_EDGE (phi, i) == edge_in)
-	  {
-	    PHI_ARG_EDGE (phi, i) = new_edge;
-	    break;
-	  }
-    }
-
   e = redirect_edge_and_branch (edge_in, new_bb);
   gcc_assert (e);
-  gcc_assert (!PENDING_STMT (edge_in));
+  reinstall_phi_args (new_edge, e);
 
   return new_bb;
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]