summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/tree-cfg.c288
2 files changed, 152 insertions, 141 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 13d0ae467c8..d4e95c14179 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2004-10-19 Kazu Hirata <kazu@cs.umass.edu>
+ * tree-cfg.c (thread_jumps): Use a do-while loop instead of a
+ loop with goto.
+
+2004-10-19 Kazu Hirata <kazu@cs.umass.edu>
+
* expr.c (expand_assignment): Remove the last argument.
Change the return type to void.
* expr.h: Update the prototype of expand_assignment.
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 012ad706af7..0722df15ac3 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -3781,173 +3781,179 @@ thread_jumps (void)
FOR_EACH_BB (bb)
bb_ann (bb)->forwardable = tree_forwarder_block_p (bb);
- restart:
- rerun = false;
- FOR_EACH_BB (bb)
+ do
{
- edge_iterator ei;
- bool this_jump_threaded = 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
- forwardable. */
- for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
+ rerun = false;
+ FOR_EACH_BB (bb)
{
- int freq;
- gcov_type count;
+ edge_iterator ei;
+ bool this_jump_threaded = false;
- /* If the edge is abnormal or its destination is not
- forwardable, then there's nothing to do. */
- if ((e->flags & EDGE_ABNORMAL)
- || !bb_ann (e->dest)->forwardable)
- {
- ei_next (&ei);
- continue;
- }
+ /* Don't waste time on forwarders. */
+ if (bb_ann (bb)->forwardable)
+ continue;
- count = e->count;
- freq = EDGE_FREQUENCY (e);
-
- /* Now walk through as many forwarder blocks as possible to
- find the ultimate destination we want to thread our jump
- to. */
- last = EDGE_SUCC (e->dest, 0);
- bb_ann (e->dest)->forwardable = 0;
- for (dest = EDGE_SUCC (e->dest, 0)->dest;
- bb_ann (dest)->forwardable;
- last = EDGE_SUCC (dest, 0),
- dest = EDGE_SUCC (dest, 0)->dest)
- bb_ann (dest)->forwardable = 0;
-
- /* Reset the forwardable marks to 1. */
- for (tmp = e->dest;
- tmp != dest;
- tmp = EDGE_SUCC (tmp, 0)->dest)
- bb_ann (tmp)->forwardable = 1;
-
- if (dest == e->dest)
+ /* Examine each of our block's successors to see if it is
+ forwardable. */
+ for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
{
- ei_next (&ei);
- continue;
- }
+ int freq;
+ gcov_type count;
+
+ /* If the edge is abnormal or its destination is not
+ forwardable, then there's nothing to do. */
+ if ((e->flags & EDGE_ABNORMAL)
+ || !bb_ann (e->dest)->forwardable)
+ {
+ ei_next (&ei);
+ continue;
+ }
+
+ count = e->count;
+ freq = EDGE_FREQUENCY (e);
+
+ /* Now walk through as many forwarder blocks as possible to
+ find the ultimate destination we want to thread our jump
+ to. */
+ last = EDGE_SUCC (e->dest, 0);
+ bb_ann (e->dest)->forwardable = 0;
+ for (dest = EDGE_SUCC (e->dest, 0)->dest;
+ bb_ann (dest)->forwardable;
+ last = EDGE_SUCC (dest, 0),
+ dest = EDGE_SUCC (dest, 0)->dest)
+ bb_ann (dest)->forwardable = 0;
+
+ /* Reset the forwardable marks to 1. */
+ for (tmp = e->dest;
+ tmp != dest;
+ tmp = EDGE_SUCC (tmp, 0)->dest)
+ bb_ann (tmp)->forwardable = 1;
+
+ if (dest == e->dest)
+ {
+ ei_next (&ei);
+ continue;
+ }
- old = find_edge (bb, dest);
- if (old)
- {
- /* If there already is an edge, check whether the values
- in phi nodes differ. */
- if (!phi_alternatives_equal (dest, last, old))
+ old = find_edge (bb, dest);
+ if (old)
{
- /* The previous block is forwarder. Redirect our jump
- to that target instead since we know it has no PHI
- nodes that will need updating. */
- dest = last->src;
-
- /* That might mean that no forwarding at all is possible. */
- if (dest == e->dest)
+ /* If there already is an edge, check whether the values
+ in phi nodes differ. */
+ if (!phi_alternatives_equal (dest, last, old))
{
- ei_next (&ei);
- continue;
+ /* The previous block is forwarder. Redirect our jump
+ to that target instead since we know it has no PHI
+ nodes that will need updating. */
+ dest = last->src;
+
+ /* That might mean that no forwarding at all is
+ possible. */
+ if (dest == e->dest)
+ {
+ ei_next (&ei);
+ continue;
+ }
+
+ old = find_edge (bb, dest);
}
-
- old = find_edge (bb, dest);
}
- }
- /* Perform the redirection. */
- retval = this_jump_threaded = true;
- old_dest = e->dest;
- e = redirect_edge_and_branch (e, dest);
+ /* Perform the redirection. */
+ retval = this_jump_threaded = true;
+ old_dest = e->dest;
+ e = redirect_edge_and_branch (e, dest);
- /* Update the profile. */
- if (profile_status != PROFILE_ABSENT)
- for (curr = old_dest; curr != dest; curr = EDGE_SUCC (curr, 0)->dest)
- {
- curr->frequency -= freq;
- if (curr->frequency < 0)
- curr->frequency = 0;
- curr->count -= count;
- if (curr->count < 0)
- curr->count = 0;
- EDGE_SUCC (curr, 0)->count -= count;
- if (EDGE_SUCC (curr, 0)->count < 0)
- EDGE_SUCC (curr, 0)->count = 0;
- }
+ /* Update the profile. */
+ if (profile_status != PROFILE_ABSENT)
+ for (curr = old_dest;
+ curr != dest;
+ curr = EDGE_SUCC (curr, 0)->dest)
+ {
+ curr->frequency -= freq;
+ if (curr->frequency < 0)
+ curr->frequency = 0;
+ curr->count -= count;
+ if (curr->count < 0)
+ curr->count = 0;
+ EDGE_SUCC (curr, 0)->count -= count;
+ if (EDGE_SUCC (curr, 0)->count < 0)
+ EDGE_SUCC (curr, 0)->count = 0;
+ }
- if (!old)
- {
- /* Update PHI nodes. We know that the new argument should
- have the same value as the argument associated with LAST.
- Otherwise we would have changed our target block above. */
- for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
+ if (!old)
{
- arg = phi_arg_from_edge (phi, last);
- gcc_assert (arg >= 0);
- add_phi_arg (&phi, PHI_ARG_DEF (phi, arg), e);
+ /* Update PHI nodes. We know that the new argument
+ should have the same value as the argument
+ associated with LAST. Otherwise we would have
+ changed our target block above. */
+ for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
+ {
+ arg = phi_arg_from_edge (phi, last);
+ gcc_assert (arg >= 0);
+ add_phi_arg (&phi, PHI_ARG_DEF (phi, arg), e);
+ }
}
- }
-
- /* Remove the unreachable blocks (observe that if all blocks
- were reachable before, only those in the path we threaded
- over and did not have any predecessor outside of the path
- become unreachable). */
- for (; old_dest != dest; old_dest = tmp)
- {
- tmp = EDGE_SUCC (old_dest, 0)->dest;
-
- if (EDGE_COUNT (old_dest->preds) > 0)
- break;
-
- delete_basic_block (old_dest);
- }
-
- /* Update the dominators. */
- if (dom_info_available_p (CDI_DOMINATORS))
- {
- /* If the dominator of the destination was in the path, set its
- dominator to the start of the redirected edge. */
- if (get_immediate_dominator (CDI_DOMINATORS, old_dest) == NULL)
- set_immediate_dominator (CDI_DOMINATORS, old_dest, bb);
-
- /* Now proceed like if we forwarded just over one edge at a time.
- Algorithm for forwarding edge S --> A over edge A --> B then
- is
-
- if (idom (B) == A
- && !dominated_by (S, B))
- idom (B) = idom (A);
- recount_idom (A); */
+ /* Remove the unreachable blocks (observe that if all blocks
+ were reachable before, only those in the path we threaded
+ over and did not have any predecessor outside of the path
+ become unreachable). */
for (; old_dest != dest; old_dest = tmp)
{
tmp = EDGE_SUCC (old_dest, 0)->dest;
- if (get_immediate_dominator (CDI_DOMINATORS, tmp) == old_dest
- && !dominated_by_p (CDI_DOMINATORS, bb, tmp))
+ if (EDGE_COUNT (old_dest->preds) > 0)
+ break;
+
+ delete_basic_block (old_dest);
+ }
+
+ /* Update the dominators. */
+ if (dom_info_available_p (CDI_DOMINATORS))
+ {
+ /* If the dominator of the destination was in the
+ path, set its dominator to the start of the
+ redirected edge. */
+ if (get_immediate_dominator (CDI_DOMINATORS, old_dest) == NULL)
+ set_immediate_dominator (CDI_DOMINATORS, old_dest, bb);
+
+ /* Now proceed like if we forwarded just over one
+ edge at a time. Algorithm for forwarding edge
+ S --> A over edge A --> B then is
+
+ if (idom (B) == A
+ && !dominated_by (S, B))
+ idom (B) = idom (A);
+ recount_idom (A); */
+
+ for (; old_dest != dest; old_dest = tmp)
{
- dom = get_immediate_dominator (CDI_DOMINATORS, old_dest);
- set_immediate_dominator (CDI_DOMINATORS, tmp, dom);
- }
+ tmp = EDGE_SUCC (old_dest, 0)->dest;
+
+ if (get_immediate_dominator (CDI_DOMINATORS, tmp) == old_dest
+ && !dominated_by_p (CDI_DOMINATORS, bb, tmp))
+ {
+ dom = get_immediate_dominator (CDI_DOMINATORS, old_dest);
+ set_immediate_dominator (CDI_DOMINATORS, tmp, dom);
+ }
- dom = recount_dominator (CDI_DOMINATORS, old_dest);
- set_immediate_dominator (CDI_DOMINATORS, old_dest, dom);
+ dom = recount_dominator (CDI_DOMINATORS, old_dest);
+ set_immediate_dominator (CDI_DOMINATORS, old_dest, dom);
+ }
}
}
- }
- /* If we succeeded in threading a jump at BB, update the
- forwardable mark as BB may have become a new forwarder block.
- This could happen if we have a useless "if" statement whose
- two arms eventually merge without any intervening
- statements. */
- if (this_jump_threaded && tree_forwarder_block_p (bb))
- bb_ann (bb)->forwardable = rerun = true;
+ /* If we succeeded in threading a jump at BB, update the
+ forwardable mark as BB may have become a new forwarder
+ block. This could happen if we have a useless "if"
+ statement whose two arms eventually merge without any
+ intervening statements. */
+ if (this_jump_threaded && tree_forwarder_block_p (bb))
+ bb_ann (bb)->forwardable = rerun = true;
+ }
}
- if (rerun)
- goto restart;
+ while (rerun);
return retval;
}