]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-vrp.c (execute_vrp): Do not update current_loops.
authorZdenek Dvorak <dvorakz@suse.cz>
Fri, 17 Nov 2006 11:29:17 +0000 (12:29 +0100)
committerZdenek Dvorak <rakdver@gcc.gnu.org>
Fri, 17 Nov 2006 11:29:17 +0000 (11:29 +0000)
* 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

32 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/basic-block.h
gcc/cfghooks.c
gcc/cfglayout.c
gcc/cfgloop.c
gcc/cfgloop.h
gcc/cfgloopanal.c
gcc/cfgloopmanip.c
gcc/doc/loop.texi
gcc/function.h
gcc/ifcvt.c
gcc/lambda-code.c
gcc/loop-doloop.c
gcc/loop-init.c
gcc/loop-unroll.c
gcc/loop-unswitch.c
gcc/modulo-sched.c
gcc/predict.c
gcc/tree-cfg.c
gcc/tree-flow.h
gcc/tree-if-conv.c
gcc/tree-ssa-dom.c
gcc/tree-ssa-loop-ch.c
gcc/tree-ssa-loop-im.c
gcc/tree-ssa-loop-manip.c
gcc/tree-ssa-loop.c
gcc/tree-ssa-pre.c
gcc/tree-ssa-sink.c
gcc/tree-vect-transform.c
gcc/tree-vectorizer.c
gcc/tree-vrp.c

index ab9b5526eec0d6b4241dcc2f04cc556b7a7cd536..12c61b79200b6abaa037bfb14d6fc474ef89e9ce 100644 (file)
@@ -1,3 +1,86 @@
+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
index fda394c1ca0461cb46cc6db418dbb134bf2cec78..8136290694ee79d1d00cef5565a85e29ffdb8620 100644 (file)
@@ -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) \
index aa4148624d65388ead338658740ebec3dd5f2f5a..6b6820c1d0fff870fc04251a87338deee508c20a 100644 (file)
@@ -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);
index 4d89aea8f5c9123f4765e2bcf55ecfbbfa5e8a60..0378b13ba8007c30331f79a04ebb9d8272c27ce9 100644 (file)
@@ -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;
 }
 
index 6bd63c250a1f41d9d9b81f741b0e4e68afcc7989..cf76cdb4125304a8aee6b95a6d65828f6ba1305b 100644 (file)
@@ -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.  */
index 9afd48ba21790f887ec6cc46a5e136cb65b23d5d..25549db5b940984555fac341e4af45104503dbdc 100644 (file)
@@ -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--;
index 311c43ea9226e3f353d00ae5472068dcfd15d10b..17a1cf7d9313d5952a580687eb379d09e688bd47 100644 (file)
@@ -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);
index da545838436856559e48139f8471dd2976b655f3..9aa75e4f2d646f21e4cf8154d674ae82e4ed1963 100644 (file)
@@ -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.  */
index 8c5a0f14a58c0b32dd8fa6cb5504720ed5302956..edb36976cc8a507ca486a7d1c163ad9038784295 100644 (file)
@@ -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;
 }
index b207b38cee846761136a735a03c2abb9eb867ef6..8c6f52ca95d48d4093f720fc639f0f403445275d 100644 (file)
@@ -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.
index 1903b165f419a05d7caa5cbbcb9e823f1d583a5a..94c81018d83f6080f6d0db70522709849caed1f9 100644 (file)
@@ -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.  */
index f2226c402aabe398c6f011f80c225a90c367a6f2..ef0c51c6500e6039b803aeb6fadf65ec04b2d60e 100644 (file)
@@ -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);
     }
 
index 14a1ba35c253e5484093085252ab072b3c3cebb2..d2876a7c8a1de2c88ce2b8c8537ac8099ca75cbc 100644 (file)
@@ -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.  */
index 7b9d168157a3143f13e7e79b31dde93d1ec9fa76..afe65cb7d288cb65fc13c6caa6c7fcaffbdd1593 100644 (file)
@@ -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
index d2c63404516a10e61602c6f38906559bf971c9b0..dd8eec15a68df50fd8bca25d4cbba6e1851d43f2 100644 (file)
@@ -33,17 +33,17 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "flags.h"
 
 \f
-/* 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 =
 
 \f
 /* 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;
 }
 
index 711b02161abc2f2725544b6cd6eabecbde6eec85..49af45d4073d0d70bc9e58f4f896485ac0d8527b 100644 (file)
@@ -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;
     }
   
index c76f481e08e424be4c3cfe2644d0e6a315abe81a..0b378f3ffdea12be818e32c4e65d29ed119e7c9f 100644 (file)
@@ -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;
 }
index 8426ba6313a963cae175c0b444afc1b3e1d4e4f6..62918a057ee66739c144957a4ac1c40817980bad 100644 (file)
@@ -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
index 6b493e264f2454818ac5f42a7fc6ac503ca8ab64..caf867ee0424d4d267a9566c4175e9b82ae56a87 100644 (file)
@@ -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)
index fc30f2285d506ff61aba6f0f5719cee8ffbf99e4..292fa48fb21f6b3dc2ebc40116ccd4d6da6bdff6 100644 (file)
@@ -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.  */
index 64926306ba9a0f59a9ff5d81eb87797e26c4749d..2444ced0bc465ff22f87511e97e105c1916b0f18 100644 (file)
@@ -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 *);
index 3a50741aff528b88d123d93cff04dd83441d5c7b..a4daaa239c2e1c332685910c96eb7d43144a245e 100644 (file)
@@ -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
index 085a5d604823890cbfd35b74d2c2026fcc5320c0..4ec276d8e5c94b91a14a084336936b518ef81166 100644 (file)
@@ -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.  */
index 1663807127a51a0c2993ae9b1f91af818e86decd..30db10c17ebe166dbba43b856a9aadada03f1f64 100644 (file)
@@ -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;
 }
 
index db9f42f698794f4df855a4a691cbb764c6144397..de0429e7683da0cea552da8e88579eebf5c2bee0 100644 (file)
@@ -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;
            }
        }
index dde0e8d2a09fc307a380505f76c866bebeaa0fd5..68e0fa6fe492c166ce32351a6cd43acc365b0446 100644 (file)
@@ -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);
index e415448ae5b86da83d4a20fb26e11146e69fa6b4..69d353b7c15997778405d031febe3ebd21414dde 100644 (file)
@@ -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;
 }
   
index d83d81eb11a2863d8dedf20b0892d5a262fc1c91..2a0ac9641a476f178b1c80bdfc06188a053bbb46 100644 (file)
@@ -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
index 4db67c524cebbe75e09d45e61a941e193b470839..fa711b386430b2f921ddd775cfd99d3fde4ad9c2 100644 (file)
@@ -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.  */
index e59c152139b8289a486b3db69115c0cd6fea0dc8..6091575ebc46a9f82850d1c6eae6394c9db847a6 100644 (file)
@@ -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 
index d5b33d6cdc6d905ef1e2cc97e8698989c668619e..8bc6885906d7ec62ba81382a68a8058e0b377a29 100644 (file)
@@ -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);
index 8b43770413088f2fb97b7821cd8c89702d71e139..7b8996c5964560fa613c07465972c7120ebd22cc 100644 (file)
@@ -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