From b4c1c7e3bdb764d242c29d530a0730dd864323a8 Mon Sep 17 00:00:00 2001 From: Zdenek Dvorak Date: Sun, 14 Jan 2007 21:07:42 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 7 +++++ gcc/cfgloop.h | 2 -- gcc/cfgloopmanip.c | 76 ++++++++++++++++++++++++--------------------- gcc/loop-unswitch.c | 5 --- 4 files changed, 47 insertions(+), 43 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 646e2928035..24d6dc65258 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2007-01-14 Zdenek Dvorak + + * 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. + 2007-01-14 Dorit Nuzman * param.h (MIN_VECT_LOOP_BOUND): New. diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index ec1149c8bb8..47bfa576103 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -242,8 +242,6 @@ extern void remove_bb_from_loops (basic_block); extern void cancel_loop_tree (struct loop *); extern void delete_loop (struct loop *); -extern int fix_loop_placement (struct loop *); - enum { CP_SIMPLE_PREHEADERS = 1 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 diff --git a/gcc/loop-unswitch.c b/gcc/loop-unswitch.c index b0e2aaa12be..05530adcfaf 100644 --- a/gcc/loop-unswitch.c +++ b/gcc/loop-unswitch.c @@ -458,11 +458,6 @@ unswitch_loop (struct loop *loop, basic_block unswitch_on, rtx cond, rtx cinsn) remove_path (true_edge); remove_path (false_edge); - /* One of created loops do not have to be subloop of the outer loop now, - so fix its placement in loop data structure. */ - fix_loop_placement (loop); - fix_loop_placement (nloop); - /* Preserve the simple loop preheaders. */ split_edge (loop_preheader_edge (loop)); split_edge (loop_preheader_edge (nloop));