summaryrefslogtreecommitdiff
path: root/gcc/cfghooks.c
diff options
context:
space:
mode:
authorZdenek Dvorak <dvorakz@suse.cz>2006-11-17 12:29:17 +0100
committerZdenek Dvorak <rakdver@gcc.gnu.org>2006-11-17 11:29:17 +0000
commit598ec7bdbe0e6e2f7c58961fd0f61e0898a3083e (patch)
tree194dc21664ec5a698ea4824b9350190e2710fce6 /gcc/cfghooks.c
parent31198773e456d1a8ecabdd576fa3a9d4412cbf07 (diff)
downloadgcc-598ec7bdbe0e6e2f7c58961fd0f61e0898a3083e.tar.gz
tree-vrp.c (execute_vrp): Do not update current_loops.
* tree-vrp.c (execute_vrp): Do not update current_loops. * loop-unswitch.c (unswitch_loop): Do not use loop_split_edge_with. * doc/loop.texi: Remove documentation for cancelled functions. * tree-ssa-loop-im.c (loop_commit_inserts): Removed. (move_computations, determine_lsm): Use bsi_commit_edge_inserts instead. * cfgloopmanip.c (remove_bbs): Do not update loops explicitly. (remove_path): Ensure that in delete_basic_blocks, the loops are still allocated. (add_loop): Work on valid loop structures. (loopify): Modify call of add_loop. (mfb_update_loops): Removed. (create_preheader): Do not update loops explicitly. (force_single_succ_latches, loop_version): Do not use loop_split_edge_with. (loop_split_edge_with): Removed. * tree-ssa-loop-manip.c (create_iv, determine_exit_conditions): Do not use bsi_insert_on_edge_immediate_loop. (split_loop_exit_edge, tree_unroll_loop): Do not use loop_split_edge_with. (bsi_insert_on_edge_immediate_loop): Removed. * tree-ssa-loop-ch.c (copy_loop_headers): Use current_loops. Do not use loop_split_edge_with. * cfghooks.c: Include cfgloop.h. (verify_flow_info): Verify that loop_father is filled iff current_loops are available. (redirect_edge_and_branch_force, split_block, delete_basic_block, split_edge, merge_blocks, make_forwarder_block, duplicate_block): Update cfg. * cfgloopanal.c (mark_irreducible_loops): Work if the function contains no loops. * modulo-sched.c (generate_prolog_epilog, canon_loop): Do not use loop_split_edge_with. (sms_schedule): Use current_loops. * tree-ssa-dom.c (tree_ssa_dominator_optimize): Use current_loops. * loop-init.c (loop_optimizer_init, loop_optimizer_finalize): Set current_loops. (rtl_loop_init, rtl_loop_done): Do not set current_loops. * tree-ssa-sink.c (execute_sink_code): Use current_loops. * ifcvt.c (if_convert): Ditto. * predict.c (predict_loops): Do not clear current_loops. (tree_estimate_probability): Use current_loops. (propagate_freq): Receive head of the region to propagate instead of loop. (estimate_loops_at_level): Do not use shared to_visit bitmap. (estimate_loops): New function. Handle case current_loops == NULL. (estimate_bb_frequencies): Do not allocate tovisit. Use estimate_loops. * tree-ssa-loop.c (current_loops): Removed. (tree_loop_optimizer_init): Do not return loops. (tree_ssa_loop_init, tree_ssa_loop_done): Do not set current_loops. * tree-vectorizer.c (slpeel_update_phi_nodes_for_guard1, slpeel_update_phi_nodes_for_guard2, slpeel_tree_peel_loop_to_edge): Do not update loops explicitly. * function.h (struct function): Add x_current_loops field. (current_loops): New macro. * tree-if-conv.c (combine_blocks): Do not update loops explicitly. * loop-unroll.c (split_edge_and_insert): New function. (unroll_loop_runtime_iterations, analyze_insns_in_loop): Do not use loop_split_edge_with. * loop-doloop.c (add_test, doloop_modify): Ditto. * tree-ssa-pre.c (init_pre, fini_pre): Do not set current_loops. * cfglayout.c (copy_bbs): Do not update loops explicitly. * lambda-code.c (perfect_nestify): Do not use loop_split_edge_with. * tree-vect-transform.c (vect_transform_loop): Do not update loops explicitly. * cfgloop.c (flow_loops_cfg_dump): Do not dump dfs_order and rc_order. (flow_loops_free): Do not free dfs_order and rc_order. (flow_loops_find): Do not set dfs_order and rc_order in loops structure. Do not call loops and flow info verification. (add_bb_to_loop, remove_bb_from_loops): Check whether the block already belongs to some loop. * cfgloop.h (struct loops): Remove struct cfg. (current_loops, loop_split_edge_with): Declaration removed. (loop_optimizer_init, loop_optimizer_finalize): Declaration changed. * tree-flow.h (loop_commit_inserts, bsi_insert_on_edge_immediate_loop): Declaration removed. * Makefile.in (cfghooks.o): Add CFGLOOP_H dependency. * basic-block.h (split_edge_and_insert): Declare. * tree-cfg.c (remove_bb): Do not update loops explicitly. From-SVN: r118931
Diffstat (limited to 'gcc/cfghooks.c')
-rw-r--r--gcc/cfghooks.c87
1 files changed, 86 insertions, 1 deletions
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index 4d89aea8f5c..0378b13ba80 100644
--- a/gcc/cfghooks.c
+++ b/gcc/cfghooks.c
@@ -29,6 +29,7 @@ Boston, MA 02110-1301, USA. */
#include "tree-flow.h"
#include "timevar.h"
#include "toplev.h"
+#include "cfgloop.h"
/* A pointer to one of the hooks containers. */
static struct cfg_hooks *cfg_hooks;
@@ -115,6 +116,18 @@ verify_flow_info (void)
edge e;
edge_iterator ei;
+ if (bb->loop_father != NULL && current_loops == NULL)
+ {
+ error ("verify_flow_info: Block %i has loop_father, but there are no loops",
+ bb->index);
+ err = 1;
+ }
+ if (bb->loop_father == NULL && current_loops != NULL)
+ {
+ error ("verify_flow_info: Block %i lacks loop_father", bb->index);
+ err = 1;
+ }
+
if (bb->count < 0)
{
error ("verify_flow_info: Wrong count of block %i %i",
@@ -308,12 +321,19 @@ basic_block
redirect_edge_and_branch_force (edge e, basic_block dest)
{
basic_block ret;
+ 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);
ret = cfg_hooks->redirect_edge_and_branch_force (e, dest);
+ if (current_loops != NULL && ret != NULL)
+ {
+ loop = find_common_loop (single_pred (ret)->loop_father,
+ single_succ (ret)->loop_father);
+ add_bb_to_loop (ret, loop);
+ }
return ret;
}
@@ -344,6 +364,9 @@ split_block (basic_block bb, void *i)
set_immediate_dominator (CDI_DOMINATORS, new_bb, bb);
}
+ if (current_loops != NULL)
+ add_bb_to_loop (new_bb, bb->loop_father);
+
return make_single_succ_edge (bb, new_bb, EDGE_FALLTHRU);
}
@@ -381,6 +404,22 @@ delete_basic_block (basic_block bb)
cfg_hooks->delete_basic_block (bb);
+ if (current_loops != NULL)
+ {
+ struct loop *loop = bb->loop_father;
+
+ /* If we remove the header or the latch of a loop, mark the loop for
+ removal by setting its header and latch to NULL. */
+ if (loop->latch == bb
+ || loop->header == bb)
+ {
+ loop->header = NULL;
+ loop->latch = NULL;
+ }
+
+ remove_bb_from_loops (bb);
+ }
+
/* Remove the edges into and out of this block. Note that there may
indeed be edges in, if we are removing an unreachable loop. */
while (EDGE_COUNT (bb->preds) != 0)
@@ -407,6 +446,8 @@ split_edge (edge e)
int freq = EDGE_FREQUENCY (e);
edge f;
bool irr = (e->flags & EDGE_IRREDUCIBLE_LOOP) != 0;
+ struct loop *loop;
+ basic_block src = e->src, dest = e->dest;
if (!cfg_hooks->split_edge)
internal_error ("%s does not support split_edge", cfg_hooks->name);
@@ -455,7 +496,16 @@ split_edge (edge e)
if (!f)
set_immediate_dominator (CDI_DOMINATORS, single_succ (ret), ret);
}
- };
+ }
+
+ if (current_loops != NULL)
+ {
+ loop = find_common_loop (src->loop_father, dest->loop_father);
+ add_bb_to_loop (ret, loop);
+
+ if (loop->latch == src)
+ loop->latch = ret;
+ }
return ret;
}
@@ -534,6 +584,9 @@ merge_blocks (basic_block a, basic_block b)
if (!cfg_hooks->merge_blocks)
internal_error ("%s does not support merge_blocks", cfg_hooks->name);
+ if (current_loops != NULL)
+ remove_bb_from_loops (b);
+
cfg_hooks->merge_blocks (a, b);
/* Normally there should only be one successor of A and that is B, but
@@ -575,6 +628,7 @@ make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge),
edge e, fallthru;
edge_iterator ei;
basic_block dummy, jump;
+ struct loop *loop, *ploop, *cloop;
if (!cfg_hooks->make_forwarder_block)
internal_error ("%s does not support make_forwarder_block",
@@ -617,6 +671,33 @@ make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge),
iterate_fix_dominators (CDI_DOMINATORS, doms_to_fix, 2);
}
+ if (current_loops != NULL)
+ {
+ /* If we do not split a loop header, then both blocks belong to the
+ same loop. In case we split loop header and do not redirect the
+ latch edge to DUMMY, then DUMMY belongs to the outer loop, and
+ BB becomes the new header. */
+ loop = dummy->loop_father;
+ if (loop->header == dummy
+ && find_edge (loop->latch, dummy) == NULL)
+ {
+ remove_bb_from_loops (dummy);
+ loop->header = bb;
+
+ cloop = loop;
+ FOR_EACH_EDGE (e, ei, dummy->preds)
+ {
+ cloop = find_common_loop (cloop, e->src->loop_father);
+ }
+ add_bb_to_loop (dummy, cloop);
+ }
+
+ /* In case we split loop latch, update it. */
+ for (ploop = loop; ploop; ploop = ploop->outer)
+ if (ploop->latch == dummy)
+ ploop->latch = bb;
+ }
+
cfg_hooks->make_forwarder_block (fallthru);
return fallthru;
@@ -768,6 +849,10 @@ duplicate_block (basic_block bb, edge e, basic_block after)
set_bb_original (new_bb, bb);
set_bb_copy (bb, new_bb);
+ /* Add the new block to the prescribed loop. */
+ if (current_loops != NULL)
+ add_bb_to_loop (new_bb, bb->loop_father->copy);
+
return new_bb;
}