From 34554d1a8ff28d42caf020a4e68982458fc9ad93 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Wed, 28 Aug 2013 09:07:45 -0600 Subject: [PATCH] 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 --- gcc/ChangeLog | 8 ++++++++ gcc/tree-ssa-threadedge.c | 8 -------- gcc/tree-ssa-threadupdate.c | 49 ++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a19826b..3d87dbb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2013-08-28 Jeff Law + + * 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. + 2013-08-28 Jan Hubicka * lto-streamer-out.c (DFS_write_tree_body): Drop diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index 320dec5..fc33647 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -761,14 +761,6 @@ thread_around_empty_block (edge taken_edge, gimple stmt; tree cond; - /* This block must have a single predecessor (E->dest). */ - if (!single_pred_p (bb)) - return NULL; - - /* This block must have more than one successor. */ - if (single_succ_p (bb)) - return NULL; - /* This block can have no PHI nodes. This is overly conservative. */ if (!gsi_end_p (gsi_start_phis (bb))) return NULL; 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)) -- 2.7.4