aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog83
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/basic-block.h1
-rw-r--r--gcc/cfghooks.c87
-rw-r--r--gcc/cfglayout.c4
-rw-r--r--gcc/cfgloop.c43
-rw-r--r--gcc/cfgloop.h24
-rw-r--r--gcc/cfgloopanal.c63
-rw-r--r--gcc/cfgloopmanip.c107
-rw-r--r--gcc/doc/loop.texi12
-rw-r--r--gcc/function.h4
-rw-r--r--gcc/ifcvt.c11
-rw-r--r--gcc/lambda-code.c2
-rw-r--r--gcc/loop-doloop.c7
-rw-r--r--gcc/loop-init.c72
-rw-r--r--gcc/loop-unroll.c35
-rw-r--r--gcc/loop-unswitch.c4
-rw-r--r--gcc/modulo-sched.c37
-rw-r--r--gcc/predict.c67
-rw-r--r--gcc/tree-cfg.c15
-rw-r--r--gcc/tree-flow.h2
-rw-r--r--gcc/tree-if-conv.c17
-rw-r--r--gcc/tree-ssa-dom.c10
-rw-r--r--gcc/tree-ssa-loop-ch.c21
-rw-r--r--gcc/tree-ssa-loop-im.c23
-rw-r--r--gcc/tree-ssa-loop-manip.c42
-rw-r--r--gcc/tree-ssa-loop.c24
-rw-r--r--gcc/tree-ssa-pre.c7
-rw-r--r--gcc/tree-ssa-sink.c4
-rw-r--r--gcc/tree-vect-transform.c4
-rw-r--r--gcc/tree-vectorizer.c5
-rw-r--r--gcc/tree-vrp.c5
32 files changed, 425 insertions, 419 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ab9b552..12c61b7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,88 @@
2006-11-17 Zdenek Dvorak <dvorakz@suse.cz>
+ * 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.
+
+2006-11-17 Zdenek Dvorak <dvorakz@suse.cz>
+
PR tree-optimization/29801
* tree-ssa-ccp.c (get_symbol_constant_value): New function.
(get_default_value): Use get_symbol_constant_value.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index fda394c1..8136290 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2427,7 +2427,7 @@ cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) \
$(REGS_H) hard-reg-set.h output.h toplev.h $(FUNCTION_H) except.h $(GGC_H) \
$(TM_P_H) $(TIMEVAR_H) $(OBSTACK_H) $(TREE_H) alloc-pool.h $(HASHTAB_H)
cfghooks.o: cfghooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- $(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TIMEVAR_H) toplev.h
+ $(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TIMEVAR_H) toplev.h $(CFGLOOP_H)
cfgexpand.o : cfgexpand.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) \
coretypes.h $(TREE_DUMP_H) except.h langhooks.h tree-pass.h $(RTL_H) \
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index aa41486..6b6820c 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -486,6 +486,7 @@ extern void update_bb_for_insn (basic_block);
extern void free_basic_block_vars (void);
extern void insert_insn_on_edge (rtx, edge);
+basic_block split_edge_and_insert (edge, rtx);
extern void commit_edge_insertions (void);
extern void commit_edge_insertions_watch_calls (void);
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index 4d89aea..0378b13 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;
}
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index 6bd63c2..cf76cdb 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -1230,9 +1230,7 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
new_bb = new_bbs[i] = duplicate_block (bb, NULL, after);
after = new_bb;
bb->flags |= BB_DUPLICATED;
- /* Add to loop. */
- add_bb_to_loop (new_bb, bb->loop_father->copy);
- /* Possibly set header. */
+ /* Possibly set loop header. */
if (bb->loop_father->header == bb && bb->loop_father != base)
new_bb->loop_father->header = new_bb;
/* Or latch. */
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index 9afd48b..25549db 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -52,7 +52,6 @@ static bool glb_enum_p (basic_block, void *);
static void
flow_loops_cfg_dump (const struct loops *loops, FILE *file)
{
- int i;
basic_block bb;
if (! loops->num || ! file)
@@ -68,26 +67,6 @@ flow_loops_cfg_dump (const struct loops *loops, FILE *file)
fprintf (file, "%d ", succ->dest->index);
fprintf (file, "}\n");
}
-
- /* Dump the DFS node order. */
- if (loops->cfg.dfs_order)
- {
- fputs (";; DFS order: ", file);
- for (i = NUM_FIXED_BLOCKS; i < n_basic_blocks; i++)
- fprintf (file, "%d ", loops->cfg.dfs_order[i]);
-
- fputs ("\n", file);
- }
-
- /* Dump the reverse completion node order. */
- if (loops->cfg.rc_order)
- {
- fputs (";; RC order: ", file);
- for (i = NUM_FIXED_BLOCKS; i < n_basic_blocks; i++)
- fprintf (file, "%d ", loops->cfg.rc_order[i]);
-
- fputs ("\n", file);
- }
}
/* Return nonzero if the nodes of LOOP are a subset of OUTER. */
@@ -208,12 +187,6 @@ flow_loops_free (struct loops *loops)
free (loops->parray);
loops->parray = NULL;
-
- if (loops->cfg.dfs_order)
- free (loops->cfg.dfs_order);
- if (loops->cfg.rc_order)
- free (loops->cfg.rc_order);
-
}
}
@@ -697,10 +670,6 @@ flow_loops_find (struct loops *loops)
rc_order = XNEWVEC (int, n_basic_blocks);
pre_and_rev_post_order_compute (dfs_order, rc_order, false);
- /* Save CFG derived information to avoid recomputing it. */
- loops->cfg.dfs_order = dfs_order;
- loops->cfg.rc_order = rc_order;
-
num_loops = 1;
for (b = 0; b < n_basic_blocks - NUM_FIXED_BLOCKS; b++)
@@ -744,16 +713,14 @@ flow_loops_find (struct loops *loops)
loops->num = num_loops;
initialize_loops_parallel_p (loops);
+
+ free (dfs_order);
+ free (rc_order);
}
sbitmap_free (headers);
loops->state = 0;
-#ifdef ENABLE_CHECKING
- verify_flow_info ();
- verify_loop_structure (loops);
-#endif
-
return loops->num;
}
@@ -969,12 +936,13 @@ add_bb_to_loop (basic_block bb, struct loop *loop)
{
int i;
+ gcc_assert (bb->loop_father == NULL);
bb->loop_father = loop;
bb->loop_depth = loop->depth;
loop->num_nodes++;
for (i = 0; i < loop->depth; i++)
loop->pred[i]->num_nodes++;
- }
+}
/* Remove basic block BB from loops. */
void
@@ -983,6 +951,7 @@ remove_bb_from_loops (basic_block bb)
int i;
struct loop *loop = bb->loop_father;
+ gcc_assert (loop != NULL);
loop->num_nodes--;
for (i = 0; i < loop->depth; i++)
loop->pred[i]->num_nodes--;
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 311c43e..17a1cf7 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -187,25 +187,10 @@ struct loops
/* Pointer to root of loop hierarchy tree. */
struct loop *tree_root;
- /* Information derived from the CFG. */
- struct cfg
- {
- /* The ordering of the basic blocks in a depth first search. */
- int *dfs_order;
-
- /* The reverse completion ordering of the basic blocks found in a
- depth first search. */
- int *rc_order;
- } cfg;
-
/* Headers shared by multiple loops that should be merged. */
sbitmap shared_headers;
};
-/* The loop tree currently optimized. */
-
-extern struct loops *current_loops;
-
/* Loop recognition. */
extern int flow_loops_find (struct loops *);
extern void flow_loops_free (struct loops *);
@@ -248,7 +233,6 @@ extern void remove_bb_from_loops (basic_block);
extern void cancel_loop_tree (struct loops *, struct loop *);
-extern basic_block loop_split_edge_with (edge, rtx);
extern int fix_loop_placement (struct loop *);
enum
@@ -410,8 +394,8 @@ extern unsigned global_cost_for_size (unsigned, unsigned, unsigned);
extern void init_set_costs (void);
/* Loop optimizer initialization. */
-extern struct loops *loop_optimizer_init (unsigned);
-extern void loop_optimizer_finalize (struct loops *);
+extern void loop_optimizer_init (unsigned);
+extern void loop_optimizer_finalize (void);
/* Optimization passes. */
extern void unswitch_loops (struct loops *);
@@ -419,8 +403,8 @@ extern void unswitch_loops (struct loops *);
enum
{
UAP_PEEL = 1, /* Enables loop peeling. */
- UAP_UNROLL = 2, /* Enables peeling of loops if it seems profitable. */
- UAP_UNROLL_ALL = 4 /* Enables peeling of all loops. */
+ UAP_UNROLL = 2, /* Enables unrolling of loops if it seems profitable. */
+ UAP_UNROLL_ALL = 4 /* Enables unrolling of all loops. */
};
extern void unroll_and_peel_loops (struct loops *, int);
diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
index da54583..9aa75e4 100644
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -273,8 +273,9 @@ mark_irreducible_loops (struct loops *loops)
edge_iterator ei;
int i, src, dest;
struct graph *g;
- int *queue1 = XNEWVEC (int, last_basic_block + loops->num);
- int *queue2 = XNEWVEC (int, last_basic_block + loops->num);
+ int num = loops ? loops->num : 1;
+ int *queue1 = XNEWVEC (int, last_basic_block + num);
+ int *queue2 = XNEWVEC (int, last_basic_block + num);
int nq, depth;
struct loop *cloop;
@@ -287,7 +288,7 @@ mark_irreducible_loops (struct loops *loops)
}
/* Create the edge lists. */
- g = new_graph (last_basic_block + loops->num);
+ g = new_graph (last_basic_block + num);
FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
FOR_EACH_EDGE (e, ei, act->succs)
@@ -296,35 +297,38 @@ mark_irreducible_loops (struct loops *loops)
if (e->dest == EXIT_BLOCK_PTR)
continue;
- /* And latch edges. */
- if (e->dest->loop_father->header == e->dest
- && e->dest->loop_father->latch == act)
- continue;
+ src = BB_REPR (act);
+ dest = BB_REPR (e->dest);
- /* Edges inside a single loop should be left where they are. Edges
- to subloop headers should lead to representative of the subloop,
- but from the same place.
+ if (loops)
+ {
+ /* Ignore latch edges. */
+ if (e->dest->loop_father->header == e->dest
+ && e->dest->loop_father->latch == act)
+ continue;
- Edges exiting loops should lead from representative
- of the son of nearest common ancestor of the loops in that
- act lays. */
+ /* Edges inside a single loop should be left where they are. Edges
+ to subloop headers should lead to representative of the subloop,
+ but from the same place.
- src = BB_REPR (act);
- dest = BB_REPR (e->dest);
+ Edges exiting loops should lead from representative
+ of the son of nearest common ancestor of the loops in that
+ act lays. */
- if (e->dest->loop_father->header == e->dest)
- dest = LOOP_REPR (e->dest->loop_father);
+ if (e->dest->loop_father->header == e->dest)
+ dest = LOOP_REPR (e->dest->loop_father);
- if (!flow_bb_inside_loop_p (act->loop_father, e->dest))
- {
- depth = find_common_loop (act->loop_father,
- e->dest->loop_father)->depth + 1;
- if (depth == act->loop_father->depth)
- cloop = act->loop_father;
- else
- cloop = act->loop_father->pred[depth];
-
- src = LOOP_REPR (cloop);
+ if (!flow_bb_inside_loop_p (act->loop_father, e->dest))
+ {
+ depth = find_common_loop (act->loop_father,
+ e->dest->loop_father)->depth + 1;
+ if (depth == act->loop_father->depth)
+ cloop = act->loop_father;
+ else
+ cloop = act->loop_father->pred[depth];
+
+ src = LOOP_REPR (cloop);
+ }
}
add_edge (g, src, dest, e);
@@ -339,7 +343,7 @@ mark_irreducible_loops (struct loops *loops)
{
queue1[nq++] = BB_REPR (act);
}
- for (i = 1; i < (int) loops->num; i++)
+ for (i = 1; i < num; i++)
if (loops->parray[i])
queue1[nq++] = LOOP_REPR (loops->parray[i]);
dfs (g, queue1, nq, queue2, false);
@@ -354,7 +358,8 @@ mark_irreducible_loops (struct loops *loops)
free (queue1);
free (queue2);
- loops->state |= LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS;
+ if (loops)
+ loops->state |= LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS;
}
/* Counts number of insns inside LOOP. */
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 8c5a0f1..edb3697 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -40,7 +40,6 @@ static void remove_bbs (basic_block *, int);
static bool rpe_enum_p (basic_block, void *);
static int find_path (edge, basic_block **);
static bool alp_enum_p (basic_block, void *);
-static void add_loop (struct loops *, struct loop *);
static void fix_loop_placements (struct loops *, struct loop *, bool *);
static bool fix_bb_placement (struct loops *, basic_block);
static void fix_bb_placements (struct loops *, basic_block, bool *);
@@ -58,18 +57,15 @@ rpe_enum_p (basic_block bb, void *data)
return dominated_by_p (CDI_DOMINATORS, bb, data);
}
-/* Remove basic blocks BBS from loop structure and dominance info,
- and delete them afterwards. */
+/* Remove basic blocks BBS. NBBS is the number of the basic blocks. */
+
static void
remove_bbs (basic_block *bbs, int nbbs)
{
int i;
for (i = 0; i < nbbs; i++)
- {
- remove_bb_from_loops (bbs[i]);
- delete_basic_block (bbs[i]);
- }
+ delete_basic_block (bbs[i]);
}
/* Find path -- i.e. the basic blocks dominated by edge E and put them
@@ -247,9 +243,10 @@ remove_path (struct loops *loops, edge e)
{
edge ae;
basic_block *rem_bbs, *bord_bbs, *dom_bbs, from, bb;
- int i, nrem, n_bord_bbs, n_dom_bbs;
+ int i, nrem, n_bord_bbs, n_dom_bbs, nreml;
sbitmap seen;
bool deleted, irred_invalidated = false;
+ struct loop **deleted_loop;
if (!loop_delete_branch_edge (e, 0))
return false;
@@ -267,7 +264,7 @@ remove_path (struct loops *loops, edge e)
fix -- when e->dest has exactly one predecessor, this corresponds
to blocks dominated by e->dest, if not, split the edge. */
if (!single_pred_p (e->dest))
- e = single_pred_edge (loop_split_edge_with (e, NULL_RTX));
+ e = single_pred_edge (split_edge (e));
/* It may happen that by removing path we remove one or more loops
we belong to. In this case first unloop the loops, then proceed
@@ -311,13 +308,19 @@ remove_path (struct loops *loops, edge e)
dom_bbs = XCNEWVEC (basic_block, n_basic_blocks);
/* Cancel loops contained in the path. */
+ deleted_loop = XNEWVEC (struct loop *, nrem);
+ nreml = 0;
for (i = 0; i < nrem; i++)
if (rem_bbs[i]->loop_father->header == rem_bbs[i])
- cancel_loop_tree (loops, rem_bbs[i]->loop_father);
+ deleted_loop[nreml++] = rem_bbs[i]->loop_father;
remove_bbs (rem_bbs, nrem);
free (rem_bbs);
+ for (i = 0; i < nreml; i++)
+ cancel_loop_tree (loops, deleted_loop[i]);
+ free (deleted_loop);
+
/* Find blocks whose dominators may be affected. */
n_dom_bbs = 0;
sbitmap_zero (seen);
@@ -364,15 +367,18 @@ alp_enum_p (basic_block bb, void *alp_header)
}
/* Given LOOP structure with filled header and latch, find the body of the
- corresponding loop and add it to LOOPS tree. */
+ corresponding loop and add it to LOOPS tree. Insert the LOOP as a son of
+ outer. */
+
static void
-add_loop (struct loops *loops, struct loop *loop)
+add_loop (struct loops *loops, struct loop *loop, struct loop *outer)
{
basic_block *bbs;
int i, n;
/* Add it to loop structure. */
place_new_loop (loops, loop);
+ flow_loop_tree_node_add (outer, loop);
loop->level = 1;
/* Find its nodes. */
@@ -381,7 +387,11 @@ add_loop (struct loops *loops, struct loop *loop)
bbs, n_basic_blocks, loop->header);
for (i = 0; i < n; i++)
- add_bb_to_loop (bbs[i], loop);
+ {
+ remove_bb_from_loops (bbs[i]);
+ add_bb_to_loop (bbs[i], loop);
+ }
+ remove_bb_from_loops (loop->header);
add_bb_to_loop (loop->header, loop);
free (bbs);
@@ -453,10 +463,11 @@ loopify (struct loops *loops, edge latch_edge, edge header_edge,
set_immediate_dominator (CDI_DOMINATORS, succ_bb, switch_bb);
/* Compute new loop. */
- add_loop (loops, loop);
- flow_loop_tree_node_add (outer, loop);
+ add_loop (loops, loop, outer);
/* Add switch_bb to appropriate loop. */
+ if (switch_bb->loop_father)
+ remove_bb_from_loops (switch_bb);
add_bb_to_loop (switch_bb, outer);
/* Fix frequencies. */
@@ -1111,21 +1122,6 @@ mfb_keep_just (edge e)
return e != mfb_kj_edge;
}
-/* A callback for make_forwarder block, to update data structures for a basic
- block JUMP created by redirecting an edge (only the latch edge is being
- redirected). */
-
-static void
-mfb_update_loops (basic_block jump)
-{
- struct loop *loop = single_succ (jump)->loop_father;
-
- if (dom_computed[CDI_DOMINATORS])
- set_immediate_dominator (CDI_DOMINATORS, jump, single_pred (jump));
- add_bb_to_loop (jump, loop);
- loop->latch = jump;
-}
-
/* Creates a pre-header for a LOOP. Returns newly created block. Unless
CP_SIMPLE_PREHEADERS is set in FLAGS, we only force LOOP to have single
entry; otherwise we also force preheader block to have only one successor.
@@ -1136,15 +1132,12 @@ create_preheader (struct loop *loop, int flags)
{
edge e, fallthru;
basic_block dummy;
- struct loop *cloop, *ploop;
int nentry = 0;
bool irred = false;
bool latch_edge_was_fallthru;
edge one_succ_pred = 0;
edge_iterator ei;
- cloop = loop->outer;
-
FOR_EACH_EDGE (e, ei, loop->header->preds)
{
if (e->src == loop->latch)
@@ -1168,17 +1161,10 @@ create_preheader (struct loop *loop, int flags)
mfb_kj_edge = loop_latch_edge (loop);
latch_edge_was_fallthru = (mfb_kj_edge->flags & EDGE_FALLTHRU) != 0;
- fallthru = make_forwarder_block (loop->header, mfb_keep_just,
- mfb_update_loops);
+ fallthru = make_forwarder_block (loop->header, mfb_keep_just, NULL);
dummy = fallthru->src;
loop->header = fallthru->dest;
- /* The header could be a latch of some superloop(s); due to design of
- split_block, it would now move to fallthru->dest. */
- for (ploop = loop; ploop; ploop = ploop->outer)
- if (ploop->latch == dummy)
- ploop->latch = fallthru->dest;
-
/* Try to be clever in placing the newly created preheader. The idea is to
avoid breaking any "fallthruness" relationship between blocks.
@@ -1197,9 +1183,6 @@ create_preheader (struct loop *loop, int flags)
move_block_after (dummy, e->src);
}
- loop->header->loop_father = loop;
- add_bb_to_loop (dummy, cloop);
-
if (irred)
{
dummy->flags |= BB_IRREDUCIBLE_LOOP;
@@ -1241,41 +1224,11 @@ force_single_succ_latches (struct loops *loops)
e = find_edge (loop->latch, loop->header);
- loop_split_edge_with (e, NULL_RTX);
+ split_edge (e);
}
loops->state |= LOOPS_HAVE_SIMPLE_LATCHES;
}
-/* A quite stupid function to put INSNS on edge E. They are supposed to form
- just one basic block. Jumps in INSNS are not handled, so cfg do not have to
- be ok after this function. The created block is placed on correct place
- in LOOPS structure and its dominator is set. */
-basic_block
-loop_split_edge_with (edge e, rtx insns)
-{
- basic_block src, dest, new_bb;
- struct loop *loop_c;
-
- src = e->src;
- dest = e->dest;
-
- loop_c = find_common_loop (src->loop_father, dest->loop_father);
-
- /* Create basic block for it. */
-
- new_bb = split_edge (e);
- add_bb_to_loop (new_bb, loop_c);
- new_bb->flags |= (insns ? BB_SUPERBLOCK : 0);
-
- if (insns)
- emit_insn_after (insns, BB_END (new_bb));
-
- if (dest->loop_father->latch == src)
- dest->loop_father->latch = new_bb;
-
- return new_bb;
-}
-
/* This function is called from loop_version. It splits the entry edge
of the loop we want to version, adds the versioning condition, and
adjust the edges to the two versions of the loop appropriately.
@@ -1424,8 +1377,8 @@ loop_version (struct loops *loops, struct loop * loop,
/* At this point condition_bb is loop predheader with two successors,
first_head and second_head. Make sure that loop predheader has only
one successor. */
- loop_split_edge_with (loop_preheader_edge (loop), NULL);
- loop_split_edge_with (loop_preheader_edge (nloop), NULL);
+ split_edge (loop_preheader_edge (loop));
+ split_edge (loop_preheader_edge (nloop));
return nloop;
}
diff --git a/gcc/doc/loop.texi b/gcc/doc/loop.texi
index b207b38..8c6f52c 100644
--- a/gcc/doc/loop.texi
+++ b/gcc/doc/loop.texi
@@ -195,19 +195,11 @@ The loops tree can be manipulated using the following functions:
@item @code{remove_bb_from_loops}: Removes a basic block from loops.
@end itemize
-The specialized versions of several low-level CFG functions that also
-update loop structures are provided:
+Most low-level CFG functions update loops automatically. The following
+functions handle some more complicated cases of CFG manipulations:
@itemize
-@item @code{loop_split_edge_with}: Splits an edge, and places a
-specified RTL code on it. On GIMPLE, the function can still be used,
-but the code must be NULL.
-@item @code{bsi_insert_on_edge_immediate_loop}: Inserts code on edge,
-splitting it if necessary. Only works on GIMPLE.
@item @code{remove_path}: Removes an edge and all blocks it dominates.
-@item @code{loop_commit_inserts}: Commits insertions scheduled on edges,
-and sets loops for the new blocks. This function can only be used on
-GIMPLE.
@item @code{split_loop_exit_edge}: Splits exit edge of the loop,
ensuring that PHI node arguments remain in the loop (this ensures that
loop-closed SSA form is preserved). Only useful on GIMPLE.
diff --git a/gcc/function.h b/gcc/function.h
index 1903b16..94c8101 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -189,6 +189,9 @@ struct function GTY(())
/* The control flow graph for this function. */
struct control_flow_graph *cfg;
+ /* The loops in this function. */
+ struct loops * GTY((skip)) x_current_loops;
+
/* For function.c. */
/* Points to the FUNCTION_DECL of this function. */
@@ -520,6 +523,7 @@ extern int trampolines_created;
#define avail_temp_slots (cfun->x_avail_temp_slots)
#define temp_slot_level (cfun->x_temp_slot_level)
#define nonlocal_goto_handler_labels (cfun->x_nonlocal_goto_handler_labels)
+#define current_loops (cfun->x_current_loops)
/* Given a function decl for a containing function,
return the `struct function' for it. */
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index f2226c4..ef0c51c 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -3854,11 +3854,12 @@ if_convert (int x_life_data_ok)
&& (!flag_reorder_blocks_and_partition || !no_new_pseudos
|| !targetm.have_named_sections))
{
- struct loops loops;
-
- flow_loops_find (&loops);
- mark_loop_exit_edges (&loops);
- flow_loops_free (&loops);
+ loop_optimizer_init (0);
+ if (current_loops)
+ {
+ mark_loop_exit_edges (current_loops);
+ loop_optimizer_finalize ();
+ }
free_dominance_info (CDI_DOMINATORS);
}
diff --git a/gcc/lambda-code.c b/gcc/lambda-code.c
index 14a1ba3..d2876a7 100644
--- a/gcc/lambda-code.c
+++ b/gcc/lambda-code.c
@@ -2464,7 +2464,7 @@ perfect_nestify (struct loops *loops,
/* Create the new loop. */
olddest = loop->single_exit->dest;
- preheaderbb = loop_split_edge_with (loop->single_exit, NULL);
+ preheaderbb = split_edge (loop->single_exit);
headerbb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
/* Push the exit phi nodes that we are moving. */
diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c
index 7b9d168..afe65cb 100644
--- a/gcc/loop-doloop.c
+++ b/gcc/loop-doloop.c
@@ -257,7 +257,7 @@ add_test (rtx cond, edge *e, basic_block dest)
seq = get_insns ();
end_sequence ();
- bb = loop_split_edge_with (*e, seq);
+ bb = split_edge_and_insert (*e, seq);
*e = single_succ_edge (bb);
if (any_uncondjump_p (jump))
@@ -372,9 +372,9 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
rtx ass = copy_rtx (desc->noloop_assumptions);
basic_block preheader = loop_preheader_edge (loop)->src;
basic_block set_zero
- = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
+ = split_edge (loop_preheader_edge (loop));
basic_block new_preheader
- = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
+ = split_edge (loop_preheader_edge (loop));
edge te;
/* Expand the condition testing the assumptions and if it does not pass,
@@ -406,7 +406,6 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
{
/* All the conditions were simplified to false, remove the
unreachable set_zero block. */
- remove_bb_from_loops (set_zero);
delete_basic_block (set_zero);
}
else
diff --git a/gcc/loop-init.c b/gcc/loop-init.c
index d2c6340..dd8eec1 100644
--- a/gcc/loop-init.c
+++ b/gcc/loop-init.c
@@ -33,17 +33,17 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "flags.h"
-/* Initialize loop optimizer. This is used by the tree and RTL loop
+/* Initialize loop structures. This is used by the tree and RTL loop
optimizers. FLAGS specify what properties to compute and/or ensure for
loops. */
-struct loops *
+void
loop_optimizer_init (unsigned flags)
{
- struct loops *loops = XCNEW (struct loops);
edge e;
edge_iterator ei;
static bool first_time = true;
+ struct loops *loops;
if (first_time)
{
@@ -51,6 +51,9 @@ loop_optimizer_init (unsigned flags)
init_set_costs ();
}
+ gcc_assert (!current_loops);
+ loops = XCNEW (struct loops);
+
/* Avoid annoying special cases of edges going to exit
block. */
@@ -62,63 +65,64 @@ loop_optimizer_init (unsigned flags)
/* Find the loops. */
- if (flow_loops_find (loops) <= 1)
+ flow_loops_find (loops);
+ current_loops = loops;
+
+ if (current_loops->num <= 1)
{
/* No loops. */
- flow_loops_free (loops);
- free (loops);
-
- return NULL;
+ loop_optimizer_finalize ();
+ return;
}
- /* Not going to update these. */
- free (loops->cfg.rc_order);
- loops->cfg.rc_order = NULL;
- free (loops->cfg.dfs_order);
- loops->cfg.dfs_order = NULL;
-
/* Create pre-headers. */
if (flags & LOOPS_HAVE_PREHEADERS)
- create_preheaders (loops, CP_SIMPLE_PREHEADERS);
+ create_preheaders (current_loops, CP_SIMPLE_PREHEADERS);
/* Force all latches to have only single successor. */
if (flags & LOOPS_HAVE_SIMPLE_LATCHES)
- force_single_succ_latches (loops);
+ force_single_succ_latches (current_loops);
/* Mark irreducible loops. */
if (flags & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
- mark_irreducible_loops (loops);
+ mark_irreducible_loops (current_loops);
if (flags & LOOPS_HAVE_MARKED_SINGLE_EXITS)
- mark_single_exit_loops (loops);
+ mark_single_exit_loops (current_loops);
/* Dump loops. */
- flow_loops_dump (loops, dump_file, NULL, 1);
+ flow_loops_dump (current_loops, dump_file, NULL, 1);
#ifdef ENABLE_CHECKING
verify_dominators (CDI_DOMINATORS);
- verify_loop_structure (loops);
+ verify_loop_structure (current_loops);
#endif
-
- return loops;
}
-/* Finalize loop optimizer. */
+/* Finalize loop structures. */
+
void
-loop_optimizer_finalize (struct loops *loops)
+loop_optimizer_finalize (void)
{
unsigned i;
+ basic_block bb;
- if (!loops)
+ if (!current_loops)
return;
- for (i = 1; i < loops->num; i++)
- if (loops->parray[i])
- free_simple_loop_desc (loops->parray[i]);
+ for (i = 1; i < current_loops->num; i++)
+ if (current_loops->parray[i])
+ free_simple_loop_desc (current_loops->parray[i]);
/* Clean up. */
- flow_loops_free (loops);
- free (loops);
+ flow_loops_free (current_loops);
+ free (current_loops);
+ current_loops = NULL;
+
+ FOR_ALL_BB (bb)
+ {
+ bb->loop_father = NULL;
+ }
/* Checking. */
#ifdef ENABLE_CHECKING
@@ -173,7 +177,7 @@ rtl_loop_init (void)
/* Initialize structures for layout changes. */
cfg_layout_initialize (0);
- current_loops = loop_optimizer_init (LOOPS_NORMAL);
+ loop_optimizer_init (LOOPS_NORMAL);
return 0;
}
@@ -196,14 +200,13 @@ struct tree_opt_pass pass_rtl_loop_init =
/* Finalization of the RTL loop passes. */
+
static unsigned int
rtl_loop_done (void)
{
basic_block bb;
- if (current_loops)
- loop_optimizer_finalize (current_loops);
-
+ loop_optimizer_finalize ();
free_dominance_info (CDI_DOMINATORS);
/* Finalize layout changes. */
@@ -218,7 +221,6 @@ rtl_loop_done (void)
if (dump_file)
dump_flow_info (dump_file, dump_flags);
- current_loops = NULL;
return 0;
}
diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
index 711b021..49af45d 100644
--- a/gcc/loop-unroll.c
+++ b/gcc/loop-unroll.c
@@ -899,6 +899,18 @@ decide_unroll_runtime_iterations (struct loop *loop, int flags)
loop->lpt_decision.times);
}
+/* Splits edge E and inserts INSNS on it. */
+
+basic_block
+split_edge_and_insert (edge e, rtx insns)
+{
+ basic_block bb = split_edge (e);
+ gcc_assert (insns != NULL_RTX);
+ emit_insn_after (insns, BB_END (bb));
+ bb->flags |= BB_SUPERBLOCK;
+ return bb;
+}
+
/* Unroll LOOP for that we are able to count number of iterations in runtime
LOOP->LPT_DECISION.TIMES + 1 times. The transformation does this (with some
extra care for case n < 0):
@@ -1009,7 +1021,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
end_sequence ();
/* Precondition the loop. */
- loop_split_edge_with (loop_preheader_edge (loop), init_code);
+ split_edge_and_insert (loop_preheader_edge (loop), init_code);
remove_edges = XCNEWVEC (edge, max_unroll + n_peel + 1);
n_remove_edges = 0;
@@ -1033,8 +1045,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
gcc_assert (ok);
/* Record the place where switch will be built for preconditioning. */
- swtch = loop_split_edge_with (loop_preheader_edge (loop),
- NULL_RTX);
+ swtch = split_edge (loop_preheader_edge (loop));
for (i = 0; i < n_peel; i++)
{
@@ -1053,12 +1064,12 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
j = n_peel - i - (extra_zero_check ? 0 : 1);
p = REG_BR_PROB_BASE / (i + 2);
- preheader = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
+ preheader = split_edge (loop_preheader_edge (loop));
branch_code = compare_and_jump_seq (copy_rtx (niter), GEN_INT (j), EQ,
block_label (preheader), p,
NULL_RTX);
- swtch = loop_split_edge_with (single_pred_edge (swtch), branch_code);
+ swtch = split_edge_and_insert (single_pred_edge (swtch), branch_code);
set_immediate_dominator (CDI_DOMINATORS, preheader, swtch);
single_pred_edge (swtch)->probability = REG_BR_PROB_BASE - p;
e = make_edge (swtch, preheader,
@@ -1071,12 +1082,12 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
/* Add branch for zero iterations. */
p = REG_BR_PROB_BASE / (max_unroll + 1);
swtch = ezc_swtch;
- preheader = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
+ preheader = split_edge (loop_preheader_edge (loop));
branch_code = compare_and_jump_seq (copy_rtx (niter), const0_rtx, EQ,
block_label (preheader), p,
NULL_RTX);
- swtch = loop_split_edge_with (single_succ_edge (swtch), branch_code);
+ swtch = split_edge_and_insert (single_succ_edge (swtch), branch_code);
set_immediate_dominator (CDI_DOMINATORS, preheader, swtch);
single_succ_edge (swtch)->probability = REG_BR_PROB_BASE - p;
e = make_edge (swtch, preheader,
@@ -1717,18 +1728,12 @@ analyze_insns_in_loop (struct loop *loop)
si_info_hash, si_info_eq, free);
/* Record the loop exit bb and loop preheader before the unrolling. */
- if (!loop_preheader_edge (loop)->src)
- {
- loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
- opt_info->loop_preheader = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
- }
- else
- opt_info->loop_preheader = loop_preheader_edge (loop)->src;
+ opt_info->loop_preheader = loop_preheader_edge (loop)->src;
if (num_edges == 1
&& !(edges[0]->flags & EDGE_COMPLEX))
{
- opt_info->loop_exit = loop_split_edge_with (edges[0], NULL_RTX);
+ opt_info->loop_exit = split_edge (edges[0]);
can_apply = true;
}
diff --git a/gcc/loop-unswitch.c b/gcc/loop-unswitch.c
index c76f481..0b378f3 100644
--- a/gcc/loop-unswitch.c
+++ b/gcc/loop-unswitch.c
@@ -480,8 +480,8 @@ unswitch_loop (struct loops *loops, struct loop *loop, basic_block unswitch_on,
fix_loop_placement (nloop);
/* Preserve the simple loop preheaders. */
- loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
- loop_split_edge_with (loop_preheader_edge (nloop), NULL_RTX);
+ split_edge (loop_preheader_edge (loop));
+ split_edge (loop_preheader_edge (nloop));
return nloop;
}
diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c
index 8426ba6..62918a0 100644
--- a/gcc/modulo-sched.c
+++ b/gcc/modulo-sched.c
@@ -742,9 +742,9 @@ generate_prolog_epilog (partial_schedule_ptr ps, struct loop * loop, rtx count_r
for (i = 0; i < last_stage; i++)
duplicate_insns_of_cycles (ps, 0, i, 1);
- /* Put the prolog , on the one and only entry edge. */
+ /* Put the prolog on the entry edge. */
e = loop_preheader_edge (loop);
- loop_split_edge_with(e , get_insns());
+ split_edge_and_insert (e, get_insns());
end_sequence ();
@@ -754,10 +754,10 @@ generate_prolog_epilog (partial_schedule_ptr ps, struct loop * loop, rtx count_r
for (i = 0; i < last_stage; i++)
duplicate_insns_of_cycles (ps, i + 1, last_stage, 0);
- /* Put the epilogue on the one and only one exit edge. */
+ /* Put the epilogue on the exit edge. */
gcc_assert (loop->single_exit);
e = loop->single_exit;
- loop_split_edge_with(e , get_insns());
+ split_edge_and_insert (e, get_insns());
end_sequence ();
}
@@ -848,7 +848,7 @@ canon_loop (struct loop *loop)
block. */
FOR_EACH_EDGE (e, i, EXIT_BLOCK_PTR->preds)
if ((e->flags & EDGE_FALLTHRU) && (EDGE_COUNT (e->src->succs) > 1))
- loop_split_edge_with (e, NULL_RTX);
+ split_edge (e);
if (loop->latch == loop->header
|| EDGE_COUNT (loop->latch->succs) > 1)
@@ -856,7 +856,7 @@ canon_loop (struct loop *loop)
FOR_EACH_EDGE (e, i, loop->header->preds)
if (e->src == loop->latch)
break;
- loop_split_edge_with (e, NULL_RTX);
+ split_edge (e);
}
}
@@ -873,7 +873,6 @@ sms_schedule (void)
unsigned i,num_loops;
partial_schedule_ptr ps;
struct df *df;
- struct loops *loops;
basic_block bb = NULL;
/* vars to the versioning only if needed*/
struct loop * nloop;
@@ -881,10 +880,10 @@ sms_schedule (void)
edge latch_edge;
gcov_type trip_count = 0;
- loops = loop_optimizer_init (LOOPS_HAVE_PREHEADERS
- | LOOPS_HAVE_MARKED_SINGLE_EXITS);
- if (!loops)
- return; /* There is no loops to schedule. */
+ loop_optimizer_init (LOOPS_HAVE_PREHEADERS
+ | LOOPS_HAVE_MARKED_SINGLE_EXITS);
+ if (!current_loops)
+ return; /* There are no loops to schedule. */
/* Initialize issue_rate. */
if (targetm.sched.issue_rate)
@@ -914,16 +913,16 @@ sms_schedule (void)
/* Allocate memory to hold the DDG array one entry for each loop.
We use loop->num as index into this array. */
- g_arr = XCNEWVEC (ddg_ptr, loops->num);
+ g_arr = XCNEWVEC (ddg_ptr, current_loops->num);
/* Build DDGs for all the relevant loops and hold them in G_ARR
indexed by the loop index. */
- for (i = 0; i < loops->num; i++)
+ for (i = 0; i < current_loops->num; i++)
{
rtx head, tail;
rtx count_reg;
- struct loop *loop = loops->parray[i];
+ struct loop *loop = current_loops->parray[i];
/* For debugging. */
if ((passes++ > MAX_SMS_LOOP_NUMBER) && (MAX_SMS_LOOP_NUMBER != -1))
@@ -1018,7 +1017,7 @@ sms_schedule (void)
df = NULL;
/* We don't want to perform SMS on new loops - created by versioning. */
- num_loops = loops->num;
+ num_loops = current_loops->num;
/* Go over the built DDGs and perfrom SMS for each one of them. */
for (i = 0; i < num_loops; i++)
{
@@ -1027,7 +1026,7 @@ sms_schedule (void)
int mii, rec_mii;
unsigned stage_count = 0;
HOST_WIDEST_INT loop_count = 0;
- struct loop *loop = loops->parray[i];
+ struct loop *loop = current_loops->parray[i];
if (! (g = g_arr[i]))
continue;
@@ -1177,8 +1176,8 @@ sms_schedule (void)
rtx comp_rtx = gen_rtx_fmt_ee (GT, VOIDmode, count_reg,
GEN_INT(stage_count));
- nloop = loop_version (loops, loop, comp_rtx, &condition_bb,
- true);
+ nloop = loop_version (current_loops, loop, comp_rtx,
+ &condition_bb, true);
}
/* Set new iteration count of loop kernel. */
@@ -1218,7 +1217,7 @@ sms_schedule (void)
/* Release scheduler data, needed until now because of DFA. */
sched_finish ();
- loop_optimizer_finalize (loops);
+ loop_optimizer_finalize ();
}
/* The SMS scheduling algorithm itself
diff --git a/gcc/predict.c b/gcc/predict.c
index 6b493e2..caf867e 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -74,8 +74,6 @@ static sreal real_zero, real_one, real_almost_one, real_br_prob_base,
static void combine_predictions_for_insn (rtx, basic_block);
static void dump_prediction (FILE *, enum br_predictor, int, basic_block, int);
-static void estimate_loops_at_level (struct loop *, bitmap);
-static void propagate_freq (struct loop *, bitmap);
static void estimate_bb_frequencies (struct loops *);
static void predict_paths_leading_to (basic_block, int *, enum br_predictor, enum prediction);
static bool last_basic_block_p (basic_block);
@@ -744,7 +742,6 @@ predict_loops (struct loops *loops_info)
}
scev_finalize ();
- current_loops = NULL;
}
/* Attempt to predict probabilities of BB outgoing edges using local
@@ -1252,11 +1249,10 @@ static unsigned int
tree_estimate_probability (void)
{
basic_block bb;
- struct loops loops_info;
- flow_loops_find (&loops_info);
+ loop_optimizer_init (0);
if (dump_file && (dump_flags & TDF_DETAILS))
- flow_loops_dump (&loops_info, dump_file, NULL, 0);
+ flow_loops_dump (current_loops, dump_file, NULL, 0);
add_noreturn_fake_exit_edges ();
connect_infinite_loops_to_exit ();
@@ -1265,8 +1261,9 @@ tree_estimate_probability (void)
tree_bb_level_predictions ();
- mark_irreducible_loops (&loops_info);
- predict_loops (&loops_info);
+ mark_irreducible_loops (current_loops);
+ if (current_loops)
+ predict_loops (current_loops);
FOR_EACH_BB (bb)
{
@@ -1328,10 +1325,10 @@ tree_estimate_probability (void)
combine_predictions_for_bb (bb);
strip_builtin_expect ();
- estimate_bb_frequencies (&loops_info);
+ estimate_bb_frequencies (current_loops);
free_dominance_info (CDI_POST_DOMINATORS);
remove_fake_exit_edges ();
- flow_loops_free (&loops_info);
+ loop_optimizer_finalize ();
if (dump_file && (dump_flags & TDF_DETAILS))
dump_tree_cfg (dump_file, dump_flags);
if (profile_status == PROFILE_ABSENT)
@@ -1437,12 +1434,12 @@ typedef struct edge_info_def
#define EDGE_INFO(E) ((edge_info) (E)->aux)
/* Helper function for estimate_bb_frequencies.
- Propagate the frequencies for LOOP. */
+ Propagate the frequencies in blocks marked in
+ TOVISIT, starting in HEAD. */
static void
-propagate_freq (struct loop *loop, bitmap tovisit)
+propagate_freq (basic_block head, bitmap tovisit)
{
- basic_block head = loop->header;
basic_block bb;
basic_block last;
unsigned i;
@@ -1579,7 +1576,7 @@ propagate_freq (struct loop *loop, bitmap tovisit)
/* Estimate probabilities of loopback edges in loops at same nest level. */
static void
-estimate_loops_at_level (struct loop *first_loop, bitmap tovisit)
+estimate_loops_at_level (struct loop *first_loop)
{
struct loop *loop;
@@ -1588,25 +1585,44 @@ estimate_loops_at_level (struct loop *first_loop, bitmap tovisit)
edge e;
basic_block *bbs;
unsigned i;
+ bitmap tovisit = BITMAP_ALLOC (NULL);
- estimate_loops_at_level (loop->inner, tovisit);
+ estimate_loops_at_level (loop->inner);
- /* Do not do this for dummy function loop. */
- if (EDGE_COUNT (loop->latch->succs) > 0)
- {
- /* Find current loop back edge and mark it. */
- e = loop_latch_edge (loop);
- EDGE_INFO (e)->back_edge = 1;
- }
+ /* Find current loop back edge and mark it. */
+ e = loop_latch_edge (loop);
+ EDGE_INFO (e)->back_edge = 1;
bbs = get_loop_body (loop);
for (i = 0; i < loop->num_nodes; i++)
bitmap_set_bit (tovisit, bbs[i]->index);
free (bbs);
- propagate_freq (loop, tovisit);
+ propagate_freq (loop->header, tovisit);
+ BITMAP_FREE (tovisit);
}
}
+/* Propates frequencies through structure of LOOPS. */
+
+static void
+estimate_loops (struct loops *loops)
+{
+ bitmap tovisit = BITMAP_ALLOC (NULL);
+ basic_block bb;
+
+ /* Start by estimating the frequencies in the loops. */
+ if (loops)
+ estimate_loops_at_level (loops->tree_root->inner);
+
+ /* Now propagate the frequencies through all the blocks. */
+ FOR_ALL_BB (bb)
+ {
+ bitmap_set_bit (tovisit, bb->index);
+ }
+ propagate_freq (ENTRY_BLOCK_PTR, tovisit);
+ BITMAP_FREE (tovisit);
+}
+
/* Convert counts measured by profile driven feedback to frequencies.
Return nonzero iff there was any nonzero execution count. */
@@ -1677,7 +1693,6 @@ estimate_bb_frequencies (struct loops *loops)
if (!flag_branch_probabilities || !counts_to_freqs ())
{
static int real_values_initialized = 0;
- bitmap tovisit;
if (!real_values_initialized)
{
@@ -1696,7 +1711,6 @@ estimate_bb_frequencies (struct loops *loops)
single_succ_edge (ENTRY_BLOCK_PTR)->probability = REG_BR_PROB_BASE;
/* Set up block info for each basic block. */
- tovisit = BITMAP_ALLOC (NULL);
alloc_aux_for_blocks (sizeof (struct block_info_def));
alloc_aux_for_edges (sizeof (struct edge_info_def));
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
@@ -1715,7 +1729,7 @@ estimate_bb_frequencies (struct loops *loops)
/* First compute probabilities locally for each loop from innermost
to outermost to examine probabilities for back edges. */
- estimate_loops_at_level (loops->tree_root, tovisit);
+ estimate_loops (loops);
memcpy (&freq_max, &real_zero, sizeof (real_zero));
FOR_EACH_BB (bb)
@@ -1734,7 +1748,6 @@ estimate_bb_frequencies (struct loops *loops)
free_aux_for_blocks ();
free_aux_for_edges ();
- BITMAP_FREE (tovisit);
}
compute_function_frequency ();
if (flag_reorder_functions)
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index fc30f22..292fa48 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -1998,24 +1998,15 @@ remove_bb (basic_block bb)
}
}
- /* 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 (current_loops)
{
struct loop *loop = bb->loop_father;
+ /* If a loop gets removed, clean up the information associated
+ with it. */
if (loop->latch == bb
|| loop->header == bb)
- {
- loop->latch = NULL;
- loop->header = NULL;
-
- /* Also clean up the information associated with the loop. Updating
- it would waste time. More importantly, it may refer to ssa
- names that were defined in other removed basic block -- these
- ssa names are now removed and invalid. */
- free_numbers_of_iterations_estimates_loop (loop);
- }
+ free_numbers_of_iterations_estimates_loop (loop);
}
/* Remove all the instructions in the block. */
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 6492630..2444ced 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -836,13 +836,11 @@ void free_numbers_of_iterations_estimates (struct loops *);
void free_numbers_of_iterations_estimates_loop (struct loop *);
void rewrite_into_loop_closed_ssa (bitmap, unsigned);
void verify_loop_closed_ssa (void);
-void loop_commit_inserts (void);
bool for_each_index (tree *, bool (*) (tree, tree *, void *), void *);
void create_iv (tree, tree, tree, struct loop *, block_stmt_iterator *, bool,
tree *, tree *);
void split_loop_exit_edge (edge);
unsigned force_expr_to_var_cost (tree);
-basic_block bsi_insert_on_edge_immediate_loop (edge, tree);
void standard_iv_increment_position (struct loop *, block_stmt_iterator *,
bool *);
basic_block ip_end_pos (struct loop *);
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 3a50741..a4daaa2 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -949,17 +949,9 @@ combine_blocks (struct loop *loop)
/* Update stmt list. */
last = tsi_last (merge_target_bb->stmt_list);
tsi_link_after (&last, bb->stmt_list, TSI_NEW_STMT);
- bb->stmt_list = NULL;
+ bb->stmt_list = alloc_stmt_list ();
- /* Update dominator info. */
- if (dom_computed[CDI_DOMINATORS])
- delete_from_dominance_info (CDI_DOMINATORS, bb);
- if (dom_computed[CDI_POST_DOMINATORS])
- delete_from_dominance_info (CDI_POST_DOMINATORS, bb);
-
- /* Remove basic block. */
- remove_bb_from_loops (bb);
- expunge_block (bb);
+ delete_basic_block (bb);
}
/* Now if possible, merge loop header and block with exit edge.
@@ -968,10 +960,7 @@ combine_blocks (struct loop *loop)
if (exit_bb
&& exit_bb != loop->header
&& can_merge_blocks_p (loop->header, exit_bb))
- {
- remove_bb_from_loops (exit_bb);
- merge_blocks (loop->header, exit_bb);
- }
+ merge_blocks (loop->header, exit_bb);
}
/* Make new temp variable of type TYPE. Add MODIFY_EXPR to assign EXP
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 085a5d6..4ec276d 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -240,7 +240,6 @@ tree_ssa_dominator_optimize (void)
{
struct dom_walk_data walk_data;
unsigned int i;
- struct loops loops_info;
memset (&opt_stats, 0, sizeof (opt_stats));
@@ -276,9 +275,12 @@ tree_ssa_dominator_optimize (void)
/* We need to know which edges exit loops so that we can
aggressively thread through loop headers to an exit
edge. */
- flow_loops_find (&loops_info);
- mark_loop_exit_edges (&loops_info);
- flow_loops_free (&loops_info);
+ loop_optimizer_init (0);
+ if (current_loops)
+ {
+ mark_loop_exit_edges (current_loops);
+ loop_optimizer_finalize ();
+ }
/* Clean up the CFG so that any forwarder blocks created by loop
canonicalization are removed. */
diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c
index 1663807..30db10c 100644
--- a/gcc/tree-ssa-loop-ch.c
+++ b/gcc/tree-ssa-loop-ch.c
@@ -123,7 +123,6 @@ do_while_loop_p (struct loop *loop)
static unsigned int
copy_loop_headers (void)
{
- struct loops *loops;
unsigned i;
struct loop *loop;
basic_block header;
@@ -132,25 +131,25 @@ copy_loop_headers (void)
unsigned n_bbs;
unsigned bbs_size;
- loops = loop_optimizer_init (LOOPS_HAVE_PREHEADERS
- | LOOPS_HAVE_SIMPLE_LATCHES);
- if (!loops)
+ loop_optimizer_init (LOOPS_HAVE_PREHEADERS
+ | LOOPS_HAVE_SIMPLE_LATCHES);
+ if (!current_loops)
return 0;
#ifdef ENABLE_CHECKING
- verify_loop_structure (loops);
+ verify_loop_structure (current_loops);
#endif
bbs = XNEWVEC (basic_block, n_basic_blocks);
copied_bbs = XNEWVEC (basic_block, n_basic_blocks);
bbs_size = n_basic_blocks;
- for (i = 1; i < loops->num; i++)
+ for (i = 1; i < current_loops->num; i++)
{
/* Copy at most 20 insns. */
int limit = 20;
- loop = loops->parray[i];
+ loop = current_loops->parray[i];
if (!loop)
continue;
header = loop->header;
@@ -194,7 +193,7 @@ copy_loop_headers (void)
/* Ensure that the header will have just the latch as a predecessor
inside the loop. */
if (!single_pred_p (exit->dest))
- exit = single_pred_edge (loop_split_edge_with (exit, NULL));
+ exit = single_pred_edge (split_edge (exit));
entry = loop_preheader_edge (loop);
@@ -206,14 +205,14 @@ copy_loop_headers (void)
/* Ensure that the latch and the preheader is simple (we know that they
are not now, since there was the loop exit condition. */
- loop_split_edge_with (loop_preheader_edge (loop), NULL);
- loop_split_edge_with (loop_latch_edge (loop), NULL);
+ split_edge (loop_preheader_edge (loop));
+ split_edge (loop_latch_edge (loop));
}
free (bbs);
free (copied_bbs);
- loop_optimizer_finalize (loops);
+ loop_optimizer_finalize ();
return 0;
}
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index db9f42f6..de0429e 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -690,25 +690,6 @@ determine_invariantness (void)
fini_walk_dominator_tree (&walk_data);
}
-/* Commits edge insertions and updates loop structures. */
-
-void
-loop_commit_inserts (void)
-{
- unsigned old_last_basic_block, i;
- basic_block bb;
-
- old_last_basic_block = last_basic_block;
- bsi_commit_edge_inserts ();
- for (i = old_last_basic_block; i < (unsigned) last_basic_block; i++)
- {
- bb = BASIC_BLOCK (i);
- add_bb_to_loop (bb,
- find_common_loop (single_pred (bb)->loop_father,
- single_succ (bb)->loop_father));
- }
-}
-
/* Hoist the statements in basic block BB out of the loops prescribed by
data stored in LIM_DATA structures associated with each statement. Callback
for walk_dominator_tree. */
@@ -778,7 +759,7 @@ move_computations (void)
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
fini_walk_dominator_tree (&walk_data);
- loop_commit_inserts ();
+ bsi_commit_edge_inserts ();
if (need_ssa_update_p ())
rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
}
@@ -1419,7 +1400,7 @@ determine_lsm (struct loops *loops)
loop = loop->outer;
if (loop == loops->tree_root)
{
- loop_commit_inserts ();
+ bsi_commit_edge_inserts ();
return;
}
}
diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
index dde0e8d..68e0fa6 100644
--- a/gcc/tree-ssa-loop-manip.c
+++ b/gcc/tree-ssa-loop-manip.c
@@ -98,7 +98,7 @@ create_iv (tree base, tree step, tree var, struct loop *loop,
loop (i.e. the step should be loop invariant). */
step = force_gimple_operand (step, &stmts, true, var);
if (stmts)
- bsi_insert_on_edge_immediate_loop (pe, stmts);
+ bsi_insert_on_edge_immediate (pe, stmts);
stmt = build2 (MODIFY_EXPR, void_type_node, va,
build2 (incr_op, TREE_TYPE (base),
@@ -111,7 +111,7 @@ create_iv (tree base, tree step, tree var, struct loop *loop,
initial = force_gimple_operand (base, &stmts, true, var);
if (stmts)
- bsi_insert_on_edge_immediate_loop (pe, stmts);
+ bsi_insert_on_edge_immediate (pe, stmts);
stmt = create_phi_node (vb, loop->header);
SSA_NAME_DEF_STMT (vb) = stmt;
@@ -445,7 +445,7 @@ void
split_loop_exit_edge (edge exit)
{
basic_block dest = exit->dest;
- basic_block bb = loop_split_edge_with (exit, NULL);
+ basic_block bb = split_edge (exit);
tree phi, new_phi, new_name, name;
use_operand_p op_p;
@@ -470,32 +470,6 @@ split_loop_exit_edge (edge exit)
}
}
-/* Insert statement STMT to the edge E and update the loop structures.
- Returns the newly created block (if any). */
-
-basic_block
-bsi_insert_on_edge_immediate_loop (edge e, tree stmt)
-{
- basic_block src, dest, new_bb;
- struct loop *loop_c;
-
- src = e->src;
- dest = e->dest;
-
- loop_c = find_common_loop (src->loop_father, dest->loop_father);
-
- new_bb = bsi_insert_on_edge_immediate (e, stmt);
-
- if (!new_bb)
- return NULL;
-
- add_bb_to_loop (new_bb, loop_c);
- if (dest->loop_father->latch == src)
- dest->loop_father->latch = new_bb;
-
- return new_bb;
-}
-
/* Returns the basic block in that statements should be emitted for induction
variables incremented at the end of the LOOP. */
@@ -749,7 +723,7 @@ determine_exit_conditions (struct loop *loop, struct tree_niter_desc *desc,
cond = force_gimple_operand (unshare_expr (cond), &stmts, false, NULL_TREE);
if (stmts)
- bsi_insert_on_edge_immediate_loop (loop_preheader_edge (loop), stmts);
+ bsi_insert_on_edge_immediate (loop_preheader_edge (loop), stmts);
/* cond now may be a gimple comparison, which would be OK, but also any
other gimple rhs (say a && b). In this case we need to force it to
operand. */
@@ -757,16 +731,16 @@ determine_exit_conditions (struct loop *loop, struct tree_niter_desc *desc,
{
cond = force_gimple_operand (cond, &stmts, true, NULL_TREE);
if (stmts)
- bsi_insert_on_edge_immediate_loop (loop_preheader_edge (loop), stmts);
+ bsi_insert_on_edge_immediate (loop_preheader_edge (loop), stmts);
}
*enter_cond = cond;
base = force_gimple_operand (unshare_expr (base), &stmts, true, NULL_TREE);
if (stmts)
- bsi_insert_on_edge_immediate_loop (loop_preheader_edge (loop), stmts);
+ bsi_insert_on_edge_immediate (loop_preheader_edge (loop), stmts);
bound = force_gimple_operand (unshare_expr (bound), &stmts, true, NULL_TREE);
if (stmts)
- bsi_insert_on_edge_immediate_loop (loop_preheader_edge (loop), stmts);
+ bsi_insert_on_edge_immediate (loop_preheader_edge (loop), stmts);
*exit_base = base;
*exit_step = bigstep;
@@ -881,7 +855,7 @@ tree_unroll_loop (struct loops *loops, struct loop *loop, unsigned factor,
/* Prepare the cfg and update the phi nodes. */
rest = loop_preheader_edge (new_loop)->src;
precond_edge = single_pred_edge (rest);
- loop_split_edge_with (loop_latch_edge (loop), NULL);
+ split_edge (loop_latch_edge (loop));
exit_bb = single_pred (loop->latch);
new_exit = make_edge (exit_bb, rest, EDGE_FALSE_VALUE | irr);
diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c
index e415448..69d353b 100644
--- a/gcc/tree-ssa-loop.c
+++ b/gcc/tree-ssa-loop.c
@@ -38,26 +38,17 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "tree-inline.h"
#include "tree-scalar-evolution.h"
-/* The loop tree currently optimized. */
-
-struct loops *current_loops = NULL;
-
/* Initializes the loop structures. */
-static struct loops *
+static void
tree_loop_optimizer_init (void)
{
- struct loops *loops;
-
- loops = loop_optimizer_init (LOOPS_NORMAL
- | LOOPS_HAVE_MARKED_SINGLE_EXITS);
-
- if (!loops)
- return NULL;
+ loop_optimizer_init (LOOPS_NORMAL
+ | LOOPS_HAVE_MARKED_SINGLE_EXITS);
+ if (!current_loops)
+ return;
rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
-
- return loops;
}
/* The loop superpass. */
@@ -90,7 +81,7 @@ struct tree_opt_pass pass_tree_loop =
static unsigned int
tree_ssa_loop_init (void)
{
- current_loops = tree_loop_optimizer_init ();
+ tree_loop_optimizer_init ();
if (!current_loops)
return 0;
@@ -487,8 +478,7 @@ tree_ssa_loop_done (void)
free_numbers_of_iterations_estimates (current_loops);
scev_finalize ();
- loop_optimizer_finalize (current_loops);
- current_loops = NULL;
+ loop_optimizer_finalize ();
return 0;
}
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index d83d81e..2a0ac96 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -4065,7 +4065,7 @@ init_pre (bool do_fre)
vn_init ();
if (!do_fre)
- current_loops = loop_optimizer_init (LOOPS_NORMAL);
+ loop_optimizer_init (LOOPS_NORMAL);
connect_infinite_loops_to_exit ();
memset (&pre_stats, 0, sizeof (pre_stats));
@@ -4169,10 +4169,7 @@ fini_pre (bool do_fre)
SSA_NAME_VALUE (name) = NULL;
}
if (!do_fre && current_loops)
- {
- loop_optimizer_finalize (current_loops);
- current_loops = NULL;
- }
+ loop_optimizer_finalize ();
}
/* Main entry point to the SSA-PRE pass. DO_FRE is true if the caller
diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c
index 4db67c5..fa711b3 100644
--- a/gcc/tree-ssa-sink.c
+++ b/gcc/tree-ssa-sink.c
@@ -522,7 +522,7 @@ sink_code_in_bb (basic_block bb)
static void
execute_sink_code (void)
{
- struct loops *loops = loop_optimizer_init (LOOPS_NORMAL);
+ loop_optimizer_init (LOOPS_NORMAL);
connect_infinite_loops_to_exit ();
memset (&sink_stats, 0, sizeof (sink_stats));
@@ -532,7 +532,7 @@ execute_sink_code (void)
fprintf (dump_file, "Sunk statements:%d\n", sink_stats.sunk);
free_dominance_info (CDI_POST_DOMINATORS);
remove_fake_exit_edges ();
- loop_optimizer_finalize (loops);
+ loop_optimizer_finalize ();
}
/* Gate and execute functions for PRE. */
diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c
index e59c152..6091575 100644
--- a/gcc/tree-vect-transform.c
+++ b/gcc/tree-vect-transform.c
@@ -3845,7 +3845,6 @@ vect_transform_loop (loop_vec_info loop_vinfo,
merge_bb = loop->single_exit->dest;
gcc_assert (EDGE_COUNT (merge_bb->preds) == 2);
new_exit_bb = split_edge (loop->single_exit);
- add_bb_to_loop (new_exit_bb, loop->outer);
new_exit_e = loop->single_exit;
e = EDGE_SUCC (new_exit_bb, 0);
@@ -3897,8 +3896,7 @@ vect_transform_loop (loop_vec_info loop_vinfo,
gcc_assert (EDGE_COUNT (loop->header->preds) == 2);
- loop_split_edge_with (loop_preheader_edge (loop), NULL);
-
+ split_edge (loop_preheader_edge (loop));
/* FORNOW: the vectorizer supports only loops which body consist
of one basic block (header + empty latch). When the vectorizer will
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index d5b33d6..8bc6885 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -520,7 +520,6 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
/* Create new bb between loop and new_merge_bb. */
*new_exit_bb = split_edge (loop->single_exit);
- add_bb_to_loop (*new_exit_bb, loop->outer);
new_exit_e = EDGE_SUCC (*new_exit_bb, 0);
@@ -646,7 +645,6 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
/* Create new bb between loop and new_merge_bb. */
*new_exit_bb = split_edge (loop->single_exit);
- add_bb_to_loop (*new_exit_bb, loop->outer);
new_exit_e = EDGE_SUCC (*new_exit_bb, 0);
@@ -1157,9 +1155,7 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops,
*/
bb_before_first_loop = split_edge (loop_preheader_edge (first_loop));
- add_bb_to_loop (bb_before_first_loop, first_loop->outer);
bb_before_second_loop = split_edge (first_loop->single_exit);
- add_bb_to_loop (bb_before_second_loop, first_loop->outer);
pre_condition =
fold_build2 (LE_EXPR, boolean_type_node, first_niters,
@@ -1199,7 +1195,6 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops,
bb_between_loops = new_exit_bb;
bb_after_second_loop = split_edge (second_loop->single_exit);
- add_bb_to_loop (bb_after_second_loop, second_loop->outer);
pre_condition =
fold_build2 (EQ_EXPR, boolean_type_node, first_niters, niters);
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 8b43770..7b8996c 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -4772,7 +4772,7 @@ execute_vrp (void)
{
insert_range_assertions ();
- current_loops = loop_optimizer_init (LOOPS_NORMAL);
+ loop_optimizer_init (LOOPS_NORMAL);
if (current_loops)
scev_initialize (current_loops);
@@ -4783,8 +4783,7 @@ execute_vrp (void)
if (current_loops)
{
scev_finalize ();
- loop_optimizer_finalize (current_loops);
- current_loops = NULL;
+ loop_optimizer_finalize ();
}
/* ASSERT_EXPRs must be removed before finalizing jump threads