diff options
author | Jeff Law <law@redhat.com> | 2013-08-28 09:07:45 -0600 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2013-08-28 09:07:45 -0600 |
commit | 34554d1a8ff28d42caf020a4e68982458fc9ad93 (patch) | |
tree | 089b6bbb6feac49068fc164ef9c0ffc916a99955 /gcc/tree-ssa-threadupdate.c | |
parent | 184799e76349bb0cc0f3193194d32d1edd405cf9 (diff) | |
download | gcc-34554d1a8ff28d42caf020a4e68982458fc9ad93.zip gcc-34554d1a8ff28d42caf020a4e68982458fc9ad93.tar.gz gcc-34554d1a8ff28d42caf020a4e68982458fc9ad93.tar.bz2 |
tree-ssa-threadedge.c (thread_around_empty_block): Remove checks for the number of predecessors and successors allowed.
* tree-ssa-threadedge.c (thread_around_empty_block): Remove
checks for the number of predecessors and successors allowed.
* tree-ssa-threadupdate.c (mark_threaded_blocks): Ignore requests
which require copying a joiner block if there is a request which
is a subpath that requires no joiner block copying.
From-SVN: r202054
Diffstat (limited to 'gcc/tree-ssa-threadupdate.c')
-rw-r--r-- | gcc/tree-ssa-threadupdate.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index 259a691..8a872a3 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -1146,17 +1146,56 @@ mark_threaded_blocks (bitmap threaded_blocks) edge e; edge_iterator ei; + /* It is possible to have jump threads in which one is a subpath + of the other. ie, (A, B), (B, C), (C, D) where B is a joiner + block and (B, C), (C, D) where no joiner block exists. + + When this occurs ignore the jump thread request with the joiner + block. It's totally subsumed by the simpler jump thread request. + + This results in less block copying, simpler CFGs. More improtantly, + when we duplicate the joiner block, B, in this case we will create + a new threading opportunity that we wouldn't be able to optimize + until the next jump threading iteration. + + So first convert the jump thread requests which do not require a + joiner block. */ for (i = 0; i < threaded_edges.length (); i += 3) { edge e = threaded_edges[i]; - edge *x = XNEWVEC (edge, 2); - e->aux = x; - THREAD_TARGET (e) = threaded_edges[i + 1]; - THREAD_TARGET2 (e) = threaded_edges[i + 2]; - bitmap_set_bit (tmp, e->dest->index); + if (threaded_edges[i + 2] == NULL) + { + edge *x = XNEWVEC (edge, 2); + + e->aux = x; + THREAD_TARGET (e) = threaded_edges[i + 1]; + THREAD_TARGET2 (e) = NULL; + bitmap_set_bit (tmp, e->dest->index); + } } + + /* Now iterate again, converting cases where we threaded through + a joiner block, but ignoring those where we have already + threaded through the joiner block. */ + for (i = 0; i < threaded_edges.length (); i += 3) + { + edge e = threaded_edges[i]; + + if (threaded_edges[i + 2] != NULL + && threaded_edges[i + 1]->aux == NULL) + { + edge *x = XNEWVEC (edge, 2); + + e->aux = x; + THREAD_TARGET (e) = threaded_edges[i + 1]; + THREAD_TARGET2 (e) = threaded_edges[i + 2]; + bitmap_set_bit (tmp, e->dest->index); + } + } + + /* If optimizing for size, only thread through block if we don't have to duplicate it or it's an otherwise empty redirection block. */ if (optimize_function_for_size_p (cfun)) |