Change API for register_jump_thread to pass in an entire path

Message ID
State New
Headers show

Commit Message

Jeff Law Aug. 21, 2013, 7:28 p.m.
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  <>
+	* 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.
 	2013-08-20  Alexey Makhalov  <>
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 ();
+	    }
@@ -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;
@@ -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,
-		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.  */
-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)