This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Change API for register_jump_thread to pass in an entire path
- From: Jeff Law <law at redhat dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 21 Aug 2013 13:28:13 -0600
- Subject: 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)