aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2013-11-19 18:55:17 -0700
committerJeff Law <law@gcc.gnu.org>2013-11-19 18:55:17 -0700
commit5f51d006610d5d74bda8f3f35eaba7ce8c0e90f1 (patch)
tree0201b6c20a42aa103d18e98486e543f4c3d753fa /gcc
parent2ed4d7ee3cc50b3ff1fd80eee9152450c0a37711 (diff)
downloadgcc-5f51d006610d5d74bda8f3f35eaba7ce8c0e90f1.zip
gcc-5f51d006610d5d74bda8f3f35eaba7ce8c0e90f1.tar.gz
gcc-5f51d006610d5d74bda8f3f35eaba7ce8c0e90f1.tar.bz2
tree-ssa-threadedge.c (thread_across_edge): After threading through a joiner...
* tree-ssa-threadedge.c (thread_across_edge): After threading through a joiner, allow threading a normal block requiring duplication. * tree-ssa-threadupdate.c (thread_block_1): Improve code to detect jump threading requests that would muck up the loop structures. From-SVN: r205074
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/tree-ssa-threadedge.c8
-rw-r--r--gcc/tree-ssa-threadupdate.c73
3 files changed, 62 insertions, 28 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 01bef34..7688983 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
2013-11-19 Jeff Law <law@redhat.com>
-
+
+ * tree-ssa-threadedge.c (thread_across_edge): After threading
+ through a joiner, allow threading a normal block requiring
+ duplication.
+
+ * tree-ssa-threadupdate.c (thread_block_1): Improve code to detect
+ jump threading requests that would muck up the loop structures.
+
* tree-ssa-threadupdate.c: Fix trailing whitespace.
* tree-ssa-threadupdate.h: Likewise.
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index b90ff23..7bb8829 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -1098,6 +1098,14 @@ thread_across_edge (gimple dummy_cond,
path,
&backedge_seen);
+ if (!found
+ && (!backedge_seen
+ || ! cond_arg_set_in_bb (path->last ()->e, e->dest)))
+ found = thread_through_normal_block (path->last ()->e, dummy_cond,
+ handle_dominating_asserts,
+ stack, simplify, path, visited,
+ &backedge_seen);
+
/* If we were able to thread through a successor of E->dest, then
record the jump threading opportunity. */
if (found)
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index 1b7c73d..777fe41 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -328,7 +328,7 @@ lookup_redirection_data (edge e, enum insert_option insert)
to the list of incoming edges associated with E. */
if (insert)
{
- struct el *el = XNEW (struct el);
+ struct el *el = XNEW (struct el);
el->next = elt->incoming_edges;
el->e = e;
elt->incoming_edges = el;
@@ -496,11 +496,11 @@ ssa_fix_duplicate_block_edges (struct redirection_data *rd,
e2 = redirect_edge_and_branch (victim, path->last ()->e->dest);
e2->count = path->last ()->e->count;
/* If we redirected the edge, then we need to copy PHI arguments
- at the target. If the edge already existed (e2 != victim
+ at the target. If the edge already existed (e2 != victim
case), then the PHIs in the target already have the correct
arguments. */
if (e2 == victim)
- copy_phi_args (e2->dest, path->last ()->e, e2);
+ copy_phi_args (e2->dest, path->last ()->e, e2);
}
else
{
@@ -550,7 +550,7 @@ ssa_create_duplicates (struct redirection_data **slot,
/* The second duplicated block in a jump threading path is specific
to the path. So it gets stored in RD rather than in LOCAL_DATA.
-
+
Each time we're called, we have to look through the path and see
if a second block needs to be duplicated.
@@ -672,7 +672,7 @@ ssa_redirect_edges (struct redirection_data **slot,
}
/* Go ahead and clear E->aux. It's not needed anymore and failure
- to clear it will cause all kinds of unpleasant problems later. */
+ to clear it will cause all kinds of unpleasant problems later. */
delete_jump_thread_path (path);
e->aux = NULL;
@@ -697,9 +697,9 @@ redirection_block_p (basic_block bb)
/* Advance to the first executable statement. */
gsi = gsi_start_bb (bb);
while (!gsi_end_p (gsi)
- && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
+ && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
|| is_gimple_debug (gsi_stmt (gsi))
- || gimple_nop_p (gsi_stmt (gsi))))
+ || gimple_nop_p (gsi_stmt (gsi))))
gsi_next (&gsi);
/* Check if this is an empty block. */
@@ -708,9 +708,9 @@ redirection_block_p (basic_block bb)
/* Test that we've reached the terminating control statement. */
return gsi_stmt (gsi)
- && (gimple_code (gsi_stmt (gsi)) == GIMPLE_COND
- || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
- || gimple_code (gsi_stmt (gsi)) == GIMPLE_SWITCH);
+ && (gimple_code (gsi_stmt (gsi)) == GIMPLE_COND
+ || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
+ || gimple_code (gsi_stmt (gsi)) == GIMPLE_SWITCH);
}
/* BB is a block which ends with a COND_EXPR or SWITCH_EXPR and when BB
@@ -795,22 +795,12 @@ thread_block_1 (basic_block bb, bool noloop_only, bool joiners)
if (!e2 || noloop_only)
{
/* If NOLOOP_ONLY is true, we only allow threading through the
- header of a loop to exit edges.
-
- There are two cases to consider. The first when BB is the
- loop header. We will attempt to thread this elsewhere, so
- we can just continue here. */
-
- if (bb == bb->loop_father->header
- && (!loop_exit_edge_p (bb->loop_father, e2)
- || (*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK))
- continue;
-
+ header of a loop to exit edges. */
- /* The second occurs when there was loop header buried in a jump
- threading path. We do not try and thread this elsewhere, so
- just cancel the jump threading request by clearing the AUX
- field now. */
+ /* One case occurs when there was loop header buried in a jump
+ threading path that crosses loop boundaries. We do not try
+ and thread this elsewhere, so just cancel the jump threading
+ request by clearing the AUX field now. */
if ((bb->loop_father != e2->src->loop_father
&& !loop_exit_edge_p (e2->src->loop_father, e2))
|| (e2->src->loop_father != e2->dest->loop_father
@@ -823,11 +813,40 @@ thread_block_1 (basic_block bb, bool noloop_only, bool joiners)
e->aux = NULL;
continue;
}
+
+ /* Another case occurs when trying to thread through our
+ own loop header, possibly from inside the loop.
+
+ If our loop header is buried in the path, then go ahead
+ and cancel the jump threading request here. This likely
+ will need updating for the FSA/FSM coremark case.
+
+ Other cases (BB is the loop header) are handled elsewhere. */
+ unsigned int i;
+ for (i = 1; i < path->length (); i++)
+ {
+ if ((*path)[i]->e->src == bb->loop_father->header
+ && (!loop_exit_edge_p (bb->loop_father, e2)
+ || (*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK))
+ {
+ /* If i != 1, then it's a buried header that will not
+ be handled elsehwere. */
+ if (i != 1)
+ {
+ delete_jump_thread_path (path);
+ e->aux = NULL;
+ }
+ break;
+ }
+ }
+
+ if (i != path->length ())
+ continue;
}
if (e->dest == e2->src)
update_bb_profile_for_threading (e->dest, EDGE_FREQUENCY (e),
- e->count, (*THREAD_PATH (e))[1]->e);
+ e->count, (*THREAD_PATH (e))[1]->e);
/* Insert the outgoing edge into the hash table if it is not
already in the hash table. */
@@ -1242,7 +1261,7 @@ thread_through_loop_header (struct loop *loop, bool may_peel_loop_headers)
unsigned nblocks, i;
/* First handle the case latch edge is redirected. We are copying
- the loop header but not creating a multiple entry loop. Make the
+ the loop header but not creating a multiple entry loop. Make the
cfg manipulation code aware of that fact. */
set_loop_copy (loop, loop);
loop->latch = thread_single_edge (latch);