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]

Change API for register_jump_thread to pass in an entire path



Right now, the API to register a requested jump thread passes three edges. The incoming edge we traverse, the outgoing edge we know will be taken as a result of traversing the incoming edge and an optional edge to allow us to find the joiner block when we thread through a join node.

Note that incoming_edge->dest does not have to reference the same block as outgoing_edge->src as we allow the threader to thread across multiple blocks. When we thread through multiple blocks, the latter blocks must be empty (no side effects other than control transfer).

The limitations we place when threading around empty blocks have kept the updating code relatively simple as we do not need to clone those empty blocks -- we just need to know where they're going to transfer control to.

As a result, the current code to update the SSA and CFG representations after threading a jump just needs to clone a single block and its side effects and perform minimal PHI node updates.


The general form of the FSA optimization changes things a bit in that we need to clone two blocks. This entails additional PHI node updates. To enable proper updating of the PHI nodes we need more pieces of the threaded path. Rather than add another special argument to the register_jump_thread API, I'm changing the API to record the entire threaded path.

This patch just changes the API so the full path is available. The SSA/CFG updating code (right now) just converts the full path into the 3-edge form. This does not change the generated code in any way shape or form.


Bootstrapped and regression tested on x86_64-unknown-linux-gnu.  Installed.


diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7162f34..ba9c7c9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
 2013-08-21  Jeff Law  <law@redhat.com>
 
+	* tree-flow.h (register_jump_thread): Pass vector of edges
+	instead of each important edge.
+	* tree-ssa-threadedge.c (thread_across_edge): Build the jump
+	thread path into a vector and pass that to register_jump_thread.
+	* tree-ssa-threadupdate.c (register_jump_thread): Conver the
+	passed in edge vector to the current 3-edge form.
+
 	Revert:
 	2013-08-20  Alexey Makhalov  <makhaloff@gmail.com>
 
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index caa8d74..01e6562 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -750,7 +750,7 @@ bool may_be_nonaddressable_p (tree expr);
 
 /* In tree-ssa-threadupdate.c.  */
 extern bool thread_through_all_blocks (bool);
-extern void register_jump_thread (edge, edge, edge);
+extern void register_jump_thread (vec<edge>);
 
 /* In gimplify.c  */
 tree force_gimple_operand_1 (tree, gimple_seq *, gimple_predicate, tree);
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 357b671..320dec5 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -937,10 +937,15 @@ thread_across_edge (gimple dummy_cond,
 	    }
 
 	  remove_temporary_equivalences (stack);
-	  if (!taken_edge)
-	    return;
-	  propagate_threaded_block_debug_into (taken_edge->dest, e->dest);
-	  register_jump_thread (e, taken_edge, NULL);
+	  if (taken_edge)
+	    {
+	      vec<edge> path = vNULL;
+	      propagate_threaded_block_debug_into (taken_edge->dest, e->dest);
+	      path.safe_push (e);
+	      path.safe_push (taken_edge);
+	      register_jump_thread (path);
+	      path.release ();
+	    }
 	  return;
 	}
     }
@@ -969,9 +974,12 @@ thread_across_edge (gimple dummy_cond,
 	bitmap_clear (visited);
 	bitmap_set_bit (visited, taken_edge->dest->index);
 	bitmap_set_bit (visited, e->dest->index);
+        vec<edge> path = vNULL;
 
 	/* Record whether or not we were able to thread through a successor
 	   of E->dest.  */
+	path.safe_push (e);
+	path.safe_push (taken_edge);
 	found = false;
 	e3 = taken_edge;
 	do
@@ -988,6 +996,7 @@ thread_across_edge (gimple dummy_cond,
 
 	    if (e2)
 	      {
+		path.safe_push (e2);
 	        e3 = e2;
 		found = true;
 	      }
@@ -1008,10 +1017,11 @@ thread_across_edge (gimple dummy_cond,
 	      {
 		propagate_threaded_block_debug_into (e3->dest,
 						     taken_edge->dest);
-		register_jump_thread (e, taken_edge, e3);
+		register_jump_thread (path);
 	      }
 	  }
 
+        path.release();
       }
     BITMAP_FREE (visited);
   }
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index 0e4cbc9..e84542c 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -1264,8 +1264,19 @@ thread_through_all_blocks (bool may_peel_loop_headers)
    after fixing the SSA graph.  */
 
 void
-register_jump_thread (edge e, edge e2, edge e3)
+register_jump_thread (vec<edge> path)
 {
+  /* Convert PATH into 3 edge representation we've been using.  This
+     is temporary until we convert this file to use a path representation
+     throughout.  */
+  edge e = path[0];
+  edge e2 = path[1];
+
+  if (path.length () <= 2)
+    e3 = NULL;
+  else
+    e3 = path[path.length () - 1];
+
   /* This can occur if we're jumping to a constant address or
      or something similar.  Just get out now.  */
   if (e2 == NULL)

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