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
This commit is contained in:
parent
184799e763
commit
34554d1a8f
3 changed files with 52 additions and 13 deletions
|
@ -1,3 +1,11 @@
|
|||
2013-08-28 Jeff Law <law@redhat.com>
|
||||
|
||||
* 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 <jh@suse.cz>
|
||||
|
||||
* lto-streamer-out.c (DFS_write_tree_body): Drop
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Add table
Reference in a new issue