diff options
author | Jeff Law <law@redhat.com> | 2013-11-19 18:55:17 -0700 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2013-11-19 18:55:17 -0700 |
commit | 5f51d006610d5d74bda8f3f35eaba7ce8c0e90f1 (patch) | |
tree | 0201b6c20a42aa103d18e98486e543f4c3d753fa /gcc | |
parent | 2ed4d7ee3cc50b3ff1fd80eee9152450c0a37711 (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/tree-ssa-threadedge.c | 8 | ||||
-rw-r--r-- | gcc/tree-ssa-threadupdate.c | 73 |
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); |