diff options
Diffstat (limited to 'gcc/tree-ssa-threadupdate.c')
-rw-r--r-- | gcc/tree-ssa-threadupdate.c | 102 |
1 files changed, 70 insertions, 32 deletions
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index fd5234c..75273ca 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "basic-block.h" #include "function.h" #include "tree-ssa.h" +#include "tree-ssa-threadupdate.h" #include "dumpfile.h" #include "cfgloop.h" #include "hash-table.h" @@ -1380,6 +1381,39 @@ thread_through_all_blocks (bool may_peel_loop_headers) return retval; } +/* Dump a jump threading path, including annotations about each + edge in the path. */ + +static void +dump_jump_thread_path (FILE *dump_file, vec<jump_thread_edge *> path) +{ + fprintf (dump_file, + " Registering jump thread: (%d, %d) incoming edge; ", + path[0]->e->src->index, path[0]->e->dest->index); + + for (unsigned int i = 1; i < path.length (); i++) + { + /* We can get paths with a NULL edge when the final destination + of a jump thread turns out to be a constant address. We dump + those paths when debugging, so we have to be prepared for that + possibility here. */ + if (path[i]->e == NULL) + continue; + + if (path[i]->type == EDGE_COPY_SRC_JOINER_BLOCK) + fprintf (dump_file, " (%d, %d) joiner; ", + path[i]->e->src->index, path[i]->e->dest->index); + if (path[i]->type == EDGE_COPY_SRC_BLOCK) + fprintf (dump_file, " (%d, %d) normal;", + path[i]->e->src->index, path[i]->e->dest->index); + if (path[i]->type == EDGE_NO_COPY_SRC_BLOCK) + fprintf (dump_file, " (%d, %d) nocopy;", + path[i]->e->src->index, path[i]->e->dest->index); + } + fputc ('\n', dump_file); +} + + /* Register a jump threading opportunity. We queue up all the jump threading opportunities discovered by a pass and update the CFG and SSA form all at once. @@ -1389,43 +1423,47 @@ thread_through_all_blocks (bool may_peel_loop_headers) after fixing the SSA graph. */ void -register_jump_thread (vec<edge> path, bool through_joiner) +register_jump_thread (vec<jump_thread_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]; - edge e3; - - if (!through_joiner) - e3 = NULL; - else - e3 = path.last (); + /* First make sure there are no NULL outgoing edges on the jump threading + path. That can happen for jumping to a constant address. */ + for (unsigned int i = 0; i < path.length (); i++) + if (path[i]->e == NULL) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, + "Found NULL edge in jump threading path. Cancelling jump thread:\n"); + dump_jump_thread_path (dump_file, path); + } + return; + } - /* This can occur if we're jumping to a constant address or - or something similar. Just get out now. */ - if (e2 == NULL) - return; + if (!threaded_edges.exists ()) + threaded_edges.create (15); if (dump_file && (dump_flags & TDF_DETAILS)) - { - unsigned int i; + dump_jump_thread_path (dump_file, path); - fprintf (dump_file, - " Registering jump thread %s:", - through_joiner ? "(through joiner block)" : ""); + /* The first entry in the vector is always the start of the + jump threading path. */ + threaded_edges.safe_push (path[0]->e); - for (i = 0; i < path.length (); i++) - fprintf (dump_file, " (%d, %d); ", - path[i]->src->index, path[i]->dest->index); - fputc ('\n', dump_file); - } - - if (!threaded_edges.exists ()) - threaded_edges.create (15); + /* In our 3-edge representation, the joiner, if it exists is always the + 2nd edge and the final block on the path is the 3rd edge. If no + jointer exists, then the final block on the path is the 2nd edge + and the 3rd edge is NULL. - threaded_edges.safe_push (e); - threaded_edges.safe_push (e2); - threaded_edges.safe_push (e3); + With upcoming improvements, we're going to be holding onto the entire + path, so we'll be able to clean this wart up shortly. */ + if (path[1]->type == EDGE_COPY_SRC_JOINER_BLOCK) + { + threaded_edges.safe_push (path[1]->e); + threaded_edges.safe_push (path.last ()->e); + } + else + { + threaded_edges.safe_push (path.last ()->e); + threaded_edges.safe_push (NULL); + } } |