* [patch] tree-cfg.c: Convert a goto to a do-while loop.
@ 2004-10-19 17:23 Kazu Hirata
0 siblings, 0 replies; only message in thread
From: Kazu Hirata @ 2004-10-19 17:23 UTC (permalink / raw)
To: gcc-patches
Hi,
Attached is a patch convert a loop with goto to a do-while loo.
There is no functional change.
Bootstrapped on i686-pc-linux-gnu. Committed as preapproved by Jeff
Law.
Kazu Hirata
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.
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-cfg.c,v
retrieving revision 2.82
diff -c -p -r2.82 tree-cfg.c
*** tree-cfg.c 18 Oct 2004 21:16:53 -0000 2.82
--- tree-cfg.c 19 Oct 2004 13:20:59 -0000
*************** thread_jumps (void)
*** 3781,3953 ****
FOR_EACH_BB (bb)
bb_ann (bb)->forwardable = tree_forwarder_block_p (bb);
! restart:
! rerun = false;
! FOR_EACH_BB (bb)
{
! 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)); )
{
! 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))
{
! /* 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);
}
- }
! /* 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;
! }
! 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))
{
! 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); */
! 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))
{
! 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);
}
}
- }
! /* 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;
return retval;
}
--- 3781,3959 ----
FOR_EACH_BB (bb)
bb_ann (bb)->forwardable = tree_forwarder_block_p (bb);
! do
{
! rerun = false;
! FOR_EACH_BB (bb)
{
! 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)); )
{
! 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))
{
! /* 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);
! }
}
! /* 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;
! }
! 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))
! {
! 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); */
! 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))
! {
! 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);
! }
}
}
! /* 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;
! }
}
! while (rerun);
return retval;
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2004-10-19 15:39 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-19 17:23 [patch] tree-cfg.c: Convert a goto to a do-while loop Kazu Hirata
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).