Commit 072269d8 by Kazu Hirata Committed by Kazu Hirata

tree-cfg.c (thread_jumps): Move a part of it to ...

	* tree-cfg.c (thread_jumps): Move a part of it to ...
	(thread_jumps_from_bb): ... here.

From-SVN: r89380
parent 5303e3d7
2004-10-21 Kazu Hirata <kazu@cs.umass.edu>
* tree-cfg.c (thread_jumps): Move a part of it to ...
(thread_jumps_from_bb): ... here.
2004-10-21 David Edelsohn <edelsohn@gnu.org> 2004-10-21 David Edelsohn <edelsohn@gnu.org>
* dbxout.c (DBX_FINISH_SYMBOL): Add asm_out_file argument. * dbxout.c (DBX_FINISH_SYMBOL): Add asm_out_file argument.
......
...@@ -3759,40 +3759,14 @@ tree_forwarder_block_p (basic_block bb) ...@@ -3759,40 +3759,14 @@ tree_forwarder_block_p (basic_block bb)
return true; return true;
} }
/* Thread jumps from BB. */
/* Thread jumps over empty statements.
This code should _not_ thread over obviously equivalent conditions
as that requires nontrivial updates to the SSA graph.
As a precondition, we require that all basic blocks be reachable.
That is, there should be no opportunities left for
delete_unreachable_blocks. */
static bool static bool
thread_jumps (void) thread_jumps_from_bb (basic_block bb)
{ {
edge e, last, old;
basic_block bb, dest, tmp, old_dest, curr, dom;
tree phi;
int arg;
bool retval = false;
bool rerun;
FOR_EACH_BB (bb)
bb_ann (bb)->forwardable = tree_forwarder_block_p (bb);
do
{
rerun = false;
FOR_EACH_BB (bb)
{
edge_iterator ei; edge_iterator ei;
bool this_jump_threaded = false; edge e;
bool retval = false;
/* Don't waste time on forwarders. */
if (bb_ann (bb)->forwardable)
continue;
/* Examine each of our block's successors to see if it is /* Examine each of our block's successors to see if it is
forwardable. */ forwardable. */
...@@ -3800,6 +3774,10 @@ thread_jumps (void) ...@@ -3800,6 +3774,10 @@ thread_jumps (void)
{ {
int freq; int freq;
gcov_type count; gcov_type count;
edge last, old;
basic_block dest, tmp, curr, old_dest;
tree phi;
int arg;
/* If the edge is abnormal or its destination is not /* If the edge is abnormal or its destination is not
forwardable, then there's nothing to do. */ forwardable, then there's nothing to do. */
...@@ -3813,9 +3791,8 @@ thread_jumps (void) ...@@ -3813,9 +3791,8 @@ thread_jumps (void)
count = e->count; count = e->count;
freq = EDGE_FREQUENCY (e); freq = EDGE_FREQUENCY (e);
/* Now walk through as many forwarder blocks as possible to /* Now walk through as many forwarder blocks as possible to find
find the ultimate destination we want to thread our jump the ultimate destination we want to thread our jump to. */
to. */
last = EDGE_SUCC (e->dest, 0); last = EDGE_SUCC (e->dest, 0);
bb_ann (e->dest)->forwardable = 0; bb_ann (e->dest)->forwardable = 0;
for (dest = EDGE_SUCC (e->dest, 0)->dest; for (dest = EDGE_SUCC (e->dest, 0)->dest;
...@@ -3839,8 +3816,8 @@ thread_jumps (void) ...@@ -3839,8 +3816,8 @@ thread_jumps (void)
old = find_edge (bb, dest); old = find_edge (bb, dest);
if (old) if (old)
{ {
/* If there already is an edge, check whether the values /* If there already is an edge, check whether the values in
in phi nodes differ. */ phi nodes differ. */
if (!phi_alternatives_equal (dest, last, old)) if (!phi_alternatives_equal (dest, last, old))
{ {
/* The previous block is forwarder. Redirect our jump /* The previous block is forwarder. Redirect our jump
...@@ -3861,7 +3838,7 @@ thread_jumps (void) ...@@ -3861,7 +3838,7 @@ thread_jumps (void)
} }
/* Perform the redirection. */ /* Perform the redirection. */
retval = this_jump_threaded = true; retval = true;
old_dest = e->dest; old_dest = e->dest;
e = redirect_edge_and_branch (e, dest); e = redirect_edge_and_branch (e, dest);
...@@ -3884,10 +3861,10 @@ thread_jumps (void) ...@@ -3884,10 +3861,10 @@ thread_jumps (void)
if (!old) if (!old)
{ {
/* Update PHI nodes. We know that the new argument /* Update PHI nodes. We know that the new argument should
should have the same value as the argument have the same value as the argument associated with LAST.
associated with LAST. Otherwise we would have Otherwise we would have changed our target block
changed our target block above. */ above. */
for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi)) for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
{ {
arg = phi_arg_from_edge (phi, last); arg = phi_arg_from_edge (phi, last);
...@@ -3919,9 +3896,9 @@ thread_jumps (void) ...@@ -3919,9 +3896,9 @@ thread_jumps (void)
if (get_immediate_dominator (CDI_DOMINATORS, old_dest) == NULL) if (get_immediate_dominator (CDI_DOMINATORS, old_dest) == NULL)
set_immediate_dominator (CDI_DOMINATORS, old_dest, bb); set_immediate_dominator (CDI_DOMINATORS, old_dest, bb);
/* Now proceed like if we forwarded just over one /* Now proceed like if we forwarded just over one edge at a
edge at a time. Algorithm for forwarding edge time. Algorithm for forwarding edge S --> A over
S --> A over edge A --> B then is edge A --> B then is
if (idom (B) == A if (idom (B) == A
&& !dominated_by (S, B)) && !dominated_by (S, B))
...@@ -3930,6 +3907,8 @@ thread_jumps (void) ...@@ -3930,6 +3907,8 @@ thread_jumps (void)
for (; old_dest != dest; old_dest = tmp) for (; old_dest != dest; old_dest = tmp)
{ {
basic_block dom;
tmp = EDGE_SUCC (old_dest, 0)->dest; tmp = EDGE_SUCC (old_dest, 0)->dest;
if (get_immediate_dominator (CDI_DOMINATORS, tmp) == old_dest if (get_immediate_dominator (CDI_DOMINATORS, tmp) == old_dest
...@@ -3945,15 +3924,52 @@ thread_jumps (void) ...@@ -3945,15 +3924,52 @@ thread_jumps (void)
} }
} }
return retval;
}
/* Thread jumps over empty statements.
This code should _not_ thread over obviously equivalent conditions
as that requires nontrivial updates to the SSA graph.
As a precondition, we require that all basic blocks be reachable.
That is, there should be no opportunities left for
delete_unreachable_blocks. */
static bool
thread_jumps (void)
{
basic_block bb;
bool retval = false;
bool rerun;
FOR_EACH_BB (bb)
bb_ann (bb)->forwardable = tree_forwarder_block_p (bb);
do
{
rerun = false;
FOR_EACH_BB (bb)
{
/* Don't waste time on forwarders. */
if (bb_ann (bb)->forwardable)
continue;
if (thread_jumps_from_bb (bb))
{
retval = true;
/* If we succeeded in threading a jump at BB, update the /* If we succeeded in threading a jump at BB, update the
forwardable mark as BB may have become a new forwarder forwardable mark as BB may have become a new
block. This could happen if we have a useless "if" forwarder block. This could happen if we have a
statement whose two arms eventually merge without any useless "if" statement whose two arms eventually
intervening statements. */ merge without any intervening statements. */
if (this_jump_threaded && tree_forwarder_block_p (bb)) if (tree_forwarder_block_p (bb))
bb_ann (bb)->forwardable = rerun = true; bb_ann (bb)->forwardable = rerun = true;
} }
} }
}
while (rerun); while (rerun);
return retval; return retval;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment