diff options
author | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-01-12 17:57:40 +0000 |
---|---|---|
committer | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-01-12 17:57:40 +0000 |
commit | dce58e66ae4584a9832bccb103a155df58be9806 (patch) | |
tree | 6cc0ea65afc6e5ab5c27890dd53712843ef3bc17 /gcc/cfghooks.c | |
parent | 2656a84c1153d7b11ea2524305a8f5b9f66b17a6 (diff) | |
download | gcc-dce58e66ae4584a9832bccb103a155df58be9806.tar.gz |
* doc/loop.texi: Document recording of loop exits.
* cfgloopmanip.c (loopify, duplicate_loop): Use alloc_loop.
(update_single_exits_after_duplication,
update_single_exit_for_duplicated_loop,
update_single_exit_for_duplicated_loops): Removed.
(duplicate_loop_to_header_edge): Do not call
update_single_exits_after_duplication and
update_single_exit_for_duplicated_loops.
(loop_version): Do not update single_exit information.
(fix_loop_structure): Use record_loop_exits instead of
mark_single_exit_loops.
* tree-ssa-loop-manip.c (tree_transform_and_unroll_loop): Update
the lists of loop exits.
* cfghooks.c (redirect_edge_and_branch, redirect_edge_and_branch_force,
split_edge, merge_blocks): Update the lists of loop exits.
* modulo-sched.c (sms_schedule): Pass LOOPS_HAVE_RECORDED_EXITS to
loop_optimizer_init.
* loop-init.c (loop_optimizer_init): Call record_loop_exits instead
of mark_single_exit_loops.
(loop_optimizer_finalize): Call release_recorded_exits.
* tree-ssa-loop.c (tree_loop_optimizer_init): Pass
LOOPS_HAVE_RECORDED_EXITS to loop_optimizer_init.
* tree-vectorizer.c (slpeel_tree_duplicate_loop_to_edge_cfg): Do not
update single exit information.
* lambda-code.c (perfect_nestify): Ditto.
* cfgloop.c (flow_loop_free): Destroy the list of exits of the loop.
(mark_single_exit_loops): Removed.
(alloc_loop, loop_exit_hash, loop_exit_eq, loop_exit_free,
get_exit_descriptions, rescan_loop_exit, record_loop_exits,
dump_recorded_exit, dump_recorded_exits, release_recorded_exits): New
functions.
(get_loop_exit_edges, single_exit): Use recorded exit lists.
(add_bb_to_loop, remove_bb_from_loops): Update the lists of loop exits.
(verify_loop_structure): Verify consistency of the exit lists.
(flow_loops_find): Use alloc_loop. Initialize exits hash.
(set_single_exit): Removed.
* cfgloop.h (struct loop_exit): New function.
(struct loop): single_exit_ field replaced by exits field.
(LOOPS_HAVE_MARKED_SINGLE_EXITS): Replaced by LOOPS_HAVE_RECORDED_EXITS.
(struct loops): Added exits hash.
(mark_single_exit_loops, set_single_exit): Declaration removed.
(release_recorded_exits, record_loop_exits, rescan_loop_exit): Declare.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120728 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfghooks.c')
-rw-r--r-- | gcc/cfghooks.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c index 50aca9f1b69..d6a981d1db8 100644 --- a/gcc/cfghooks.c +++ b/gcc/cfghooks.c @@ -310,6 +310,11 @@ redirect_edge_and_branch (edge e, basic_block dest) ret = cfg_hooks->redirect_edge_and_branch (e, dest); + /* If RET != E, then the edge E was removed since RET already lead to the + same destination. */ + if (ret != NULL && current_loops != NULL) + rescan_loop_exit (e, false, ret != e); + return ret; } @@ -320,19 +325,27 @@ redirect_edge_and_branch (edge e, basic_block dest) basic_block redirect_edge_and_branch_force (edge e, basic_block dest) { - basic_block ret; + basic_block ret, src = e->src; struct loop *loop; if (!cfg_hooks->redirect_edge_and_branch_force) internal_error ("%s does not support redirect_edge_and_branch_force", cfg_hooks->name); + if (current_loops != NULL) + rescan_loop_exit (e, false, true); + ret = cfg_hooks->redirect_edge_and_branch_force (e, dest); - if (current_loops != NULL && ret != NULL) + if (current_loops != NULL) { - loop = find_common_loop (single_pred (ret)->loop_father, - single_succ (ret)->loop_father); - add_bb_to_loop (ret, loop); + if (ret != NULL) + { + loop = find_common_loop (single_pred (ret)->loop_father, + single_succ (ret)->loop_father); + add_bb_to_loop (ret, loop); + } + else if (find_edge (src, dest) == e) + rescan_loop_exit (e, true, false); } return ret; @@ -452,6 +465,9 @@ split_edge (edge e) if (!cfg_hooks->split_edge) internal_error ("%s does not support split_edge", cfg_hooks->name); + if (current_loops != NULL) + rescan_loop_exit (e, false, true); + ret = cfg_hooks->split_edge (e); ret->count = count; ret->frequency = freq; @@ -595,11 +611,19 @@ merge_blocks (basic_block a, basic_block b) whole lot of them and hope the caller knows what they're doing. */ while (EDGE_COUNT (a->succs) != 0) - remove_edge (EDGE_SUCC (a, 0)); + { + if (current_loops != NULL) + rescan_loop_exit (EDGE_SUCC (a, 0), false, true); + remove_edge (EDGE_SUCC (a, 0)); + } /* Adjust the edges out of B for the new owner. */ FOR_EACH_EDGE (e, ei, b->succs) - e->src = a; + { + e->src = a; + if (current_loops != NULL) + rescan_loop_exit (e, true, false); + } a->succs = b->succs; a->flags |= b->flags; |