diff options
author | Zdenek Dvorak <dvorakz@suse.cz> | 2007-01-14 21:07:42 +0100 |
---|---|---|
committer | Zdenek Dvorak <rakdver@gcc.gnu.org> | 2007-01-14 20:07:42 +0000 |
commit | b4c1c7e3bdb764d242c29d530a0730dd864323a8 (patch) | |
tree | 18a27a7ce6c6eb581f08c16c0df3ef47d68304a3 /gcc/cfgloopmanip.c | |
parent | cd9ae11c1a02a8a99da7f7e3b574e66d5428a99f (diff) | |
download | gcc-b4c1c7e3bdb764d242c29d530a0730dd864323a8.tar.gz |
loop-unswitch.c (unswitch_loop): Do not call fix_loop_placement.
* loop-unswitch.c (unswitch_loop): Do not call fix_loop_placement.
* cfgloopmanip.c (fix_loop_placement): Made static. Use
get_loop_exit_edges. Changed return type to bool.
* cfgloop.h (fix_loop_placement): Declaration removed.
From-SVN: r120782
Diffstat (limited to 'gcc/cfgloopmanip.c')
-rw-r--r-- | gcc/cfgloopmanip.c | 76 |
1 files changed, 40 insertions, 36 deletions
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c index 222bcb3623c..74f7b0781a7 100644 --- a/gcc/cfgloopmanip.c +++ b/gcc/cfgloopmanip.c @@ -120,6 +120,46 @@ fix_bb_placement (basic_block bb) return true; } +/* Fix placement of LOOP inside loop tree, i.e. find the innermost superloop + of LOOP to that leads at least one exit edge of LOOP, and set it + as the immediate superloop of LOOP. Return true if the immediate superloop + of LOOP changed. */ + +static bool +fix_loop_placement (struct loop *loop) +{ + unsigned i; + edge e; + VEC (edge, heap) *exits = get_loop_exit_edges (loop); + struct loop *father = current_loops->tree_root, *act; + bool ret = false; + + for (i = 0; VEC_iterate (edge, exits, i, e); i++) + { + act = find_common_loop (loop, e->dest->loop_father); + if (flow_loop_nested_p (father, act)) + father = act; + } + + if (father != loop->outer) + { + for (act = loop->outer; act != father; act = act->outer) + act->num_nodes -= loop->num_nodes; + flow_loop_tree_node_remove (loop); + flow_loop_tree_node_add (father, loop); + + /* The exit edges of LOOP no longer exits its original immediate + superloops; remove them from the appropriate exit lists. */ + for (i = 0; VEC_iterate (edge, exits, i, e); i++) + rescan_loop_exit (e, false, false); + + ret = true; + } + + VEC_free (edge, heap, exits); + return ret; +} + /* Fix placements of basic blocks inside loop hierarchy stored in loops; i.e. enforce condition condition stated in description of fix_bb_placement. We start from basic block FROM that had some of its successors removed, so that @@ -563,42 +603,6 @@ unloop (struct loop *loop, bool *irred_invalidated) fix_bb_placements (latch, &dummy); } -/* Fix placement of LOOP inside loop tree, i.e. find the innermost superloop - FATHER of LOOP such that all of the edges coming out of LOOP belong to - FATHER, and set it as outer loop of LOOP. Return true if placement of - LOOP changed. */ - -int -fix_loop_placement (struct loop *loop) -{ - basic_block *body; - unsigned i; - edge e; - edge_iterator ei; - struct loop *father = loop->pred[0], *act; - - body = get_loop_body (loop); - for (i = 0; i < loop->num_nodes; i++) - FOR_EACH_EDGE (e, ei, body[i]->succs) - if (!flow_bb_inside_loop_p (loop, e->dest)) - { - act = find_common_loop (loop, e->dest->loop_father); - if (flow_loop_nested_p (father, act)) - father = act; - } - free (body); - - if (father != loop->outer) - { - for (act = loop->outer; act != father; act = act->outer) - act->num_nodes -= loop->num_nodes; - flow_loop_tree_node_remove (loop); - flow_loop_tree_node_add (father, loop); - return 1; - } - return 0; -} - /* Fix placement of superloops of LOOP inside loop tree, i.e. ensure that condition stated in description of fix_loop_placement holds for them. It is used in case when we removed some edges coming out of LOOP, which |