summaryrefslogtreecommitdiffstats
path: root/gcc
diff options
context:
space:
mode:
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2004-01-29 07:47:56 +0000
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2004-01-29 07:47:56 +0000
commit5f5d4cd12a68a2564978c5cbacbae78e7f9f1559 (patch)
tree075d0d98ba746f488ac4ecf2ecf94a83992aacbc /gcc
parentd41dc6f8ad2b5f4e3d1bfd130e7f67dc10a99579 (diff)
downloadppe42-gcc-5f5d4cd12a68a2564978c5cbacbae78e7f9f1559.tar.gz
ppe42-gcc-5f5d4cd12a68a2564978c5cbacbae78e7f9f1559.zip
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@76851 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog63
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/basic-block.h8
-rw-r--r--gcc/cfg.c173
-rw-r--r--gcc/cfgcleanup.c12
-rw-r--r--gcc/cfghooks.c536
-rw-r--r--gcc/cfghooks.h57
-rw-r--r--gcc/cfglayout.c1
-rw-r--r--gcc/cfgloop.c128
-rw-r--r--gcc/cfgloopmanip.c95
-rw-r--r--gcc/cfgrtl.c208
-rw-r--r--gcc/flow.c6
-rw-r--r--gcc/ifcvt.c26
-rw-r--r--gcc/loop-unswitch.c1
-rw-r--r--gcc/timevar.def1
15 files changed, 824 insertions, 493 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index faa3c9a1376..39e5a4b5202 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 92916f0e2c6..946b4f75b18 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -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)
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 10cc6351bd6..240edfd79df 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -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
diff --git a/gcc/cfg.c b/gcc/cfg.c
index 80425853666..ff3f3679136 100644
--- 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;
}
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 52d58196d85..a886e832bb5 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -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;
}
}
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index 525289c04f8..fd361c5fc85 100644
--- a/gcc/cfghooks.c
+++ b/gcc/cfghooks.c
@@ -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);
+ }
+}
diff --git a/gcc/cfghooks.h b/gcc/cfghooks.h
index 5ef3b1f5480..4c2d0bf37bb 100644
--- a/gcc/cfghooks.h
+++ b/gcc/cfghooks.h
@@ -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);
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index 15ec0547451..bdee8675768 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -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;
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index 69097c009a9..6fa8b17706a 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -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);
/* 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 ();
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 86af4a2536b..2c60659fec8 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -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;
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 70d06563ac6..01a5f3dbe66 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -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);
/* 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);
}
/* Records the basic block struct in BLOCK_FOR_INSN for every insn. */
@@ -470,28 +459,34 @@ update_bb_for_insn (basic_block bb)
}
}
-/* 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);
- }
-}
/* 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);
}
-/* 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
};
diff --git a/gcc/flow.c b/gcc/flow.c
index dbd82503609..76ffdacc194 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -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 ();
}
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index ffcb0016298..7a790638091 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -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++;
diff --git a/gcc/loop-unswitch.c b/gcc/loop-unswitch.c
index 4cfaa2f6255..aa39ae23816 100644
--- a/gcc/loop-unswitch.c
+++ b/gcc/loop-unswitch.c
@@ -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. */
diff --git a/gcc/timevar.def b/gcc/timevar.def
index 6fab782c052..19dc0c468f0 100644
--- a/gcc/timevar.def
+++ b/gcc/timevar.def
@@ -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")
OpenPOWER on IntegriCloud