aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-threadupdate.c
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2013-08-28 09:07:45 -0600
committerJeff Law <law@gcc.gnu.org>2013-08-28 09:07:45 -0600
commit34554d1a8ff28d42caf020a4e68982458fc9ad93 (patch)
tree089b6bbb6feac49068fc164ef9c0ffc916a99955 /gcc/tree-ssa-threadupdate.c
parent184799e76349bb0cc0f3193194d32d1edd405cf9 (diff)
downloadgcc-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.c49
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))