On 11/19/13 19:33, David Malcolm wrote:
FWIW, it looks like you attached the whitespace cleanup patch again, rather than the one you discuss above. For the archives, it looks like your email is referring to r205074 (though that itself seems to have some purely whitespace fixes, together with the real changes).
Nuts. Here's the actual change I meant to attach. Sorry about that, thanks for catching it. Jeff
commit f28876ff94428d3109e9e575d6a2d62d23af8092 Author: law <law@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Wed Nov 20 01:55:17 2013 +0000 * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@205074 138bc75d-0d04-0410-961f-82ee72b054a4 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 <l...@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);