Makefile.in (cfghooks.o): Add TIMEVAR_H and toplev.h dependency.
authorZdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
Thu, 29 Jan 2004 07:47:56 +0000 (08:47 +0100)
committerZdenek Dvorak <rakdver@gcc.gnu.org>
Thu, 29 Jan 2004 07:47:56 +0000 (07:47 +0000)
* Makefile.in (cfghooks.o): Add TIMEVAR_H and toplev.h dependency.
* basic-block.h (tidy_fallthru_edge, tidy_fallthru_edges, dump_bb,
verify_flow_info): Declaration removed.
* cfg.c (verify_flow_info, dump_bb): Moved to cfghooks.c.
(debug_bb, debug_bb_n): Add argument to dump_bb call.
* cfgcleanup.c (try_simplify_condjump, try_crossjump_to_edge,
try_optimize_cfg, delete_unreachable_blocks): Use delete_basic_block
instead of delete_block.
* cfghooks.c: Include timevar.h and toplev.h.
(cfg_hooks): Define here.
(verify_flow_info, dump_bb): Moved from cfg.c.
(redirect_edge_and_branch, redirect_edge_and_branch_force,
split_block, split_block_after_labels, move_block_after,
delete_basic_block, split_edge, create_basic_block,
create_empty_bb, can_merge_blocks_p, merge_blocks,
make_forwarder_block, tidy_fallthru_edge, tidy_fallthru_edges):
New functions.
* cfghooks.h (struct cfg_hooks): Added fields name,
make_forwarder_block, tidy_fallthru_edge and
move_block_after. Changed type of verify_flow_info, dump_bb,
split_block fields. Renamed cfgh_split_edge and delete_block
fields.
(redirect_edge_and_branch, redirect_edge_and_branch_force,
split_block, delete_block, split_edge, create_basic_block,
can_merge_blocks_p, merge_blocks): Macros removed.
(cfg_hooks): Do not export.
(verify_flow_info, dump_bb, redirect_edge_and_branch,
redirect_edge_and_branch_force, split_block, split_block_after_labels,
move_block_after, delete_basic_block, split_edge, create_basic_block,
create_empty_bb, can_merge_blocks_p, merge_blocks,
make_forwarder_block, tidy_fallthru_edge, tidy_fallthru_edges):
Declare.
(cfg_layout_rtl_cfg_hooks): Declare.
* cfgloop.c (update_latch_info, mfb_keep_just, mfb_keep_nonlatch):
New functions.
(canonicalize_loop_headers): Use new semantics of make_forwarder_block.
(redirect_edge_with_latch_update): Removed.
(make_forwarder_block): Moved to cfghooks.c, semantics changed.
* cfgloopmanip.c (remove_bbs): Do not update dominators here.
* cfgrtl.c (cfg_layout_split_block, rtl_split_block, rtl_dump_bb,
rtl_delete_block, rtl_split_block, rtl_merge_blocks,
tidy_fallthru_edge, rtl_split_edge, cfg_layout_delete_block,
cfg_layout_merge_blocks, cfg_layout_split_edge): Partly moved to
cfghooks.c.
(rtl_create_basic_block): Coding style fix.
(rtl_tidy_fallthru_edge, rtl_move_block_after,
rtl_make_forwarder_block): New functions.
(update_cfg_after_block_merging): Removed.
(rtl_cfg_hooks, cfg_layout_rtl_cfg_hooks): Fill in new entries.
* flow.c (verify_wide_reg, verify_local_live_at_start): Add argument
to dump_bb.
* ifcvt.c (merge_if_block, find_cond_trap, find_if_case_1,
find_if_case_2): Don't update dominators.
* timevar.def (TV_CFG_VERIFY): New.
* loop-unswitch.c (unswitch_loop): Don't call add_to_dominance_info.
* cfglayout.c (copy_bbs): Don't call add_to_dominance_info.
* cfgloopmanip.c (split_loop_bb): Don't update dominators.
(remove_bbs): Don't call remove_bbs.
(create_preheader): Use make_forwarder_block.
(mfb_keep_just, mfb_update_loops): New static functions.

From-SVN: r76851

15 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/basic-block.h
gcc/cfg.c
gcc/cfgcleanup.c
gcc/cfghooks.c
gcc/cfghooks.h
gcc/cfglayout.c
gcc/cfgloop.c
gcc/cfgloopmanip.c
gcc/cfgrtl.c
gcc/flow.c
gcc/ifcvt.c
gcc/loop-unswitch.c
gcc/timevar.def

index faa3c9a13762c94f50e6b74a83af8b2fa73368b1..39e5a4b520208537833269efe86dcb334b4f7633 100644 (file)
@@ -1,3 +1,66 @@
+2004-01-29  Zdenek Dvorak  <rakdver@atrey.karlin.mff.cuni.cz>
+
+       * Makefile.in (cfghooks.o): Add TIMEVAR_H and toplev.h dependency.
+       * basic-block.h (tidy_fallthru_edge, tidy_fallthru_edges, dump_bb,
+       verify_flow_info): Declaration removed.
+       * cfg.c (verify_flow_info, dump_bb): Moved to cfghooks.c.
+       (debug_bb, debug_bb_n): Add argument to dump_bb call.
+       * cfgcleanup.c (try_simplify_condjump, try_crossjump_to_edge,
+       try_optimize_cfg, delete_unreachable_blocks): Use delete_basic_block
+       instead of delete_block.
+       * cfghooks.c: Include timevar.h and toplev.h.
+       (cfg_hooks): Define here.
+       (verify_flow_info, dump_bb): Moved from cfg.c.
+       (redirect_edge_and_branch, redirect_edge_and_branch_force,
+       split_block, split_block_after_labels, move_block_after,
+       delete_basic_block, split_edge, create_basic_block,
+       create_empty_bb, can_merge_blocks_p, merge_blocks,
+       make_forwarder_block, tidy_fallthru_edge, tidy_fallthru_edges):
+       New functions.
+       * cfghooks.h (struct cfg_hooks): Added fields name,
+       make_forwarder_block, tidy_fallthru_edge and
+       move_block_after. Changed type of verify_flow_info, dump_bb,
+       split_block fields. Renamed cfgh_split_edge and delete_block
+       fields.
+       (redirect_edge_and_branch, redirect_edge_and_branch_force,
+       split_block, delete_block, split_edge, create_basic_block,
+       can_merge_blocks_p, merge_blocks): Macros removed.
+       (cfg_hooks): Do not export.
+       (verify_flow_info, dump_bb, redirect_edge_and_branch,
+       redirect_edge_and_branch_force, split_block, split_block_after_labels,
+       move_block_after, delete_basic_block, split_edge, create_basic_block,
+       create_empty_bb, can_merge_blocks_p, merge_blocks,
+       make_forwarder_block, tidy_fallthru_edge, tidy_fallthru_edges):
+       Declare.
+       (cfg_layout_rtl_cfg_hooks): Declare.
+       * cfgloop.c (update_latch_info, mfb_keep_just, mfb_keep_nonlatch):
+       New functions.
+       (canonicalize_loop_headers): Use new semantics of make_forwarder_block.
+       (redirect_edge_with_latch_update): Removed.
+       (make_forwarder_block): Moved to cfghooks.c, semantics changed.
+       * cfgloopmanip.c (remove_bbs): Do not update dominators here.
+       * cfgrtl.c (cfg_layout_split_block, rtl_split_block, rtl_dump_bb,
+       rtl_delete_block, rtl_split_block, rtl_merge_blocks,
+       tidy_fallthru_edge, rtl_split_edge, cfg_layout_delete_block,
+       cfg_layout_merge_blocks, cfg_layout_split_edge): Partly moved to
+       cfghooks.c.
+       (rtl_create_basic_block): Coding style fix.
+       (rtl_tidy_fallthru_edge, rtl_move_block_after,
+       rtl_make_forwarder_block): New functions.
+       (update_cfg_after_block_merging): Removed.
+       (rtl_cfg_hooks, cfg_layout_rtl_cfg_hooks): Fill in new entries.
+       * flow.c (verify_wide_reg, verify_local_live_at_start): Add argument
+       to dump_bb.
+       * ifcvt.c (merge_if_block, find_cond_trap, find_if_case_1,
+       find_if_case_2): Don't update dominators.
+       * timevar.def (TV_CFG_VERIFY): New.
+       * loop-unswitch.c (unswitch_loop): Don't call add_to_dominance_info.
+       * cfglayout.c (copy_bbs): Don't call add_to_dominance_info.
+       * cfgloopmanip.c (split_loop_bb): Don't update dominators.
+       (remove_bbs): Don't call remove_bbs.
+       (create_preheader): Use make_forwarder_block.
+       (mfb_keep_just, mfb_update_loops): New static functions.
+
 2004-01-29  Kazu Hirata  <kazu@cs.umass.edu>
 
        * config/avr/avr.h: Remove target-independent comments about
index 92916f0e2c63c5645cf0dac0934d107495390326..946b4f75b18cd6969e5be536fa5950f291dd2d33 100644 (file)
@@ -1686,7 +1686,7 @@ cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h insn-
    $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
    function.h except.h $(GGC_H) $(TM_P_H) alloc-pool.h
 cfghooks.o: cfghooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
-   $(BASIC_BLOCK_H) cfglayout.h
+   $(BASIC_BLOCK_H) cfglayout.h $(TIMEVAR_H) toplev.h
 cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \
    insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
    function.h except.h $(GGC_H) $(TM_P_H) insn-config.h $(EXPR_H)
index 10cc6351bd6826eae05f1f795f354d6664f8328b..240edfd79dfd321b0b2e609251c39f6c433ab782 100644 (file)
@@ -363,8 +363,6 @@ extern edge redirect_edge_succ_nodup (edge, basic_block);
 extern void redirect_edge_pred (edge, basic_block);
 extern basic_block create_basic_block_structure (rtx, rtx, rtx, basic_block);
 extern void clear_bb_flags (void);
-extern void tidy_fallthru_edge (edge, basic_block, basic_block);
-extern void tidy_fallthru_edges (void);
 extern void flow_reverse_top_sort_order_compute (int *);
 extern int flow_depth_first_order_compute (int *, int *);
 extern void flow_preorder_transversal_compute (int *);
@@ -537,7 +535,6 @@ extern bool probably_never_executed_bb_p (basic_block);
 
 /* In flow.c */
 extern void init_flow (void);
-extern void dump_bb (basic_block, FILE *);
 extern void debug_bb (basic_block);
 extern basic_block debug_bb_n (int);
 extern void dump_regset (regset, FILE *);
@@ -570,11 +567,6 @@ extern void alloc_aux_for_edges (int);
 extern void clear_aux_for_edges (void);
 extern void free_aux_for_edges (void);
 
-/* This function is always defined so it can be called from the
-   debugger, and it is declared extern so we don't get warnings about
-   it being unused.  */
-extern void verify_flow_info (void);
-
 typedef struct conflict_graph_def *conflict_graph;
 
 /* Callback function when enumerating conflicts.  The arguments are
index 8042585366604e3d8790748ea0fd1e684ef2f1bb..ff3f367913678045160983eb988011d67bb644d7 100644 (file)
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -810,185 +810,16 @@ free_aux_for_edges (void)
   clear_aux_for_edges ();
 }
 
-/* Verify the CFG consistency.
-
-   Currently it does following checks edge and basic block list correctness
-   and calls into IL dependent checking then.  */
-void
-verify_flow_info (void)
-{
-  size_t *edge_checksum;
-  int num_bb_notes, err = 0;
-  basic_block bb, last_bb_seen;
-  basic_block *last_visited;
-
-  last_visited = xcalloc (last_basic_block + 2, sizeof (basic_block));
-  edge_checksum = xcalloc (last_basic_block + 2, sizeof (size_t));
-
-  /* Check bb chain & numbers.  */
-  last_bb_seen = ENTRY_BLOCK_PTR;
-  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb, NULL, next_bb)
-    {
-      if (bb != EXIT_BLOCK_PTR
-         && bb != BASIC_BLOCK (bb->index))
-       {
-         error ("bb %d on wrong place", bb->index);
-         err = 1;
-       }
-
-      if (bb->prev_bb != last_bb_seen)
-       {
-         error ("prev_bb of %d should be %d, not %d",
-                bb->index, last_bb_seen->index, bb->prev_bb->index);
-         err = 1;
-       }
-
-      last_bb_seen = bb;
-    }
-
-  /* Now check the basic blocks (boundaries etc.) */
-  FOR_EACH_BB_REVERSE (bb)
-    {
-      int n_fallthru = 0;
-      edge e;
-
-      if (bb->count < 0)
-       {
-         error ("verify_flow_info: Wrong count of block %i %i",
-                bb->index, (int)bb->count);
-         err = 1;
-       }
-      if (bb->frequency < 0)
-       {
-         error ("verify_flow_info: Wrong frequency of block %i %i",
-                bb->index, bb->frequency);
-         err = 1;
-       }
-      for (e = bb->succ; e; e = e->succ_next)
-       {
-         if (last_visited [e->dest->index + 2] == bb)
-           {
-             error ("verify_flow_info: Duplicate edge %i->%i",
-                    e->src->index, e->dest->index);
-             err = 1;
-           }
-         if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
-           {
-             error ("verify_flow_info: Wrong probability of edge %i->%i %i",
-                    e->src->index, e->dest->index, e->probability);
-             err = 1;
-           }
-         if (e->count < 0)
-           {
-             error ("verify_flow_info: Wrong count of edge %i->%i %i",
-                    e->src->index, e->dest->index, (int)e->count);
-             err = 1;
-           }
-
-         last_visited [e->dest->index + 2] = bb;
-
-         if (e->flags & EDGE_FALLTHRU)
-           n_fallthru++;
-
-         if (e->src != bb)
-           {
-             error ("verify_flow_info: Basic block %d succ edge is corrupted",
-                    bb->index);
-             fprintf (stderr, "Predecessor: ");
-             dump_edge_info (stderr, e, 0);
-             fprintf (stderr, "\nSuccessor: ");
-             dump_edge_info (stderr, e, 1);
-             fprintf (stderr, "\n");
-             err = 1;
-           }
-
-         edge_checksum[e->dest->index + 2] += (size_t) e;
-       }
-      if (n_fallthru > 1)
-       {
-         error ("Wrong amount of branch edges after unconditional jump %i", bb->index);
-         err = 1;
-       }
-
-      for (e = bb->pred; e; e = e->pred_next)
-       {
-         if (e->dest != bb)
-           {
-             error ("basic block %d pred edge is corrupted", bb->index);
-             fputs ("Predecessor: ", stderr);
-             dump_edge_info (stderr, e, 0);
-             fputs ("\nSuccessor: ", stderr);
-             dump_edge_info (stderr, e, 1);
-             fputc ('\n', stderr);
-             err = 1;
-           }
-         edge_checksum[e->dest->index + 2] -= (size_t) e;
-       }
-    }
-
-  /* Complete edge checksumming for ENTRY and EXIT.  */
-  {
-    edge e;
-
-    for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next)
-      edge_checksum[e->dest->index + 2] += (size_t) e;
-
-    for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
-      edge_checksum[e->dest->index + 2] -= (size_t) e;
-  }
-
-  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
-    if (edge_checksum[bb->index + 2])
-      {
-       error ("basic block %i edge lists are corrupted", bb->index);
-       err = 1;
-      }
-
-  num_bb_notes = 0;
-  last_bb_seen = ENTRY_BLOCK_PTR;
-
-  /* Clean up.  */
-  free (last_visited);
-  free (edge_checksum);
-  err |= cfg_hooks->cfgh_verify_flow_info ();
-  if (err)
-    internal_error ("verify_flow_info failed");
-}
-
-/* Print out one basic block with live information at start and end.  */
-
-void
-dump_bb (basic_block bb, FILE *outf)
-{
-  edge e;
-
-  fprintf (outf, ";; Basic block %d, loop depth %d, count ",
-          bb->index, bb->loop_depth);
-  fprintf (outf, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count);
-  putc ('\n', outf);
-  fputs (";; Predecessors: ", outf);
-  for (e = bb->pred; e; e = e->pred_next)
-    dump_edge_info (outf, e, 0);
-  putc ('\n', outf);
-
-  cfg_hooks->dump_bb (bb, outf);
-
-  fputs (";; Successors: ", outf);
-  for (e = bb->succ; e; e = e->succ_next)
-    dump_edge_info (outf, e, 1);
-  putc ('\n', outf);
-}
-
 void
 debug_bb (basic_block bb)
 {
-  dump_bb (bb, stderr);
+  dump_bb (bb, stderr, 0);
 }
 
 basic_block
 debug_bb_n (int n)
 {
   basic_block bb = BASIC_BLOCK (n);
-  dump_bb (bb, stderr);
+  dump_bb (bb, stderr, 0);
   return bb;
 }
index 52d58196d85b3b20e0103ddbae0539de424b7caa..a886e832bb5bb71f33d357a1c85c17adbb423833 100644 (file)
@@ -194,8 +194,8 @@ try_simplify_condjump (basic_block cbranch_block)
        }
     }
   /* Delete the block with the unconditional jump, and clean up the mess.  */
-  delete_block (jump_block);
-  tidy_fallthru_edge (cbranch_jump_edge, cbranch_block, cbranch_dest_block);
+  delete_basic_block (jump_block);
+  tidy_fallthru_edge (cbranch_jump_edge);
 
   return true;
 }
@@ -1530,7 +1530,7 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
   to_remove = redirect_from->succ->dest;
 
   redirect_edge_and_branch_force (redirect_from->succ, redirect_to);
-  delete_block (to_remove);
+  delete_basic_block (to_remove);
 
   update_forwarder_flag (redirect_from);
 
@@ -1694,7 +1694,7 @@ try_optimize_cfg (int mode)
                    fprintf (rtl_dump_file, "Deleting block %i.\n",
                             b->index);
 
-                 delete_block (b);
+                 delete_basic_block (b);
                  if (!(mode & CLEANUP_CFGLAYOUT))
                    changed = true;
                  b = c;
@@ -1755,7 +1755,7 @@ try_optimize_cfg (int mode)
 
                  c = b->prev_bb == ENTRY_BLOCK_PTR ? b->next_bb : b->prev_bb;
                  redirect_edge_succ_nodup (b->pred, b->succ->dest);
-                 delete_block (b);
+                 delete_basic_block (b);
                  changed = true;
                  b = c;
                }
@@ -1873,7 +1873,7 @@ delete_unreachable_blocks (void)
 
       if (!(b->flags & BB_REACHABLE))
        {
-         delete_block (b);
+         delete_basic_block (b);
          changed = true;
        }
     }
index 525289c04f8413ac6901de73280594735a57b1e0..fd361c5fc85d65ce9fae611a29e8b247678d77a7 100644 (file)
@@ -26,12 +26,11 @@ Boston, MA 02111-1307, USA.  */
 #include "tree.h"
 #include "rtl.h"
 #include "basic-block.h"
-
-extern struct cfg_hooks rtl_cfg_hooks;
-extern struct cfg_hooks cfg_layout_rtl_cfg_hooks;
+#include "timevar.h"
+#include "toplev.h"
 
 /* A pointer to one of the hooks containers.  */
-struct cfg_hooks *cfg_hooks;
+static struct cfg_hooks *cfg_hooks;
 
 /* Initialization of functions specific to the rtl IR.  */
 void
@@ -46,3 +45,532 @@ cfg_layout_rtl_register_cfg_hooks (void)
 {
   cfg_hooks = &cfg_layout_rtl_cfg_hooks;
 }
+
+/* Verify the CFG consistency.
+
+   Currently it does following: checks edge and basic block list correctness
+   and calls into IL dependent checking then.  */
+
+void
+verify_flow_info (void)
+{
+  size_t *edge_checksum;
+  int num_bb_notes, err = 0;
+  basic_block bb, last_bb_seen;
+  basic_block *last_visited;
+
+  timevar_push (TV_CFG_VERIFY);
+  last_visited = xcalloc (last_basic_block + 2, sizeof (basic_block));
+  edge_checksum = xcalloc (last_basic_block + 2, sizeof (size_t));
+
+  /* Check bb chain & numbers.  */
+  last_bb_seen = ENTRY_BLOCK_PTR;
+  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb, NULL, next_bb)
+    {
+      if (bb != EXIT_BLOCK_PTR
+         && bb != BASIC_BLOCK (bb->index))
+       {
+         error ("bb %d on wrong place", bb->index);
+         err = 1;
+       }
+
+      if (bb->prev_bb != last_bb_seen)
+       {
+         error ("prev_bb of %d should be %d, not %d",
+                bb->index, last_bb_seen->index, bb->prev_bb->index);
+         err = 1;
+       }
+
+      last_bb_seen = bb;
+    }
+
+  /* Now check the basic blocks (boundaries etc.) */
+  FOR_EACH_BB_REVERSE (bb)
+    {
+      int n_fallthru = 0;
+      edge e;
+
+      if (bb->count < 0)
+       {
+         error ("verify_flow_info: Wrong count of block %i %i",
+                bb->index, (int)bb->count);
+         err = 1;
+       }
+      if (bb->frequency < 0)
+       {
+         error ("verify_flow_info: Wrong frequency of block %i %i",
+                bb->index, bb->frequency);
+         err = 1;
+       }
+      for (e = bb->succ; e; e = e->succ_next)
+       {
+         if (last_visited [e->dest->index + 2] == bb)
+           {
+             error ("verify_flow_info: Duplicate edge %i->%i",
+                    e->src->index, e->dest->index);
+             err = 1;
+           }
+         if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
+           {
+             error ("verify_flow_info: Wrong probability of edge %i->%i %i",
+                    e->src->index, e->dest->index, e->probability);
+             err = 1;
+           }
+         if (e->count < 0)
+           {
+             error ("verify_flow_info: Wrong count of edge %i->%i %i",
+                    e->src->index, e->dest->index, (int)e->count);
+             err = 1;
+           }
+
+         last_visited [e->dest->index + 2] = bb;
+
+         if (e->flags & EDGE_FALLTHRU)
+           n_fallthru++;
+
+         if (e->src != bb)
+           {
+             error ("verify_flow_info: Basic block %d succ edge is corrupted",
+                    bb->index);
+             fprintf (stderr, "Predecessor: ");
+             dump_edge_info (stderr, e, 0);
+             fprintf (stderr, "\nSuccessor: ");
+             dump_edge_info (stderr, e, 1);
+             fprintf (stderr, "\n");
+             err = 1;
+           }
+
+         edge_checksum[e->dest->index + 2] += (size_t) e;
+       }
+      if (n_fallthru > 1)
+       {
+         error ("Wrong amount of branch edges after unconditional jump %i", bb->index);
+         err = 1;
+       }
+
+      for (e = bb->pred; e; e = e->pred_next)
+       {
+         if (e->dest != bb)
+           {
+             error ("basic block %d pred edge is corrupted", bb->index);
+             fputs ("Predecessor: ", stderr);
+             dump_edge_info (stderr, e, 0);
+             fputs ("\nSuccessor: ", stderr);
+             dump_edge_info (stderr, e, 1);
+             fputc ('\n', stderr);
+             err = 1;
+           }
+         edge_checksum[e->dest->index + 2] -= (size_t) e;
+       }
+    }
+
+  /* Complete edge checksumming for ENTRY and EXIT.  */
+  {
+    edge e;
+
+    for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next)
+      edge_checksum[e->dest->index + 2] += (size_t) e;
+
+    for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
+      edge_checksum[e->dest->index + 2] -= (size_t) e;
+  }
+
+  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
+    if (edge_checksum[bb->index + 2])
+      {
+       error ("basic block %i edge lists are corrupted", bb->index);
+       err = 1;
+      }
+
+  num_bb_notes = 0;
+  last_bb_seen = ENTRY_BLOCK_PTR;
+
+  /* Clean up.  */
+  free (last_visited);
+  free (edge_checksum);
+
+  if (cfg_hooks->verify_flow_info)
+    err |= cfg_hooks->verify_flow_info ();
+  if (err)
+    internal_error ("verify_flow_info failed");
+  timevar_pop (TV_CFG_VERIFY);
+}
+
+/* Print out one basic block.  This function takes care of the purely
+   graph related information.  The cfg hook for the active representation
+   should dump representation-specific information.  */
+
+void
+dump_bb (basic_block bb, FILE *outf, int indent)
+{
+  edge e;
+  char *s_indent;
+  s_indent = (char *) alloca ((size_t) indent + 1);
+  memset ((void *) s_indent, ' ', (size_t) indent);
+  s_indent[indent] = '\0';
+
+  fprintf (outf, ";;%s basic block %d, loop depth %d, count ",
+          s_indent, bb->index, bb->loop_depth);
+  fprintf (outf, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count);
+  putc ('\n', outf);
+
+  fprintf (outf, ";;%s prev block ", s_indent);
+  if (bb->prev_bb)
+    fprintf (outf, "%d, ", bb->prev_bb->index);
+  else
+    fprintf (outf, "(nil), ");
+  fprintf (outf, "next block ");
+  if (bb->next_bb)
+    fprintf (outf, "%d", bb->next_bb->index);
+  else
+    fprintf (outf, "(nil)");
+  putc ('\n', outf);
+
+  fprintf (outf, ";;%s pred:      ", s_indent);
+  for (e = bb->pred; e; e = e->pred_next)
+    dump_edge_info (outf, e, 0);
+  putc ('\n', outf);
+
+  fprintf (outf, ";;%s succ:      ", s_indent);
+  for (e = bb->succ; e; e = e->succ_next)
+    dump_edge_info (outf, e, 1);
+  putc ('\n', outf);
+
+  if (cfg_hooks->dump_bb)
+    cfg_hooks->dump_bb (bb, outf, indent);
+}
+
+/* Redirect edge E to the given basic block DEST and update underlying program
+   representation.  Returns edge representing redirected branch (that may not
+   be equivalent to E in the case of duplicate edges being removed) or NULL
+   if edge is not easily redirectable for whatever reason.  */
+
+bool
+redirect_edge_and_branch (edge e, basic_block dest)
+{
+  bool ret;
+
+  if (!cfg_hooks->redirect_edge_and_branch)
+    internal_error ("%s does not support redirect_edge_and_branch.",
+                   cfg_hooks->name);
+
+  ret = cfg_hooks->redirect_edge_and_branch (e, dest);
+
+  return ret;
+}
+
+/* Redirect the edge E to basic block DEST even if it requires creating
+   of a new basic block; then it returns the newly created basic block.
+   Aborts when redirection is impossible.  */
+
+basic_block
+redirect_edge_and_branch_force (edge e, basic_block dest)
+{
+  basic_block ret;
+
+  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);
+
+  return ret;
+}
+
+/* Splits basic block BB after the specified instruction I (but at least after
+   the labels).  If I is NULL, splits just after labels.  The newly created edge
+   is returned.  The new basic block is created just after the old one.  */
+
+edge
+split_block (basic_block bb, void *i)
+{
+  basic_block new_bb;
+
+  if (!cfg_hooks->split_block)
+    internal_error ("%s does not support split_block.", cfg_hooks->name);
+
+  new_bb = cfg_hooks->split_block (bb, i);
+  if (!new_bb)
+    return NULL;
+
+  new_bb->count = bb->count;
+  new_bb->frequency = bb->frequency;
+  new_bb->loop_depth = bb->loop_depth;
+
+  if (dom_computed[CDI_DOMINATORS] >= DOM_CONS_OK)
+    {
+      redirect_immediate_dominators (CDI_DOMINATORS, bb, new_bb);
+      set_immediate_dominator (CDI_DOMINATORS, new_bb, bb);
+    }
+
+  return make_edge (bb, new_bb, EDGE_FALLTHRU);
+}
+
+/* Splits block BB just after labels.  The newly created edge is returned.  */
+
+edge
+split_block_after_labels (basic_block bb)
+{
+  return split_block (bb, NULL);
+}
+
+/* Moves block BB immediatelly after block AFTER.  Returns false if the
+   movement was impossible.  */
+
+bool
+move_block_after (basic_block bb, basic_block after)
+{
+  bool ret;
+
+  if (!cfg_hooks->move_block_after)
+    internal_error ("%s does not support move_block_after.", cfg_hooks->name);
+
+  ret = cfg_hooks->move_block_after (bb, after);
+
+  return ret;
+}
+
+/* Deletes the basic block BB.  */
+
+void
+delete_basic_block (basic_block bb)
+{
+  if (!cfg_hooks->delete_basic_block)
+    internal_error ("%s does not support delete_basic_block.", cfg_hooks->name);
+
+  cfg_hooks->delete_basic_block (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 (bb->pred != NULL)
+    remove_edge (bb->pred);
+  while (bb->succ != NULL)
+    remove_edge (bb->succ);
+
+  bb->pred = NULL;
+  bb->succ = NULL;
+
+  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 the basic block from the array.  */
+  expunge_block (bb);
+}
+
+/* Splits edge E and returns the newly created basic block.  */
+
+basic_block
+split_edge (edge e)
+{
+  basic_block ret;
+  gcov_type count = e->count;
+  int freq = EDGE_FREQUENCY (e);
+
+  if (!cfg_hooks->split_edge)
+    internal_error ("%s does not support split_edge.", cfg_hooks->name);
+
+  ret = cfg_hooks->split_edge (e);
+  ret->count = count;
+  ret->frequency = freq;
+  ret->succ->probability = REG_BR_PROB_BASE;
+  ret->succ->count = count;
+
+  if (dom_computed[CDI_DOMINATORS])
+    set_immediate_dominator (CDI_DOMINATORS, ret, ret->pred->src);
+
+  if (dom_computed[CDI_DOMINATORS] >= DOM_NO_FAST_QUERY)
+    set_immediate_dominator (CDI_DOMINATORS, ret->succ->dest,
+                            recount_dominator (CDI_DOMINATORS,
+                                               ret->succ->dest));
+
+  return ret;
+}
+
+/* Creates a new basic block just after the basic block AFTER.
+   HEAD and END are the first and the last statement belonging
+   to the block.  If both are NULL, an empty block is created.  */
+
+basic_block
+create_basic_block (void *head, void *end, basic_block after)
+{
+  basic_block ret;
+
+  if (!cfg_hooks->create_basic_block)
+    internal_error ("%s does not support create_basic_block.", cfg_hooks->name);
+
+  ret = cfg_hooks->create_basic_block (head, end, after);
+
+  if (dom_computed[CDI_DOMINATORS])
+    add_to_dominance_info (CDI_DOMINATORS, ret);
+  if (dom_computed[CDI_POST_DOMINATORS])
+    add_to_dominance_info (CDI_POST_DOMINATORS, ret);
+
+  return ret;
+}
+
+/* Creates an empty basic block just after basic block AFTER.  */
+
+basic_block
+create_empty_bb (basic_block after)
+{
+  return create_basic_block (NULL, NULL, after);
+}
+
+/* Checks whether we may merge blocks BB1 and BB2.  */
+
+bool
+can_merge_blocks_p (basic_block bb1, basic_block bb2)
+{
+  bool ret;
+
+  if (!cfg_hooks->can_merge_blocks_p)
+    internal_error ("%s does not support can_merge_blocks_p.", cfg_hooks->name);
+
+  ret = cfg_hooks->can_merge_blocks_p (bb1, bb2);
+
+  return ret;
+}
+
+/* Merges basic block B into basic block A.  */
+
+void
+merge_blocks (basic_block a, basic_block b)
+{
+  edge e;
+
+  if (!cfg_hooks->merge_blocks)
+    internal_error ("%s does not support merge_blocks.", cfg_hooks->name);
+
+  cfg_hooks->merge_blocks (a, b);
+
+  /* Normally there should only be one successor of A and that is B, but
+     partway though the merge of blocks for conditional_execution we'll
+     be merging a TEST block with THEN and ELSE successors.  Free the
+     whole lot of them and hope the caller knows what they're doing.  */
+  while (a->succ)
+    remove_edge (a->succ);
+
+  /* Adjust the edges out of B for the new owner.  */
+  for (e = b->succ; e; e = e->succ_next)
+    e->src = a;
+  a->succ = b->succ;
+  a->flags |= b->flags;
+
+  /* B hasn't quite yet ceased to exist.  Attempt to prevent mishap.  */
+  b->pred = b->succ = NULL;
+  a->global_live_at_end = b->global_live_at_end;
+
+  if (dom_computed[CDI_DOMINATORS])
+    redirect_immediate_dominators (CDI_DOMINATORS, b, a);
+
+  if (dom_computed[CDI_DOMINATORS])
+    delete_from_dominance_info (CDI_DOMINATORS, b);
+  if (dom_computed[CDI_POST_DOMINATORS])
+    delete_from_dominance_info (CDI_POST_DOMINATORS, b);
+
+  expunge_block (b);
+}
+
+/* Split BB into entry part and the rest (the rest is the newly created block).
+   Redirect those edges for that REDIRECT_EDGE_P returns true to the entry
+   part.  Returns the edge connecting the entry part to the rest.  */
+
+edge
+make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge),
+                     void (*new_bb_cbk) (basic_block))
+{
+  edge e, next_e, fallthru;
+  basic_block dummy, jump;
+
+  if (!cfg_hooks->make_forwarder_block)
+    internal_error ("%s does not support make_forwarder_block.",
+                   cfg_hooks->name);
+
+  fallthru = split_block_after_labels (bb);
+  dummy = fallthru->src;
+  bb = fallthru->dest;
+
+  /* Redirect back edges we want to keep.  */
+  for (e = dummy->pred; e; e = next_e)
+    {
+      next_e = e->pred_next;
+      if (redirect_edge_p (e))
+       continue;
+
+      dummy->frequency -= EDGE_FREQUENCY (e);
+      dummy->count -= e->count;
+      if (dummy->frequency < 0)
+       dummy->frequency = 0;
+      if (dummy->count < 0)
+       dummy->count = 0;
+
+      jump = redirect_edge_and_branch_force (e, bb);
+      if (jump)
+       new_bb_cbk (jump);
+    }
+
+  if (dom_computed[CDI_DOMINATORS] >= DOM_CONS_OK)
+    {
+      basic_block doms_to_fix[2];
+
+      doms_to_fix[0] = dummy;
+      doms_to_fix[1] = bb;
+      iterate_fix_dominators (CDI_DOMINATORS, doms_to_fix, 2);
+    }
+
+  cfg_hooks->make_forwarder_block (fallthru);
+
+  return fallthru;
+}
+
+void
+tidy_fallthru_edge (edge e)
+{
+  if (cfg_hooks->tidy_fallthru_edge)
+    cfg_hooks->tidy_fallthru_edge (e);
+}
+
+/* Fix up edges that now fall through, or rather should now fall through
+   but previously required a jump around now deleted blocks.  Simplify
+   the search by only examining blocks numerically adjacent, since this
+   is how find_basic_blocks created them.  */
+
+void
+tidy_fallthru_edges (void)
+{
+  basic_block b, c;
+
+  if (!cfg_hooks->tidy_fallthru_edge)
+    return;
+
+  if (ENTRY_BLOCK_PTR->next_bb == EXIT_BLOCK_PTR)
+    return;
+
+  FOR_BB_BETWEEN (b, ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR->prev_bb, next_bb)
+    {
+      edge s;
+
+      c = b->next_bb;
+
+      /* We care about simple conditional or unconditional jumps with
+        a single successor.
+
+        If we had a conditional branch to the next instruction when
+        find_basic_blocks was called, then there will only be one
+        out edge for the block which ended with the conditional
+        branch (since we do not create duplicate edges).
+
+        Furthermore, the edge will be marked as a fallthru because we
+        merge the flags for the duplicate edges.  So we do not want to
+        check that the edge is not a FALLTHRU edge.  */
+
+      if ((s = b->succ) != NULL
+         && ! (s->flags & EDGE_COMPLEX)
+         && s->succ_next == NULL
+         && s->dest == c)
+       tidy_fallthru_edge (s);
+    }
+}
index 5ef3b1f5480feeb1a2f19a16e17208dc38ab5c7d..4c2d0bf37bb1f1b564d57bd53fc72635f962802e 100644 (file)
@@ -24,10 +24,12 @@ Boston, MA 02111-1307, USA.  */
 
 struct cfg_hooks
 {
-  /* Debugging.  Do not use macros to hook these so they can be called from
-     debugger!  */
-  int (*cfgh_verify_flow_info) (void);
-  void (*dump_bb) (basic_block, FILE *);
+  /* Name of the corresponding ir.  */
+  const char *name;
+
+  /* Debugging.  */
+  int (*verify_flow_info) (void);
+  void (*dump_bb) (basic_block, FILE *, int);
 
   /* Basic CFG manipulation.  */
 
@@ -44,11 +46,15 @@ struct cfg_hooks
      on abnormal edge.  */
   basic_block (*redirect_edge_and_branch_force) (edge, basic_block);
 
-  /* Remove given basic block and all edges possibly pointing into it.  */
-  void (*delete_block) (basic_block);
+  /* Remove statements corresponding to a given basic block.  */
+  void (*delete_basic_block) (basic_block);
+
+  /* Creates a new basic block just after basic block B by splitting
+     everything after specified instruction I.  */
+  basic_block (*split_block) (basic_block b, void * i);
 
-  /* Split basic block B after specified instruction I.  */
-  edge (*split_block) (basic_block b, void * i);
+  /* Move block B immediately after block A.  */
+  bool (*move_block_after) (basic_block b, basic_block a);
 
   /* Return true when blocks A and B can be merged into single basic block.  */
   bool (*can_merge_blocks_p) (basic_block a, basic_block b);
@@ -58,23 +64,34 @@ struct cfg_hooks
 
   /* Higher level functions representable by primitive operations above if
      we didn't have some oddities in RTL and Tree representations.  */
-  basic_block (*cfgh_split_edge) (edge);
+  basic_block (*split_edge) (edge);
+  void (*make_forwarder_block) (edge);
+
+  /* Tries to make the edge fallthru.  */
+  void (*tidy_fallthru_edge) (edge);
 };
 
-#define redirect_edge_and_branch(e,b)        cfg_hooks->redirect_edge_and_branch (e,b)
-#define redirect_edge_and_branch_force(e,b)  cfg_hooks->redirect_edge_and_branch_force (e,b)
-#define split_block(e,i)                     cfg_hooks->split_block (e,i)
-#define delete_block(b)                             cfg_hooks->delete_block (b)
-#define split_edge(e)                        cfg_hooks->cfgh_split_edge (e)
-#define create_basic_block(h,e,a)            cfg_hooks->create_basic_block (h,e,a)
-#define can_merge_blocks_p(a,b)                     cfg_hooks->can_merge_blocks_p (a,b)
-#define merge_blocks(a,b)                   cfg_hooks->merge_blocks (a,b)
+extern void verify_flow_info (void);
+extern void dump_bb (basic_block, FILE *, int);
+extern bool redirect_edge_and_branch (edge, basic_block);
+extern basic_block redirect_edge_and_branch_force (edge, basic_block);
+extern edge split_block (basic_block, void *);
+extern edge split_block_after_labels (basic_block);
+extern bool move_block_after (basic_block, basic_block);
+extern void delete_basic_block (basic_block);
+extern basic_block split_edge (edge);
+extern basic_block create_basic_block (void *, void *, basic_block);
+extern basic_block create_empty_bb (basic_block);
+extern bool can_merge_blocks_p (basic_block, basic_block);
+extern void merge_blocks (basic_block, basic_block);
+extern edge make_forwarder_block (basic_block, bool (*)(edge),
+                                 void (*) (basic_block));
+extern void tidy_fallthru_edge (edge);
+extern void tidy_fallthru_edges (void);
 
 /* Hooks containers.  */
 extern struct cfg_hooks rtl_cfg_hooks;
-
-/* A pointer to one of the hooks containers.  */
-extern struct cfg_hooks *cfg_hooks;
+extern struct cfg_hooks cfg_layout_rtl_cfg_hooks;
 
 /* Declarations.  */
 extern void rtl_register_cfg_hooks (void);
index 15ec054745122fcbf5bcd3a8b055ffacfab701c6..bdee86757684d8232377b47c83c42581593d5d5e 100644 (file)
@@ -1268,7 +1268,6 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
       bb->rbi->duplicated = 1;
       /* Add to loop.  */
       add_bb_to_loop (new_bb, bb->loop_father->copy);
-      add_to_dominance_info (CDI_DOMINATORS, new_bb);
       /* Possibly set header.  */
       if (bb->loop_father->header == bb && bb->loop_father != base)
        new_bb->loop_father->header = new_bb;
index 69097c009a9cfd70bdfaba29f9954cbc6a9c1341..6fa8b17706ae6a7e40d69c6d6b23a9b05cfb122d 100644 (file)
@@ -33,6 +33,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
    considered to belong to inner loop with same header.  */
 #define HEAVY_EDGE_RATIO 8
 
+#define HEADER_BLOCK(B) (* (int *) (B)->aux)
+#define LATCH_EDGE(E) (*(int *) (E)->aux)
+
 static void flow_loops_cfg_dump (const struct loops *, FILE *);
 static void flow_loop_entry_edges_find (struct loop *);
 static void flow_loop_exit_edges_find (struct loop *);
@@ -42,10 +45,8 @@ static basic_block flow_loop_pre_header_find (basic_block);
 static int flow_loop_level_compute (struct loop *);
 static int flow_loops_level_compute (struct loops *);
 static void establish_preds (struct loop *);
-static basic_block make_forwarder_block (basic_block, int, int, edge, int);
 static void canonicalize_loop_headers (void);
 static bool glb_enum_p (basic_block, void *);
-static void redirect_edge_with_latch_update (edge, basic_block);
 \f
 /* Dump loop related CFG information.  */
 
@@ -547,78 +548,41 @@ flow_loop_scan (struct loop *loop, int flags)
   return 1;
 }
 
-#define HEADER_BLOCK(B) (* (int *) (B)->aux)
-#define LATCH_EDGE(E) (*(int *) (E)->aux)
+/* A callback to update latch and header info for basic block JUMP created
+   by redirecting an edge.  */
 
-/* Redirect edge and update latch and header info.  */
 static void
-redirect_edge_with_latch_update (edge e, basic_block to)
+update_latch_info (basic_block jump)
 {
-  basic_block jump;
-
-  jump = redirect_edge_and_branch_force (e, to);
-  if (jump)
-    {
-      alloc_aux_for_block (jump, sizeof (int));
-      HEADER_BLOCK (jump) = 0;
-      alloc_aux_for_edge (jump->pred, sizeof (int));
-      LATCH_EDGE (jump->succ) = LATCH_EDGE (e);
-      LATCH_EDGE (jump->pred) = 0;
-    }
+  alloc_aux_for_block (jump, sizeof (int));
+  HEADER_BLOCK (jump) = 0;
+  alloc_aux_for_edge (jump->pred, sizeof (int));
+  LATCH_EDGE (jump->pred) = 0;
 }
 
-/* Split BB into entry part and rest; if REDIRECT_LATCH, redirect edges
-   marked as latch into entry part, analogically for REDIRECT_NONLATCH.
-   In both of these cases, ignore edge EXCEPT.  If CONN_LATCH, set edge
-   between created entry part and BB as latch one.  Return created entry
-   part.  */
+/* A callback for make_forwarder block, to redirect all edges except for
+   MFB_KJ_EDGE to the entry part.  E is the edge for that we should decide
+   whether to redirect it.  */
 
-static basic_block
-make_forwarder_block (basic_block bb, int redirect_latch, int redirect_nonlatch, edge except, int conn_latch)
+static edge mfb_kj_edge;
+static bool
+mfb_keep_just (edge e)
 {
-  edge e, next_e, fallthru;
-  basic_block dummy;
-  rtx insn;
-
-  insn = PREV_INSN (first_insn_after_basic_block_note (bb));
-
-  /* For empty block split_block will return NULL.  */
-  if (BB_END (bb) == insn)
-    emit_note_after (NOTE_INSN_DELETED, insn);
-
-  fallthru = split_block (bb, insn);
-  dummy = fallthru->src;
-  bb = fallthru->dest;
-
-  bb->aux = xmalloc (sizeof (int));
-  HEADER_BLOCK (dummy) = 0;
-  HEADER_BLOCK (bb) = 1;
-
-  /* Redirect back edges we want to keep.  */
-  for (e = dummy->pred; e; e = next_e)
-    {
-      next_e = e->pred_next;
-      if (e == except
-         || !((redirect_latch && LATCH_EDGE (e))
-              || (redirect_nonlatch && !LATCH_EDGE (e))))
-       {
-         dummy->frequency -= EDGE_FREQUENCY (e);
-         dummy->count -= e->count;
-         if (dummy->frequency < 0)
-           dummy->frequency = 0;
-         if (dummy->count < 0)
-           dummy->count = 0;
-         redirect_edge_with_latch_update (e, bb);
-       }
-    }
+  return e != mfb_kj_edge;
+}
 
-  alloc_aux_for_edge (fallthru, sizeof (int));
-  LATCH_EDGE (fallthru) = conn_latch;
+/* A callback for make_forwarder block, to redirect the latch edges into an
+   entry part.  E is the edge for that we should decide whether to redirect
+   it.  */
 
-  return dummy;
+static bool
+mfb_keep_nonlatch (edge e)
+{
+  return LATCH_EDGE (e);
 }
 
 /* Takes care of merging natural loops with shared headers.  */
+
 static void
 canonicalize_loop_headers (void)
 {
@@ -675,19 +639,10 @@ canonicalize_loop_headers (void)
 
   FOR_EACH_BB (header)
     {
-      int num_latch;
-      int want_join_latch;
       int max_freq, is_heavy;
-      edge heavy;
+      edge heavy, tmp_edge;
 
-      if (!HEADER_BLOCK (header))
-       continue;
-
-      num_latch = HEADER_BLOCK (header);
-
-      want_join_latch = (num_latch > 1);
-
-      if (!want_join_latch)
+      if (HEADER_BLOCK (header) <= 1)
        continue;
 
       /* Find a heavy edge.  */
@@ -713,13 +668,28 @@ canonicalize_loop_headers (void)
 
       if (is_heavy)
        {
-         basic_block new_header =
-           make_forwarder_block (header, true, true, heavy, 0);
-         if (num_latch > 2)
-           make_forwarder_block (new_header, true, false, NULL, 1);
+         /* Split out the heavy edge, and create inner loop for it.  */
+         mfb_kj_edge = heavy;
+         tmp_edge = make_forwarder_block (header, mfb_keep_just,
+                                          update_latch_info);
+         alloc_aux_for_block (tmp_edge->dest, sizeof (int));
+         HEADER_BLOCK (tmp_edge->dest) = 1;
+         alloc_aux_for_edge (tmp_edge, sizeof (int));
+         LATCH_EDGE (tmp_edge) = 0;
+         HEADER_BLOCK (header)--;
+       }
+
+      if (HEADER_BLOCK (header) > 1)
+       {
+         /* Create a new latch block.  */
+         tmp_edge = make_forwarder_block (header, mfb_keep_nonlatch,
+                                          update_latch_info);
+         alloc_aux_for_block (tmp_edge->dest, sizeof (int));
+         HEADER_BLOCK (tmp_edge->src) = 0;
+         HEADER_BLOCK (tmp_edge->dest) = 1;
+         alloc_aux_for_edge (tmp_edge, sizeof (int));
+         LATCH_EDGE (tmp_edge) = 1;
        }
-      else
-       make_forwarder_block (header, true, false, NULL, 1);
     }
 
   free_aux_for_blocks ();
index 86af4a2536b7027088a29a2c9aaa0ae4f94bc367..2c60659fec8b8e91cd2045a8af78fb52fa2e0a5e 100644 (file)
@@ -63,11 +63,6 @@ split_loop_bb (basic_block bb, rtx insn)
   /* Add dest to loop.  */
   add_bb_to_loop (e->dest, e->src->loop_father);
 
-  /* Fix dominators.  */
-  add_to_dominance_info (CDI_DOMINATORS, e->dest);
-  redirect_immediate_dominators (CDI_DOMINATORS, e->src, e->dest);
-  set_immediate_dominator (CDI_DOMINATORS, e->dest, e->src);
-
   return e;
 }
 
@@ -88,8 +83,7 @@ remove_bbs (basic_block *bbs, int nbbs)
   for (i = 0; i < nbbs; i++)
     {
       remove_bb_from_loops (bbs[i]);
-      delete_from_dominance_info (CDI_DOMINATORS, bbs[i]);
-      delete_block (bbs[i]);
+      delete_basic_block (bbs[i]);
     }
 }
 
@@ -1070,19 +1064,45 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
   return true;
 }
 
+/* A callback for make_forwarder block, to redirect all edges except for
+   MFB_KJ_EDGE to the entry part.  E is the edge for that we should decide
+   whether to redirect it.  */
+
+static edge mfb_kj_edge;
+static bool
+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 = jump->succ->dest->loop_father;
+
+  if (dom_computed[CDI_DOMINATORS])
+    set_immediate_dominator (CDI_DOMINATORS, jump, jump->pred->src);
+  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.
-   The function also updates dominators stored in DOM.  */
+   The function also updates dominators.  */
+
 static basic_block
 create_preheader (struct loop *loop, int flags)
 {
   edge e, fallthru;
   basic_block dummy;
-  basic_block jump, src = 0;
   struct loop *cloop, *ploop;
   int nentry = 0;
-  rtx insn;
+  bool irred = false;
 
   cloop = loop->outer;
 
@@ -1090,6 +1110,7 @@ create_preheader (struct loop *loop, int flags)
     {
       if (e->src == loop->latch)
        continue;
+      irred |= (e->flags & EDGE_IRREDUCIBLE_LOOP) != 0;
       nentry++;
     }
   if (!nentry)
@@ -1102,17 +1123,9 @@ create_preheader (struct loop *loop, int flags)
        return NULL;
     }
 
-  insn = first_insn_after_basic_block_note (loop->header);
-  if (insn)
-    insn = PREV_INSN (insn);
-  else
-    insn = get_last_insn ();
-  if (insn == BB_END (loop->header))
-    {
-      /* Split_block would not split block after its end.  */
-      emit_note_after (NOTE_INSN_DELETED, insn);
-    }
-  fallthru = split_block (loop->header, insn);
+  mfb_kj_edge = loop_latch_edge (loop);
+  fallthru = make_forwarder_block (loop->header, mfb_keep_just,
+                                  mfb_update_loops);
   dummy = fallthru->src;
   loop->header = fallthru->dest;
 
@@ -1122,35 +1135,22 @@ create_preheader (struct loop *loop, int flags)
     if (ploop->latch == dummy)
       ploop->latch = fallthru->dest;
 
-  add_to_dominance_info (CDI_DOMINATORS, fallthru->dest);
-
-  /* Redirect edges.  */
+  /* Reorganize blocks so that the preheader is not stuck in the middle of the
+     loop.  */
   for (e = dummy->pred; e; e = e->pred_next)
-    {
-      src = e->src;
-      if (src == loop->latch)
-       break;
-    }
-  if (!e)
-    abort ();
+    if (e->src != loop->latch)
+      break;
+  move_block_after (dummy, e->src);
+
+  loop->header->loop_father = loop;
+  add_bb_to_loop (dummy, cloop);
 
-  dummy->frequency -= EDGE_FREQUENCY (e);
-  dummy->count -= e->count;
-  fallthru->count -= e->count;
-  jump = redirect_edge_and_branch_force (e, loop->header);
-  if (jump)
+  if (irred)
     {
-      add_to_dominance_info (CDI_DOMINATORS, jump);
-      set_immediate_dominator (CDI_DOMINATORS, jump, src);
-      add_bb_to_loop (jump, loop);
-      loop->latch = jump;
+      dummy->flags |= BB_IRREDUCIBLE_LOOP;
+      dummy->succ->flags |= EDGE_IRREDUCIBLE_LOOP;
     }
 
-  /* Update structures.  */
-  redirect_immediate_dominators (CDI_DOMINATORS, dummy, loop->header);
-  set_immediate_dominator (CDI_DOMINATORS, loop->header, dummy);
-  loop->header->loop_father = loop;
-  add_bb_to_loop (dummy, cloop);
   if (rtl_dump_file)
     fprintf (rtl_dump_file, "Created preheader block for loop %i\n",
             loop->num);
@@ -1212,7 +1212,6 @@ loop_split_edge_with (edge e, rtx insns)
   /* Create basic block for it.  */
 
   new_bb = split_edge (e);
-  add_to_dominance_info (CDI_DOMINATORS, new_bb);
   add_bb_to_loop (new_bb, loop_c);
   new_bb->flags = insns ? BB_SUPERBLOCK : 0;
 
@@ -1226,10 +1225,6 @@ loop_split_edge_with (edge e, rtx insns)
   if (insns)
     emit_insn_after (insns, BB_END (new_bb));
 
-  set_immediate_dominator (CDI_DOMINATORS, new_bb, src);
-  set_immediate_dominator (CDI_DOMINATORS, dest,
-                          recount_dominator (CDI_DOMINATORS, dest));
-
   if (dest->loop_father->latch == src)
     dest->loop_father->latch = new_bb;
 
index 70d06563ac6bf6ef2c51abd2812221a4abfa3bcc..01a5f3dbe668bccec6b7aa3505404326594702aa 100644 (file)
@@ -76,18 +76,20 @@ static rtx last_loop_beg_note (rtx);
 static bool back_edge_of_syntactic_loop_p (basic_block, basic_block);
 basic_block force_nonfallthru_and_redirect (edge, basic_block);
 static basic_block rtl_split_edge (edge);
+static bool rtl_move_block_after (basic_block, basic_block);
 static int rtl_verify_flow_info (void);
-static edge cfg_layout_split_block (basic_block, void *);
+static basic_block cfg_layout_split_block (basic_block, void *);
 static bool cfg_layout_redirect_edge_and_branch (edge, basic_block);
 static basic_block cfg_layout_redirect_edge_and_branch_force (edge, basic_block);
 static void cfg_layout_delete_block (basic_block);
 static void rtl_delete_block (basic_block);
 static basic_block rtl_redirect_edge_and_branch_force (edge, basic_block);
 static bool rtl_redirect_edge_and_branch (edge, basic_block);
-static edge rtl_split_block (basic_block, void *);
-static void rtl_dump_bb (basic_block, FILE *);
+static basic_block rtl_split_block (basic_block, void *);
+static void rtl_dump_bb (basic_block, FILE *, int);
 static int rtl_verify_flow_info_1 (void);
 static void mark_killed_regs (rtx, rtx, void *);
+static void rtl_make_forwarder_block (edge);
 \f
 /* Return true if NOTE is not one of the ones that must be kept paired,
    so that we may simply delete it.  */
@@ -337,7 +339,7 @@ rtl_create_basic_block (void *headp, void *endp, basic_block after)
   basic_block bb;
 
   /* Place the new block just after the end.  */
-  VARRAY_GROW (basic_block_info, last_basic_block+1);
+  VARRAY_GROW (basic_block_info, last_basic_block + 1);
 
   n_basic_blocks++;
 
@@ -407,19 +409,6 @@ rtl_delete_block (basic_block b)
   /* Selectively delete the entire chain.  */
   BB_HEAD (b) = NULL;
   delete_insn_chain (insn, end);
-
-  /* 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 (b->pred != NULL)
-    remove_edge (b->pred);
-  while (b->succ != NULL)
-    remove_edge (b->succ);
-
-  b->pred = NULL;
-  b->succ = NULL;
-
-  /* Remove the basic block from the array.  */
-  expunge_block (b);
 }
 \f
 /* Records the basic block struct in BLOCK_FOR_INSN for every insn.  */
@@ -470,28 +459,34 @@ update_bb_for_insn (basic_block bb)
     }
 }
 \f
-/* Split a block BB after insn INSN creating a new fallthru edge.
-   Return the new edge.  Note that to keep other parts of the compiler happy,
-   this function renumbers all the basic blocks so that the new
-   one has a number one greater than the block split.  */
+/* Creates a new basic block just after basic block B by splitting
+   everything after specified instruction I.  */
 
-static edge
+static basic_block
 rtl_split_block (basic_block bb, void *insnp)
 {
   basic_block new_bb;
-  edge new_edge;
-  edge e;
   rtx insn = insnp;
+  edge e;
 
-  /* There is no point splitting the block after its end.  */
-  if (BB_END (bb) == insn)
-    return 0;
+  if (!insn)
+    {
+      insn = first_insn_after_basic_block_note (bb);
+
+      if (insn)
+       insn = PREV_INSN (insn);
+      else
+       insn = get_last_insn ();
+    }
+
+  /* We probably should check type of the insn so that we do not create
+     inconsistent cfg.  It is checked in verify_flow_info anyway, so do not
+     bother.  */
+  if (insn == BB_END (bb))
+    emit_note_after (NOTE_INSN_DELETED, insn);
 
   /* Create the new basic block.  */
   new_bb = create_basic_block (NEXT_INSN (insn), BB_END (bb), bb);
-  new_bb->count = bb->count;
-  new_bb->frequency = bb->frequency;
-  new_bb->loop_depth = bb->loop_depth;
   BB_END (bb) = insn;
 
   /* Redirect the outgoing edges.  */
@@ -500,8 +495,6 @@ rtl_split_block (basic_block bb, void *insnp)
   for (e = new_bb->succ; e; e = e->succ_next)
     e->src = new_bb;
 
-  new_edge = make_single_succ_edge (bb, new_bb, EDGE_FALLTHRU);
-
   if (bb->global_live_at_start)
     {
       new_bb->global_live_at_start = OBSTACK_ALLOC_REG_SET (&flow_obstack);
@@ -528,34 +521,7 @@ rtl_split_block (basic_block bb, void *insnp)
 #endif
     }
 
-  return new_edge;
-}
-
-/* Assume that the code of basic block B has been merged into A.
-   Do corresponding CFG updates:  redirect edges accordingly etc.  */
-static void
-update_cfg_after_block_merging (basic_block a, basic_block b)
-{
-  edge e;
-
-  /* Normally there should only be one successor of A and that is B, but
-     partway though the merge of blocks for conditional_execution we'll
-     be merging a TEST block with THEN and ELSE successors.  Free the
-     whole lot of them and hope the caller knows what they're doing.  */
-  while (a->succ)
-    remove_edge (a->succ);
-
-  /* Adjust the edges out of B for the new owner.  */
-  for (e = b->succ; e; e = e->succ_next)
-    e->src = a;
-  a->succ = b->succ;
-  a->flags |= b->flags;
-
-  /* B hasn't quite yet ceased to exist.  Attempt to prevent mishap.  */
-  b->pred = b->succ = NULL;
-  a->global_live_at_end = b->global_live_at_end;
-
-  expunge_block (b);
+  return new_bb;
 }
 
 /* Blocks A and B are to be merged into a single block A.  The insns
@@ -625,10 +591,9 @@ rtl_merge_blocks (basic_block a, basic_block b)
   else if (GET_CODE (NEXT_INSN (a_end)) == BARRIER)
     del_first = NEXT_INSN (a_end);
 
-  update_cfg_after_block_merging (a, b);
-
   /* Delete everything marked above as well as crap that might be
      hanging out between the two blocks.  */
+  BB_HEAD (b) = NULL;
   delete_insn_chain (del_first, del_last);
 
   /* Reassociate the insns of B with A.  */
@@ -1159,10 +1124,16 @@ rtl_redirect_edge_and_branch_force (edge e, basic_block target)
 /* The given edge should potentially be a fallthru edge.  If that is in
    fact true, delete the jump and barriers that are in the way.  */
 
-void
-tidy_fallthru_edge (edge e, basic_block b, basic_block c)
+static void
+rtl_tidy_fallthru_edge (edge e)
 {
   rtx q;
+  basic_block b = e->src, c = b->next_bb;
+
+  /* If the jump insn has side effects, we can't tidy the edge.  */
+  if (GET_CODE (BB_END (b)) == JUMP_INSN
+      && !onlyjump_p (BB_END (b)))
+    return;
 
   /* ??? In a late-running flow pass, other folks may have deleted basic
      blocks by nopping out blocks, leaving multiple BARRIERs between here
@@ -1208,48 +1179,6 @@ tidy_fallthru_edge (edge e, basic_block b, basic_block c)
 
   e->flags |= EDGE_FALLTHRU;
 }
-
-/* Fix up edges that now fall through, or rather should now fall through
-   but previously required a jump around now deleted blocks.  Simplify
-   the search by only examining blocks numerically adjacent, since this
-   is how find_basic_blocks created them.  */
-
-void
-tidy_fallthru_edges (void)
-{
-  basic_block b, c;
-
-  if (ENTRY_BLOCK_PTR->next_bb == EXIT_BLOCK_PTR)
-    return;
-
-  FOR_BB_BETWEEN (b, ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR->prev_bb, next_bb)
-    {
-      edge s;
-
-      c = b->next_bb;
-
-      /* We care about simple conditional or unconditional jumps with
-        a single successor.
-
-        If we had a conditional branch to the next instruction when
-        find_basic_blocks was called, then there will only be one
-        out edge for the block which ended with the conditional
-        branch (since we do not create duplicate edges).
-
-        Furthermore, the edge will be marked as a fallthru because we
-        merge the flags for the duplicate edges.  So we do not want to
-        check that the edge is not a FALLTHRU edge.  */
-
-      if ((s = b->succ) != NULL
-         && ! (s->flags & EDGE_COMPLEX)
-         && s->succ_next == NULL
-         && s->dest == c
-         /* If the jump insn has side effects, we can't tidy the edge.  */
-         && (GET_CODE (BB_END (b)) != JUMP_INSN
-             || onlyjump_p (BB_END (b))))
-       tidy_fallthru_edge (s, b, c);
-    }
-}
 \f
 /* Helper function for split_edge.  Return true in case edge BB2 to BB1
    is back edge of syntactic loop.  */
@@ -1285,6 +1214,15 @@ back_edge_of_syntactic_loop_p (basic_block bb1, basic_block bb2)
   return count >= 0;
 }
 
+/* Should move basic block BB after basic block AFTER.  NIY.  */
+
+static bool
+rtl_move_block_after (basic_block bb ATTRIBUTE_UNUSED,
+                     basic_block after ATTRIBUTE_UNUSED)
+{
+  return false;
+}
+
 /* Split a (typically critical) edge.  Return the new block.
    Abort on abnormal edges.
 
@@ -1347,8 +1285,6 @@ rtl_split_edge (edge edge_in)
     before = NULL_RTX;
 
   bb = create_basic_block (before, NULL, edge_in->dest->prev_bb);
-  bb->count = edge_in->count;
-  bb->frequency = EDGE_FREQUENCY (edge_in);
 
   /* ??? This info is likely going to be out of date very soon.  */
   if (edge_in->dest->global_live_at_start)
@@ -1714,15 +1650,21 @@ commit_edge_insertions_watch_calls (void)
   sbitmap_free (blocks);
 }
 \f
-/* Print out one basic block with live information at start and end.  */
+/* Print out RTL-specific basic block information (live information
+   at start and end).  */
 
 static void
-rtl_dump_bb (basic_block bb, FILE *outf)
+rtl_dump_bb (basic_block bb, FILE *outf, int indent)
 {
   rtx insn;
   rtx last;
+  char *s_indent;
 
-  fputs (";; Registers live at start:", outf);
+  s_indent = (char *) alloca ((size_t) indent + 1);
+  memset ((void *) s_indent, ' ', (size_t) indent);
+  s_indent[indent] = '\0';
+
+  fprintf (outf, ";;%s Registers live at start: ", s_indent);
   dump_regset (bb->global_live_at_start, outf);
   putc ('\n', outf);
 
@@ -1730,7 +1672,7 @@ rtl_dump_bb (basic_block bb, FILE *outf)
        insn = NEXT_INSN (insn))
     print_rtl_single (outf, insn);
 
-  fputs (";; Registers live at end:", outf);
+  fprintf (outf, ";;%s Registers live at end: ", s_indent);
   dump_regset (bb->global_live_at_end, outf);
   putc ('\n', outf);
 }
@@ -1847,6 +1789,7 @@ update_br_prob_note (basic_block bb)
 
    In future it can be extended check a lot of other stuff as well
    (reachability of basic blocks, life information, etc. etc.).  */
+
 static int
 rtl_verify_flow_info_1 (void)
 {
@@ -2412,16 +2355,17 @@ purge_all_dead_edges (int update_life_p)
 }
 
 /* Same as split_block but update cfg_layout structures.  */
-static edge
+
+static basic_block
 cfg_layout_split_block (basic_block bb, void *insnp)
 {
   rtx insn = insnp;
+  basic_block new_bb = rtl_split_block (bb, insn);
 
-  edge fallthru = rtl_split_block (bb, insn);
+  new_bb->rbi->footer = bb->rbi->footer;
+  bb->rbi->footer = NULL;
 
-  fallthru->dest->rbi->footer = fallthru->src->rbi->footer;
-  fallthru->src->rbi->footer = NULL;
-  return fallthru;
+  return new_bb;
 }
 
 
@@ -2511,7 +2455,8 @@ cfg_layout_redirect_edge_and_branch_force (edge e, basic_block dest)
   return NULL;
 }
 
-/* Same as flow_delete_block but update cfg_layout structures.  */
+/* Same as delete_basic_block but update cfg_layout structures.  */
+
 static void
 cfg_layout_delete_block (basic_block bb)
 {
@@ -2693,11 +2638,10 @@ cfg_layout_merge_blocks (basic_block a, basic_block b)
   if (rtl_dump_file)
     fprintf (rtl_dump_file, "Merged blocks %d and %d.\n",
             a->index, b->index);
-
-  update_cfg_after_block_merging (a, b);
 }
 
 /* Split edge E.  */
+
 static basic_block
 cfg_layout_split_edge (edge e)
 {
@@ -2707,19 +2651,22 @@ cfg_layout_split_edge (edge e)
                        ? NEXT_INSN (BB_END (e->src)) : get_insns (),
                        NULL_RTX, e->src);
 
-  new_bb->count = e->count;
-  new_bb->frequency = EDGE_FREQUENCY (e);
-
   new_e = make_edge (new_bb, e->dest, EDGE_FALLTHRU);
-  new_e->probability = REG_BR_PROB_BASE;
-  new_e->count = e->count;
   redirect_edge_and_branch_force (e, new_bb);
 
   return new_bb;
 }
 
+/* Do postprocessing after making a forwarder block joined by edge FALLTHRU.  */
+
+static void
+rtl_make_forwarder_block (edge fallthru ATTRIBUTE_UNUSED)
+{
+}
+
 /* Implementation of CFG manipulation for linearized RTL.  */
 struct cfg_hooks rtl_cfg_hooks = {
+  "rtl",
   rtl_verify_flow_info,
   rtl_dump_bb,
   rtl_create_basic_block,
@@ -2727,9 +2674,12 @@ struct cfg_hooks rtl_cfg_hooks = {
   rtl_redirect_edge_and_branch_force,
   rtl_delete_block,
   rtl_split_block,
+  rtl_move_block_after,
   rtl_can_merge_blocks,  /* can_merge_blocks_p */
   rtl_merge_blocks,
-  rtl_split_edge
+  rtl_split_edge,
+  rtl_make_forwarder_block,
+  rtl_tidy_fallthru_edge
 };
 
 /* Implementation of CFG manipulation for cfg layout RTL, where
@@ -2737,6 +2687,7 @@ struct cfg_hooks rtl_cfg_hooks = {
    This representation will hopefully become the default one in future
    version of the compiler.  */
 struct cfg_hooks cfg_layout_rtl_cfg_hooks = {
+  "cfglayout mode",
   rtl_verify_flow_info_1,
   rtl_dump_bb,
   cfg_layout_create_basic_block,
@@ -2744,7 +2695,10 @@ struct cfg_hooks cfg_layout_rtl_cfg_hooks = {
   cfg_layout_redirect_edge_and_branch_force,
   cfg_layout_delete_block,
   cfg_layout_split_block,
+  rtl_move_block_after,
   cfg_layout_can_merge_blocks_p,
   cfg_layout_merge_blocks,
-  cfg_layout_split_edge
+  cfg_layout_split_edge,
+  rtl_make_forwarder_block,
+  NULL
 };
index dbd8250360923cf167da45655ddb5ba2c59642b2..76ffdacc19441c12a5b207b56d6b707f466f2a16 100644 (file)
@@ -517,7 +517,7 @@ verify_wide_reg (int regno, basic_block bb)
   if (rtl_dump_file)
     {
       fprintf (rtl_dump_file, "Register %d died unexpectedly.\n", regno);
-      dump_bb (bb, rtl_dump_file);
+      dump_bb (bb, rtl_dump_file, 0);
     }
   abort ();
 }
@@ -541,7 +541,7 @@ verify_local_live_at_start (regset new_live_at_start, basic_block bb)
                       bb->index);
              debug_bitmap_file (rtl_dump_file, new_live_at_start);
              fputs ("Old:\n", rtl_dump_file);
-             dump_bb (bb, rtl_dump_file);
+             dump_bb (bb, rtl_dump_file, 0);
            }
          abort ();
        }
@@ -562,7 +562,7 @@ verify_local_live_at_start (regset new_live_at_start, basic_block bb)
                {
                  fprintf (rtl_dump_file,
                           "Register %d died unexpectedly.\n", i);
-                 dump_bb (bb, rtl_dump_file);
+                 dump_bb (bb, rtl_dump_file, 0);
                }
              abort ();
            }
index ffcb0016298b66a139be20c394527134c1b9e066..7a790638091eaafd9d05e26f340bf72e26723e00 100644 (file)
@@ -2103,8 +2103,6 @@ merge_if_block (struct ce_if_block * ce_info)
        {
          bb = fallthru;
          fallthru = block_fallthru (bb);
-         if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
-           delete_from_dominance_info (CDI_POST_DOMINATORS, bb);
          merge_blocks (combo_bb, bb);
          num_true_changes++;
        }
@@ -2120,8 +2118,6 @@ merge_if_block (struct ce_if_block * ce_info)
       if (combo_bb->global_live_at_end)
        COPY_REG_SET (combo_bb->global_live_at_end,
                      then_bb->global_live_at_end);
-      if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
-       delete_from_dominance_info (CDI_POST_DOMINATORS, then_bb);
       merge_blocks (combo_bb, then_bb);
       num_true_changes++;
     }
@@ -2131,8 +2127,6 @@ merge_if_block (struct ce_if_block * ce_info)
      get their addresses taken.  */
   if (else_bb)
     {
-      if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
-               delete_from_dominance_info (CDI_POST_DOMINATORS, else_bb);
       merge_blocks (combo_bb, else_bb);
       num_true_changes++;
     }
@@ -2188,8 +2182,6 @@ merge_if_block (struct ce_if_block * ce_info)
        COPY_REG_SET (combo_bb->global_live_at_end,
                      join_bb->global_live_at_end);
 
-      if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
-       delete_from_dominance_info (CDI_POST_DOMINATORS, join_bb);
       merge_blocks (combo_bb, join_bb);
       num_true_changes++;
     }
@@ -2205,7 +2197,7 @@ merge_if_block (struct ce_if_block * ce_info)
 
       /* Remove the jump and cruft from the end of the COMBO block.  */
       if (join_bb != EXIT_BLOCK_PTR)
-       tidy_fallthru_edge (combo_bb->succ, combo_bb, join_bb);
+       tidy_fallthru_edge (combo_bb->succ);
     }
 
   num_updated_if_blocks++;
@@ -2643,11 +2635,7 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge)
   /* Delete the trap block if possible.  */
   remove_edge (trap_bb == then_bb ? then_edge : else_edge);
   if (trap_bb->pred == NULL)
-    {
-      if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
-       delete_from_dominance_info (CDI_POST_DOMINATORS, trap_bb);
-      delete_block (trap_bb);
-    }
+    delete_basic_block (trap_bb);
 
   /* If the non-trap block and the test are now adjacent, merge them.
      Otherwise we must insert a direct branch.  */
@@ -2829,9 +2817,7 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
 
   new_bb = redirect_edge_and_branch_force (FALLTHRU_EDGE (test_bb), else_bb);
   then_bb_index = then_bb->index;
-  if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
-    delete_from_dominance_info (CDI_POST_DOMINATORS, then_bb);
-  delete_block (then_bb);
+  delete_basic_block (then_bb);
 
   /* Make rest of code believe that the newly created block is the THEN_BB
      block we removed.  */
@@ -2839,8 +2825,6 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
     {
       new_bb->index = then_bb_index;
       BASIC_BLOCK (then_bb_index) = new_bb;
-      if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
-       add_to_dominance_info (CDI_POST_DOMINATORS, new_bb);
     }
   /* We've possibly created jump to next insn, cleanup_cfg will solve that
      later.  */
@@ -2909,9 +2893,7 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
                    then_bb->global_live_at_start,
                    else_bb->global_live_at_end, BITMAP_IOR);
 
-  if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
-    delete_from_dominance_info (CDI_POST_DOMINATORS, else_bb);
-  delete_block (else_bb);
+  delete_basic_block (else_bb);
 
   num_true_changes++;
   num_updated_if_blocks++;
index 4cfaa2f62554b07e014aef78dddcf53d826cab2c..aa39ae238165015a3e9a6af045a2baeeda0a42ef 100644 (file)
@@ -381,7 +381,6 @@ unswitch_loop (struct loops *loops, struct loop *loop, basic_block unswitch_on)
       switch_bb->succ->flags &= ~EDGE_IRREDUCIBLE_LOOP;
       switch_bb->succ->succ_next->flags &= ~EDGE_IRREDUCIBLE_LOOP;
     }
-  add_to_dominance_info (CDI_DOMINATORS, switch_bb);
   unswitch_on->rbi->copy = unswitch_on_alt;
 
   /* Loopify from the copy of LOOP body, constructing the new loop.  */
index 6fab782c0527e324dbf8a73a06e12c874369f19e..19dc0c468f0dcb5a5a41060e65ca56ad24b96473 100644 (file)
@@ -45,6 +45,7 @@ DEFTIMEVAR (TV_CGRAPHOPT             , "callgraph optimization")
 DEFTIMEVAR (TV_CFG                   , "cfg construction")
 /* Time spent by cleaning up CFG.  */
 DEFTIMEVAR (TV_CLEANUP_CFG           , "cfg cleanup")
+DEFTIMEVAR (TV_CFG_VERIFY            , "CFG verifier")
 DEFTIMEVAR (TV_DELETE_TRIVIALLY_DEAD , "trivially dead code")
 /* Time spent by life analysis.  */
 DEFTIMEVAR (TV_LIFE                 , "life analysis")