summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2002-02-28 10:11:01 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2002-02-28 10:11:01 +0000
commit308f9b7994783bcf7867e5c06fe3a88bd01d847f (patch)
tree8d5067250a1945f16e7442da0ebfa33bcd46322d /gcc
parentea5356cdbd7b2cbdb81a2f971be4ca11ce8fdda2 (diff)
downloadgcc-308f9b7994783bcf7867e5c06fe3a88bd01d847f.tar.gz
* basic-block.h (BB_REACHABLE): Renumber.
(BB_DIRTY, BB_NEW): New flags. (clear_bb_flags): Declare. (update_life_info_in_dirty_blocks): Declare. * cfg.c (clear_bb_flags): New function. * cfgrtl.c (create_basic_block_structure): Set flags to BB_NEW. * emit-rtl.c (add_insn_after, add_insn_before, remove_insn, reorder_insns, emit_insn_after): Mark block as dirty. * flow.c (update_life_info): Fix clearing of PROP_LOG_LINKS. (update_life_info_in_dirty_blocks): New function. * recog.c (apply_change_group): Dirtify block. * cse.c (cse_insn): Reorder emitting of jump insn to keep cfg consistent. * gcse.c (delete_null_pointer_checks): Likewise. * toplev.c (dump_file_index): Move cse2 after bp, add DFI_null (dump_file_info): Similary. (rest_of_compilation): Avoid most of CFG rebuilds; do first if converision after null pointer checks, do cse2 after branch prediction; avoid full liveness rebuild after initializing subregs. * invoke.texi (-d options): Document -du, renumber. * cfgcleanup.c (bb_flags): Remove BB_UPDATE_LIFE. (notice_new_block): Do not set BB_UPDATE_LIFE. (try_forward_edges, merge_blocks_move_predecessor_nojumps, merge_blocks_move_successor_nojumps, merge_blocks, try_crossjump_to_edge): Likewise. (try_optimize_cfg): Likewise; use update_life_info_in_dirty_blocks. * cfgrtl.c (merge_blocks_nomove): Copy b's flags to a. * ifcvt.c (SET_UPDATE_LIFE, UPDATE_LIFE): Kill. (merge_of_block): Do not use life_data_ok. (find_if_case_1): Do not use SET_UPDATE_LIFE. (if_convert): Use BB_DIRTY mechanizm to update life. * lcm.c (optimize_mode_switching): Update update_life_info_in_dirty_blocks git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@50127 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog41
-rw-r--r--gcc/basic-block.h7
-rw-r--r--gcc/cfg.c11
-rw-r--r--gcc/cfgcleanup.c48
-rw-r--r--gcc/cfgrtl.c2
-rw-r--r--gcc/cse.c3
-rw-r--r--gcc/doc/invoke.texi51
-rw-r--r--gcc/emit-rtl.c9
-rw-r--r--gcc/flow.c33
-rw-r--r--gcc/gcse.c4
-rw-r--r--gcc/ifcvt.c41
-rw-r--r--gcc/lcm.c16
-rw-r--r--gcc/recog.c11
-rw-r--r--gcc/toplev.c221
14 files changed, 272 insertions, 226 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3074e4b47af..d757905eb2e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,44 @@
+Don Feb 28 11:07:36 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * basic-block.h (BB_REACHABLE): Renumber.
+ (BB_DIRTY, BB_NEW): New flags.
+ (clear_bb_flags): Declare.
+ (update_life_info_in_dirty_blocks): Declare.
+ * cfg.c (clear_bb_flags): New function.
+ * cfgrtl.c (create_basic_block_structure): Set flags to BB_NEW.
+ * emit-rtl.c (add_insn_after, add_insn_before, remove_insn,
+ reorder_insns, emit_insn_after): Mark block as dirty.
+ * flow.c (update_life_info): Fix clearing of PROP_LOG_LINKS.
+ (update_life_info_in_dirty_blocks): New function.
+ * recog.c (apply_change_group): Dirtify block.
+
+ * cse.c (cse_insn): Reorder emitting of jump insn to keep
+ cfg consistent.
+ * gcse.c (delete_null_pointer_checks): Likewise.
+
+ * toplev.c (dump_file_index): Move cse2 after bp,
+ add DFI_null
+ (dump_file_info): Similary.
+ (rest_of_compilation): Avoid most of CFG rebuilds;
+ do first if converision after null pointer checks, do cse2
+ after branch prediction; avoid full liveness rebuild after
+ initializing subregs.
+ * invoke.texi (-d options): Document -du, renumber.
+
+ * cfgcleanup.c (bb_flags): Remove BB_UPDATE_LIFE.
+ (notice_new_block): Do not set BB_UPDATE_LIFE.
+ (try_forward_edges, merge_blocks_move_predecessor_nojumps,
+ merge_blocks_move_successor_nojumps, merge_blocks,
+ try_crossjump_to_edge): Likewise.
+ (try_optimize_cfg): Likewise; use update_life_info_in_dirty_blocks.
+ * cfgrtl.c (merge_blocks_nomove): Copy b's flags to a.
+ * ifcvt.c (SET_UPDATE_LIFE, UPDATE_LIFE): Kill.
+ (merge_of_block): Do not use life_data_ok.
+ (find_if_case_1): Do not use SET_UPDATE_LIFE.
+ (if_convert): Use BB_DIRTY mechanizm to update life.
+ * lcm.c (optimize_mode_switching): Update
+ update_life_info_in_dirty_blocks
+
2002-02-28 Neil Booth <neil@daikokuya.demon.co.uk>
* Makefile.in (integrate.o): Update.
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 1bc1d780f19..39e24c82760 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -221,7 +221,9 @@ typedef struct basic_block_def {
#define BB_FREQ_MAX 10000
/* Masks for basic_block.flags. */
-#define BB_REACHABLE 1
+#define BB_DIRTY 1
+#define BB_NEW 2
+#define BB_REACHABLE 4
/* Number of basic blocks in the current function. */
@@ -311,6 +313,7 @@ extern void redirect_edge_pred PARAMS ((edge, basic_block));
extern basic_block create_basic_block_structure PARAMS ((int, rtx, rtx, rtx));
extern basic_block create_basic_block PARAMS ((int, rtx, rtx));
extern int flow_delete_block PARAMS ((basic_block));
+extern void clear_bb_flags PARAMS ((void));
extern void merge_blocks_nomove PARAMS ((basic_block, basic_block));
extern void tidy_fallthru_edge PARAMS ((edge, basic_block,
basic_block));
@@ -587,6 +590,8 @@ enum update_life_extent
extern void life_analysis PARAMS ((rtx, FILE *, int));
extern void update_life_info PARAMS ((sbitmap, enum update_life_extent,
int));
+extern void update_life_info_in_dirty_blocks PARAMS ((enum update_life_extent,
+ int));
extern int count_or_remove_death_notes PARAMS ((sbitmap, int));
extern int propagate_block PARAMS ((basic_block, regset, regset, regset,
int));
diff --git a/gcc/cfg.c b/gcc/cfg.c
index 8adcef637b3..a33beffd0b2 100644
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -38,6 +38,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
dump_flow_info, debug_flow_info, dump_edge_info
- Allocation of AUX fields for basic blocks
alloc_aux_for_blocks, free_aux_for_blocks, alloc_aux_for_block
+ - clear_bb_flags
*/
#include "config.h"
@@ -440,6 +441,16 @@ redirect_edge_pred (e, new_pred)
new_pred->succ = e;
e->src = new_pred;
}
+
+void
+clear_bb_flags ()
+{
+ int i;
+ ENTRY_BLOCK_PTR->flags = 0;
+ EXIT_BLOCK_PTR->flags = 0;
+ for (i = 0; i < n_basic_blocks; i++)
+ BASIC_BLOCK (i)->flags = 0;
+}
void
dump_flow_info (file)
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index d9f9cf261e5..017a4aa5390 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -52,11 +52,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
enum bb_flags
{
- /* Set if life info needs to be recomputed for given BB. */
- BB_UPDATE_LIFE = 1,
/* Set if BB is the forwarder block to avoid too many
forwarder_block_p calls. */
- BB_FORWARDER_BLOCK = 2
+ BB_FORWARDER_BLOCK = 1
};
#define BB_FLAGS(BB) (enum bb_flags) (BB)->aux
@@ -101,7 +99,6 @@ notice_new_block (bb)
if (!bb)
return;
- BB_SET_FLAG (bb, BB_UPDATE_LIFE);
if (forwarder_block_p (bb))
BB_SET_FLAG (bb, BB_FORWARDER_BLOCK);
}
@@ -519,7 +516,6 @@ try_forward_edges (mode, b)
if (!FORWARDER_BLOCK_P (b) && forwarder_block_p (b))
BB_SET_FLAG (b, BB_FORWARDER_BLOCK);
- BB_SET_FLAG (b, BB_UPDATE_LIFE);
do
{
@@ -663,7 +659,7 @@ merge_blocks_move_predecessor_nojumps (a, b)
/* Scramble the insn chain. */
if (a->end != PREV_INSN (b->head))
reorder_insns_nobb (a->head, a->end, PREV_INSN (b->head));
- BB_SET_FLAG (a, BB_UPDATE_LIFE);
+ a->flags |= BB_DIRTY;
if (rtl_dump_file)
fprintf (rtl_dump_file, "Moved block %d before %d and merged.\n",
@@ -731,7 +727,6 @@ merge_blocks_move_successor_nojumps (a, b)
/* Now blocks A and B are contiguous. Merge them. */
merge_blocks_nomove (a, b);
- BB_SET_FLAG (a, BB_UPDATE_LIFE);
if (rtl_dump_file)
fprintf (rtl_dump_file, "Moved block %d after %d and merged.\n",
@@ -760,12 +755,6 @@ merge_blocks (e, b, c, mode)
if (e->flags & EDGE_FALLTHRU)
{
int b_index = b->index, c_index = c->index;
- /* We need to update liveness in case C already has broken liveness
- or B ends by conditional jump to next instructions that will be
- removed. */
- if ((BB_FLAGS (c) & BB_UPDATE_LIFE)
- || GET_CODE (b->end) == JUMP_INSN)
- BB_SET_FLAG (b, BB_UPDATE_LIFE);
merge_blocks_nomove (b, c);
update_forwarder_flag (b);
@@ -831,8 +820,6 @@ merge_blocks (e, b, c, mode)
bb = force_nonfallthru (b_fallthru_edge);
if (bb)
notice_new_block (bb);
- else
- BB_SET_FLAG (b_fallthru_edge->src, BB_UPDATE_LIFE);
}
merge_blocks_move_predecessor_nojumps (b, c);
@@ -1418,7 +1405,6 @@ try_crossjump_to_edge (mode, e1, e2)
remove_edge (src1->succ);
make_single_succ_edge (src1, redirect_to, 0);
- BB_SET_FLAG (src1, BB_UPDATE_LIFE);
update_forwarder_flag (src1);
return true;
@@ -1532,6 +1518,9 @@ try_optimize_cfg (mode)
for (i = 0; i < n_basic_blocks; i++)
update_forwarder_flag (BASIC_BLOCK (i));
+ if (mode & CLEANUP_UPDATE_LIFE)
+ clear_bb_flags ();
+
if (! (* targetm.cannot_modify_jumps_p) ())
{
/* Attempt to merge blocks as made possible by edge removal. If
@@ -1633,10 +1622,7 @@ try_optimize_cfg (mode)
/* Simplify branch over branch. */
if ((mode & CLEANUP_EXPENSIVE) && try_simplify_condjump (b))
- {
- BB_SET_FLAG (b, BB_UPDATE_LIFE);
- changed_here = true;
- }
+ changed_here = true;
/* If B has a single outgoing edge, but uses a
non-trivial jump instruction without side-effects, we
@@ -1649,7 +1635,6 @@ try_optimize_cfg (mode)
&& onlyjump_p (b->end)
&& redirect_edge_and_branch (b->succ, b->succ->dest))
{
- BB_SET_FLAG (b, BB_UPDATE_LIFE);
update_forwarder_flag (b);
changed_here = true;
}
@@ -1689,24 +1674,9 @@ try_optimize_cfg (mode)
remove_fake_edges ();
if ((mode & CLEANUP_UPDATE_LIFE) && changed_overall)
- {
- bool found = 0;
-
- blocks = sbitmap_alloc (n_basic_blocks);
- sbitmap_zero (blocks);
- for (i = 0; i < n_basic_blocks; i++)
- if (BB_FLAGS (BASIC_BLOCK (i)) & BB_UPDATE_LIFE)
- {
- found = 1;
- SET_BIT (blocks, i);
- }
-
- if (found)
- update_life_info (blocks, UPDATE_LIFE_GLOBAL,
- PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
- | PROP_KILL_DEAD_CODE);
- sbitmap_free (blocks);
- }
+ update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL,
+ PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
+ | PROP_KILL_DEAD_CODE | PROP_LOG_LINKS);
for (i = 0; i < n_basic_blocks; i++)
BASIC_BLOCK (i)->aux = NULL;
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 5b99ab237e2..1b00a61285c 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -271,6 +271,7 @@ create_basic_block_structure (index, head, end, bb_note)
bb->head = head;
bb->end = end;
bb->index = index;
+ bb->flags = BB_NEW;
BASIC_BLOCK (index) = bb;
if (basic_block_for_insn)
update_bb_for_insn (bb);
@@ -592,6 +593,7 @@ merge_blocks_nomove (a, b)
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;
diff --git a/gcc/cse.c b/gcc/cse.c
index a607b0c46f3..557e8086d7f 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -5800,10 +5800,11 @@ cse_insn (insn, libcall_insn)
and hope for the best. */
if (n_sets == 1)
{
- rtx new = emit_jump_insn_before (gen_jump (XEXP (src, 0)), insn);
+ rtx new = emit_jump_insn_after (gen_jump (XEXP (src, 0)), insn);
JUMP_LABEL (new) = XEXP (src, 0);
LABEL_NUSES (XEXP (src, 0))++;
+ delete_insn (insn);
insn = new;
/* Now emit a BARRIER after the unconditional jump. */
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 90df7de7361..8dab7a0f3a8 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -2853,19 +2853,19 @@ Here are the possible letters for use in @var{letters}, and their meanings:
Annotate the assembler output with miscellaneous debugging information.
@item b
@opindex db
-Dump after computing branch probabilities, to @file{@var{file}.14.bp}.
+Dump after computing branch probabilities, to @file{@var{file}.15.bp}.
@item B
@opindex dB
-Dump after block reordering, to @file{@var{file}.29.bbro}.
+Dump after block reordering, to @file{@var{file}.30.bbro}.
@item c
@opindex dc
-Dump after instruction combination, to the file @file{@var{file}.16.combine}.
+Dump after instruction combination, to the file @file{@var{file}.17.combine}.
@item C
@opindex dC
-Dump after the first if conversion, to the file @file{@var{file}.17.ce}.
+Dump after the first if conversion, to the file @file{@var{file}.18.ce}.
@item d
@opindex dd
-Dump after delayed branch scheduling, to @file{@var{file}.31.dbr}.
+Dump after delayed branch scheduling, to @file{@var{file}.32.dbr}.
@item D
@opindex dD
Dump all macro definitions, at the end of preprocessing, in addition to
@@ -2876,28 +2876,28 @@ Dump after SSA optimizations, to @file{@var{file}.04.ssa} and
@file{@var{file}.07.ussa}.
@item E
@opindex dE
-Dump after the second if conversion, to @file{@var{file}.26.ce2}.
+Dump after the second if conversion, to @file{@var{file}.27.ce2}.
@item f
@opindex df
-Dump after life analysis, to @file{@var{file}.15.life}.
+Dump after life analysis, to @file{@var{file}.16.life}.
@item F
@opindex dF
-Dump after purging @code{ADDRESSOF} codes, to @file{@var{file}.09.addressof}.
+Dump after purging @code{ADDRESSOF} codes, to @file{@var{file}.10.addressof}.
@item g
@opindex dg
-Dump after global register allocation, to @file{@var{file}.21.greg}.
+Dump after global register allocation, to @file{@var{file}.22.greg}.
@item h
@opindex dh
Dump after finalization of EH handling code, to @file{@var{file}.02.eh}.
@item k
@opindex dk
-Dump after reg-to-stack conversion, to @file{@var{file}.28.stack}.
+Dump after reg-to-stack conversion, to @file{@var{file}.29.stack}.
@item o
@opindex do
-Dump after post-reload optimizations, to @file{@var{file}.22.postreload}.
+Dump after post-reload optimizations, to @file{@var{file}.23.postreload}.
@item G
@opindex dG
-Dump after GCSE, to @file{@var{file}.10.gcse}.
+Dump after GCSE, to @file{@var{file}.11.gcse}.
@item i
@opindex di
Dump after sibling call optimizations, to @file{@var{file}.01.sibling}.
@@ -2906,49 +2906,52 @@ Dump after sibling call optimizations, to @file{@var{file}.01.sibling}.
Dump after the first jump optimization, to @file{@var{file}.03.jump}.
@item k
@opindex dk
-Dump after conversion from registers to stack, to @file{@var{file}.32.stack}.
+Dump after conversion from registers to stack, to @file{@var{file}.33.stack}.
@item l
@opindex dl
-Dump after local register allocation, to @file{@var{file}.20.lreg}.
+Dump after local register allocation, to @file{@var{file}.21.lreg}.
@item L
@opindex dL
-Dump after loop optimization, to @file{@var{file}.11.loop}.
+Dump after loop optimization, to @file{@var{file}.12.loop}.
@item M
@opindex dM
Dump after performing the machine dependent reorganisation pass, to
-@file{@var{file}.30.mach}.
+@file{@var{file}.31.mach}.
@item n
@opindex dn
-Dump after register renumbering, to @file{@var{file}.25.rnreg}.
+Dump after register renumbering, to @file{@var{file}.26.rnreg}.
@item N
@opindex dN
-Dump after the register move pass, to @file{@var{file}.18.regmove}.
+Dump after the register move pass, to @file{@var{file}.19.regmove}.
@item r
@opindex dr
Dump after RTL generation, to @file{@var{file}.00.rtl}.
@item R
@opindex dR
-Dump after the second scheduling pass, to @file{@var{file}.27.sched2}.
+Dump after the second scheduling pass, to @file{@var{file}.28.sched2}.
@item s
@opindex ds
Dump after CSE (including the jump optimization that sometimes follows
-CSE), to @file{@var{file}.08.cse}.
+CSE), to @file{@var{file}.09.cse}.
@item S
@opindex dS
-Dump after the first scheduling pass, to @file{@var{file}.19.sched}.
+Dump after the first scheduling pass, to @file{@var{file}.20.sched}.
@item t
@opindex dt
Dump after the second CSE pass (including the jump optimization that
-sometimes follows CSE), to @file{@var{file}.12.cse2}.
+sometimes follows CSE), to @file{@var{file}.13.cse2}.
+@item u
+@opindex du
+Dump after null pointer ellimination pass ti @file{@var{file}.08.null}.
@item w
@opindex dw
-Dump after the second flow pass, to @file{@var{file}.23.flow2}.
+Dump after the second flow pass, to @file{@var{file}.24.flow2}.
@item X
@opindex dX
Dump after SSA dead code elimination, to @file{@var{file}.06.ssadce}.
@item z
@opindex dz
-Dump after the peephole pass, to @file{@var{file}.24.peephole2}.
+Dump after the peephole pass, to @file{@var{file}.25.peephole2}.
@item a
@opindex da
Produce all the dumps listed above.
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 492888f9037..e248af19021 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -3276,6 +3276,8 @@ add_insn_after (insn, after)
&& (bb = BLOCK_FOR_INSN (after)))
{
set_block_for_insn (insn, bb);
+ if (INSN_P (insn))
+ bb->flags |= BB_DIRTY;
/* Should not happen as first in the BB is always
either NOTE or LABEL. */
if (bb->end == after
@@ -3343,6 +3345,8 @@ add_insn_before (insn, before)
&& (bb = BLOCK_FOR_INSN (before)))
{
set_block_for_insn (insn, bb);
+ if (INSN_P (insn))
+ bb->flags |= BB_DIRTY;
/* Should not happen as first in the BB is always
either NOTE or LABEl. */
if (bb->head == insn
@@ -3420,6 +3424,8 @@ remove_insn (insn)
&& (unsigned int)INSN_UID (insn) < basic_block_for_insn->num_elements
&& (bb = BLOCK_FOR_INSN (insn)))
{
+ if (INSN_P (insn))
+ bb->flags |= BB_DIRTY;
if (bb->head == insn)
{
/* Never ever delete the basic block note without deleting whole basic
@@ -3497,6 +3503,7 @@ reorder_insns (from, to, after)
&& (bb = BLOCK_FOR_INSN (after)))
{
rtx x;
+ bb->flags |= BB_DIRTY;
if (basic_block_for_insn
&& (unsigned int)INSN_UID (from) < basic_block_for_insn->num_elements
@@ -3504,6 +3511,7 @@ reorder_insns (from, to, after)
{
if (bb2->end == to)
bb2->end = prev;
+ bb2->flags |= BB_DIRTY;
}
if (bb->end == after)
@@ -4028,6 +4036,7 @@ emit_insns_after (first, after)
&& (unsigned int)INSN_UID (after) < basic_block_for_insn->num_elements
&& (bb = BLOCK_FOR_INSN (after)))
{
+ bb->flags |= BB_DIRTY;
for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
set_block_for_insn (last, bb);
set_block_for_insn (last, bb);
diff --git a/gcc/flow.c b/gcc/flow.c
index 6c3cd564d7d..54985d921f5 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -645,10 +645,6 @@ update_life_info (blocks, extent, prop_flags)
&& (extent == UPDATE_LIFE_LOCAL || blocks))
abort ();
- /* Clear log links in case we are asked to (re)compute them. */
- if (prop_flags & PROP_LOG_LINKS)
- clear_log_links (blocks);
-
/* For a global update, we go through the relaxation process again. */
if (extent != UPDATE_LIFE_LOCAL)
{
@@ -685,6 +681,10 @@ update_life_info (blocks, extent, prop_flags)
count_or_remove_death_notes (blocks, 1);
}
+ /* Clear log links in case we are asked to (re)compute them. */
+ if (prop_flags & PROP_LOG_LINKS)
+ clear_log_links (blocks);
+
if (blocks)
{
EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
@@ -746,6 +746,31 @@ update_life_info (blocks, extent, prop_flags)
? TV_LIFE_UPDATE : TV_LIFE);
}
+/* Update life information in all blocks where BB_DIRTY is set. */
+
+void
+update_life_info_in_dirty_blocks (extent, prop_flags)
+ enum update_life_extent extent;
+ int prop_flags;
+{
+ sbitmap update_life_blocks = sbitmap_alloc (n_basic_blocks);
+ int block_num;
+ int n = 0;
+
+ sbitmap_zero (update_life_blocks);
+ for (block_num = 0; block_num < n_basic_blocks; block_num++)
+ if (BASIC_BLOCK (block_num)->flags & BB_DIRTY)
+ {
+ SET_BIT (update_life_blocks, block_num);
+ n++;
+ }
+
+ if (n)
+ update_life_info (update_life_blocks, extent, prop_flags);
+
+ sbitmap_free (update_life_blocks);
+}
+
/* Free the variables allocated by find_basic_blocks.
KEEP_HEAD_END_P is non-zero if basic_block_info is not to be freed. */
diff --git a/gcc/gcse.c b/gcc/gcse.c
index b7b08f2840a..52013c1ddd1 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -5330,8 +5330,8 @@ delete_null_pointer_checks_1 (block_reg, nonnull_avin,
{
rtx new_jump;
- new_jump = emit_jump_insn_before (gen_jump (JUMP_LABEL (last_insn)),
- last_insn);
+ new_jump = emit_jump_insn_after (gen_jump (JUMP_LABEL (last_insn)),
+ last_insn);
JUMP_LABEL (new_jump) = JUMP_LABEL (last_insn);
LABEL_NUSES (JUMP_LABEL (new_jump))++;
emit_barrier_after (new_jump);
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index a7860e3ea4e..038b8c5d5ff 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -113,10 +113,8 @@ static void noce_emit_move_insn PARAMS ((rtx, rtx));
as well as a flag indicating that the block should be rescaned for
life analysis. */
-#define SET_ORIG_INDEX(BB,I) ((BB)->aux = (void *)((size_t)(I) << 1))
-#define ORIG_INDEX(BB) ((size_t)(BB)->aux >> 1)
-#define SET_UPDATE_LIFE(BB) ((BB)->aux = (void *)((size_t)(BB)->aux | 1))
-#define UPDATE_LIFE(BB) ((size_t)(BB)->aux & 1)
+#define SET_ORIG_INDEX(BB,I) ((BB)->aux = (void *)((size_t)(I)))
+#define ORIG_INDEX(BB) ((size_t)(BB)->aux)
/* Count the number of non-jump active insns in BB. */
@@ -1845,7 +1843,7 @@ merge_if_block (test_bb, then_bb, else_bb, join_bb)
/* First merge TEST block into THEN block. This is a no-brainer since
the THEN block did not have a code label to begin with. */
- if (life_data_ok)
+ if (combo_bb->global_live_at_end)
COPY_REG_SET (combo_bb->global_live_at_end, then_bb->global_live_at_end);
merge_blocks_nomove (combo_bb, then_bb);
num_removed_blocks++;
@@ -1886,7 +1884,7 @@ merge_if_block (test_bb, then_bb, else_bb, join_bb)
&& join_bb != EXIT_BLOCK_PTR)
{
/* We can merge the JOIN. */
- if (life_data_ok)
+ if (combo_bb->global_live_at_end)
COPY_REG_SET (combo_bb->global_live_at_end,
join_bb->global_live_at_end);
merge_blocks_nomove (combo_bb, join_bb);
@@ -1907,9 +1905,6 @@ merge_if_block (test_bb, then_bb, else_bb, join_bb)
tidy_fallthru_edge (combo_bb->succ, combo_bb, join_bb);
}
- /* Make sure we update life info properly. */
- SET_UPDATE_LIFE (combo_bb);
-
num_updated_if_blocks++;
}
@@ -2324,7 +2319,6 @@ find_if_case_1 (test_bb, then_edge, else_edge)
/* Conversion went ok, including moving the insns and fixing up the
jump. Adjust the CFG to match. */
- SET_UPDATE_LIFE (test_bb);
bitmap_operation (test_bb->global_live_at_end,
else_bb->global_live_at_start,
then_bb->global_live_at_end, BITMAP_IOR);
@@ -2333,10 +2327,7 @@ find_if_case_1 (test_bb, then_edge, else_edge)
/* Make rest of code believe that the newly created block is the THEN_BB
block we are going to remove. */
if (new_bb)
- {
- new_bb->aux = then_bb->aux;
- SET_UPDATE_LIFE (then_bb);
- }
+ new_bb->aux = then_bb->aux;
flow_delete_block (then_bb);
/* We've possibly created jump to next insn, cleanup_cfg will solve that
later. */
@@ -2403,7 +2394,6 @@ find_if_case_2 (test_bb, then_edge, else_edge)
/* Conversion went ok, including moving the insns and fixing up the
jump. Adjust the CFG to match. */
- SET_UPDATE_LIFE (test_bb);
bitmap_operation (test_bb->global_live_at_end,
then_bb->global_live_at_start,
else_bb->global_live_at_end, BITMAP_IOR);
@@ -2718,6 +2708,8 @@ if_convert (x_life_data_ok)
post_dominators = sbitmap_vector_alloc (n_basic_blocks, n_basic_blocks);
calculate_dominance_info (NULL, post_dominators, CDI_POST_DOMINATORS);
}
+ if (life_data_ok)
+ clear_bb_flags ();
/* Record initial block numbers. */
for (block_num = 0; block_num < n_basic_blocks; block_num++)
@@ -2742,28 +2734,15 @@ if_convert (x_life_data_ok)
/* Rebuild life info for basic blocks that require it. */
if (num_removed_blocks && life_data_ok)
{
- sbitmap update_life_blocks = sbitmap_alloc (n_basic_blocks);
- sbitmap_zero (update_life_blocks);
-
/* If we allocated new pseudos, we must resize the array for sched1. */
if (max_regno < max_reg_num ())
{
max_regno = max_reg_num ();
allocate_reg_info (max_regno, FALSE, FALSE);
}
-
- for (block_num = 0; block_num < n_basic_blocks; block_num++)
- if (UPDATE_LIFE (BASIC_BLOCK (block_num)))
- SET_BIT (update_life_blocks, block_num);
-
- count_or_remove_death_notes (update_life_blocks, 1);
- /* ??? See about adding a mode that verifies that the initial
- set of blocks don't let registers come live. */
- update_life_info (update_life_blocks, UPDATE_LIFE_GLOBAL,
- PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
- | PROP_KILL_DEAD_CODE);
-
- sbitmap_free (update_life_blocks);
+ update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
+ PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
+ | PROP_KILL_DEAD_CODE);
}
clear_aux_for_blocks ();
diff --git a/gcc/lcm.c b/gcc/lcm.c
index 0a8a7cef9a1..f64c7ada7d4 100644
--- a/gcc/lcm.c
+++ b/gcc/lcm.c
@@ -1031,6 +1031,7 @@ optimize_mode_switching (file)
int max_num_modes = 0;
bool emited = false;
+ clear_bb_flags ();
#ifdef NORMAL_MODE
/* Increment n_basic_blocks before allocating bb_info. */
n_basic_blocks++;
@@ -1398,16 +1399,11 @@ optimize_mode_switching (file)
if (!need_commit && !emited)
return 0;
- /* Ideally we'd figure out what blocks were affected and start from
- there, but this is enormously complicated by commit_edge_insertions,
- which would screw up any indices we'd collected, and also need to
- be involved in the update. Bail and recompute global life info for
- everything. */
-
- allocate_reg_life_data ();
- update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
- (PROP_DEATH_NOTES | PROP_KILL_DEAD_CODE
- | PROP_SCAN_DEAD_CODE | PROP_REG_INFO));
+ max_regno = max_reg_num ();
+ allocate_reg_info (max_regno, FALSE, FALSE);
+ update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
+ (PROP_DEATH_NOTES | PROP_KILL_DEAD_CODE
+ | PROP_SCAN_DEAD_CODE));
return 1;
}
diff --git a/gcc/recog.c b/gcc/recog.c
index 6039c4d607a..69f75b79bf6 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -392,6 +392,17 @@ apply_change_group ()
if (i == num_changes)
{
+ basic_block bb;
+
+ for (i = 0; i < num_changes; i++)
+ if (changes[i].object
+ && INSN_P (changes[i].object)
+ && basic_block_for_insn
+ && ((unsigned int)INSN_UID (changes[i].object)
+ < basic_block_for_insn->num_elements)
+ && (bb = BLOCK_FOR_INSN (changes[i].object)))
+ bb->flags |= BB_DIRTY;
+
num_changes = 0;
return 1;
}
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 9676dcde5a0..7cf0c96db9a 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -240,13 +240,14 @@ enum dump_file_index
DFI_ssa_ccp,
DFI_ssa_dce,
DFI_ussa,
+ DFI_null,
DFI_cse,
DFI_addressof,
DFI_gcse,
DFI_loop,
- DFI_cse2,
DFI_cfg,
DFI_bp,
+ DFI_cse2,
DFI_life,
DFI_combine,
DFI_ce,
@@ -272,7 +273,7 @@ enum dump_file_index
Remaining -d letters:
- " o q u "
+ " o q "
" H JK OPQ TUV YZ"
*/
@@ -286,13 +287,14 @@ static struct dump_file_info dump_file[DFI_MAX] =
{ "ssaccp", 'W', 1, 0, 0 },
{ "ssadce", 'X', 1, 0, 0 },
{ "ussa", 'e', 1, 0, 0 }, /* Yes, duplicate enable switch. */
+ { "null", 'u', 0, 0, 0 },
{ "cse", 's', 0, 0, 0 },
{ "addressof", 'F', 0, 0, 0 },
{ "gcse", 'G', 1, 0, 0 },
{ "loop", 'L', 1, 0, 0 },
- { "cse2", 't', 1, 0, 0 },
{ "cfg", 'f', 1, 0, 0 },
{ "bp", 'b', 1, 0, 0 },
+ { "cse2", 't', 1, 0, 0 },
{ "life", 'f', 1, 0, 0 }, /* Yes, duplicate enable switch. */
{ "combine", 'c', 1, 0, 0 },
{ "ce", 'C', 1, 0, 0 },
@@ -2608,6 +2610,8 @@ rest_of_compilation (decl)
reg_scan (insns, max_reg_num (), 0);
rebuild_jump_labels (insns);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ if (rtl_dump_file)
+ dump_flow_info (rtl_dump_file);
cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP);
/* CFG is no longer maintained up-to-date. */
@@ -2616,11 +2620,11 @@ rest_of_compilation (decl)
purge_line_number_notes (insns);
timevar_pop (TV_JUMP);
+ close_dump_file (DFI_jump, print_rtl, insns);
/* Now is when we stop if -fsyntax-only and -Wreturn-type. */
if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl))
{
- close_dump_file (DFI_jump, print_rtl, insns);
goto exit_rest_of_compilation;
}
@@ -2697,23 +2701,22 @@ rest_of_compilation (decl)
if (optimize > 0)
{
+ open_dump_file (DFI_null, decl);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ if (rtl_dump_file)
+ dump_flow_info (rtl_dump_file);
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP
| (flag_thread_jumps ? CLEANUP_THREADING : 0));
- /* ??? Run if-conversion before delete_null_pointer_checks,
- since the later does not preserve the CFG. This should
- be changed -- no since converting if's that are going to
- be deleted. */
- timevar_push (TV_IFCVT);
- if_convert (0);
- timevar_pop (TV_IFCVT);
-
- /* CFG is no longer maintained up-to-date. */
- free_bb_for_insn ();
/* Try to identify useless null pointer tests and delete them. */
if (flag_delete_null_pointer_checks)
delete_null_pointer_checks (insns);
+
+ timevar_push (TV_IFCVT);
+ if_convert (0);
+ timevar_pop (TV_IFCVT);
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
+ close_dump_file (DFI_null, print_rtl_with_bb, insns);
}
/* Jump optimization, and the removal of NULL pointer checks, may
@@ -2722,9 +2725,11 @@ rest_of_compilation (decl)
maximum instruction UID, so if we can reduce the maximum UID
we'll save big on memory. */
renumber_insns (rtl_dump_file);
+ if (optimize)
+ compute_bb_for_insn (get_max_uid ());
timevar_pop (TV_JUMP);
- close_dump_file (DFI_jump, print_rtl, insns);
+ close_dump_file (DFI_jump, print_rtl_with_bb, insns);
ggc_collect ();
@@ -2736,36 +2741,32 @@ rest_of_compilation (decl)
if (optimize > 0)
{
open_dump_file (DFI_cse, decl);
+ if (rtl_dump_file)
+ dump_flow_info (rtl_dump_file);
timevar_push (TV_CSE);
reg_scan (insns, max_reg_num (), 1);
tem = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
+ if (tem)
+ rebuild_jump_labels (insns);
+ purge_all_dead_edges (0);
/* If we are not running more CSE passes, then we are no longer
expecting CSE to be run. But always rerun it in a cheap mode. */
cse_not_expected = !flag_rerun_cse_after_loop && !flag_gcse;
if (tem || optimize > 1)
- {
- timevar_push (TV_JUMP);
- rebuild_jump_labels (insns);
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
- timevar_pop (TV_JUMP);
- /* CFG is no longer maintained up-to-date. */
- free_bb_for_insn ();
- }
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
/* Run this after jump optmizations remove all the unreachable code
so that unreachable code will not keep values live. */
- delete_trivially_dead_insns (insns, max_reg_num (), 0);
+ delete_trivially_dead_insns (insns, max_reg_num (), 1);
/* Try to identify useless null pointer tests and delete them. */
if (flag_delete_null_pointer_checks || flag_thread_jumps)
{
timevar_push (TV_JUMP);
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP
| (flag_thread_jumps ? CLEANUP_THREADING : 0));
@@ -2773,21 +2774,23 @@ rest_of_compilation (decl)
if (flag_delete_null_pointer_checks)
delete_null_pointer_checks (insns);
/* CFG is no longer maintained up-to-date. */
- free_bb_for_insn ();
timevar_pop (TV_JUMP);
}
/* The second pass of jump optimization is likely to have
removed a bunch more instructions. */
renumber_insns (rtl_dump_file);
+ compute_bb_for_insn (get_max_uid ());
timevar_pop (TV_CSE);
- close_dump_file (DFI_cse, print_rtl, insns);
+ close_dump_file (DFI_cse, print_rtl_with_bb, insns);
}
open_dump_file (DFI_addressof, decl);
purge_addressof (insns);
+ if (optimize)
+ purge_all_dead_edges (0);
reg_scan (insns, max_reg_num (), 1);
close_dump_file (DFI_addressof, print_rtl, insns);
@@ -2804,7 +2807,6 @@ rest_of_compilation (decl)
timevar_push (TV_GCSE);
open_dump_file (DFI_gcse, decl);
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
tem = gcse_main (insns, rtl_dump_file);
rebuild_jump_labels (insns);
@@ -2813,8 +2815,6 @@ rest_of_compilation (decl)
save_cfj = flag_cse_follow_jumps;
flag_cse_skip_blocks = flag_cse_follow_jumps = 0;
- /* CFG is no longer maintained up-to-date. */
- free_bb_for_insn ();
/* If -fexpensive-optimizations, re-run CSE to clean up things done
by gcse. */
if (flag_expensive_optimizations)
@@ -2822,6 +2822,7 @@ rest_of_compilation (decl)
timevar_push (TV_CSE);
reg_scan (insns, max_reg_num (), 1);
tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
+ purge_all_dead_edges (0);
timevar_pop (TV_CSE);
cse_not_expected = !flag_rerun_cse_after_loop;
}
@@ -2833,11 +2834,8 @@ rest_of_compilation (decl)
tem = tem2 = 0;
timevar_push (TV_JUMP);
rebuild_jump_labels (insns);
- delete_trivially_dead_insns (insns, max_reg_num (), 0);
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ delete_trivially_dead_insns (insns, max_reg_num (), 1);
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
- /* CFG is no longer maintained up-to-date. */
- free_bb_for_insn ();
timevar_pop (TV_JUMP);
if (flag_expensive_optimizations)
@@ -2845,16 +2843,20 @@ rest_of_compilation (decl)
timevar_push (TV_CSE);
reg_scan (insns, max_reg_num (), 1);
tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
+ purge_all_dead_edges (0);
timevar_pop (TV_CSE);
}
}
- close_dump_file (DFI_gcse, print_rtl, insns);
+ close_dump_file (DFI_gcse, print_rtl_with_bb, insns);
timevar_pop (TV_GCSE);
ggc_collect ();
flag_cse_skip_blocks = save_csb;
flag_cse_follow_jumps = save_cfj;
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
+#endif
}
/* Move constant computations out of loops. */
@@ -2863,6 +2865,7 @@ rest_of_compilation (decl)
{
timevar_push (TV_LOOP);
open_dump_file (DFI_loop, decl);
+ /* CFG is no longer maintained up-to-date. */
free_bb_for_insn ();
if (flag_rerun_loop_opt)
@@ -2888,62 +2891,98 @@ rest_of_compilation (decl)
(flag_unroll_loops ? LOOP_UNROLL : 0) | LOOP_BCT
| (flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0));
+ /* Loop can create trivially dead instructions. */
+ delete_trivially_dead_insns (insns, max_reg_num (), 0);
close_dump_file (DFI_loop, print_rtl, insns);
timevar_pop (TV_LOOP);
ggc_collect ();
}
+ /* Do control and data flow analysis; wrote some of the results to
+ the dump file. */
+
+ timevar_push (TV_FLOW);
+ open_dump_file (DFI_cfg, decl);
+
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ if (rtl_dump_file)
+ dump_flow_info (rtl_dump_file);
+ cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0)
+ | (flag_thread_jumps ? CLEANUP_THREADING : 0));
+
+ /* It may make more sense to mark constant functions after dead code is
+ eliminated by life_analyzis, but we need to do it early, as -fprofile-arcs
+ may insert code making function non-constant, but we still must consider
+ it as constant, otherwise -fbranch-probabilities will not read data back.
+
+ life_analyzis rarely eliminates modification of external memory.
+ */
+ mark_constant_function ();
+
+ close_dump_file (DFI_cfg, print_rtl_with_bb, insns);
+
+ /* Do branch profiling and static profile estimation passes. */
+ if (optimize > 0 || profile_arc_flag || flag_test_coverage
+ || flag_branch_probabilities)
+ {
+ struct loops loops;
+
+ timevar_push (TV_BRANCH_PROB);
+ open_dump_file (DFI_bp, decl);
+ if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
+ branch_prob ();
+
+ /* Discover and record the loop depth at the head of each basic
+ block. The loop infrastructure does the real job for us. */
+ flow_loops_find (&loops, LOOP_TREE);
+
+ /* Estimate using heuristics if no profiling info is available. */
+ if (flag_guess_branch_prob)
+ estimate_probability (&loops);
+
+ if (rtl_dump_file)
+ flow_loops_dump (&loops, rtl_dump_file, NULL, 0);
+
+ flow_loops_free (&loops);
+ close_dump_file (DFI_bp, print_rtl_with_bb, insns);
+ timevar_pop (TV_BRANCH_PROB);
+ }
+
if (optimize > 0)
{
timevar_push (TV_CSE2);
open_dump_file (DFI_cse2, decl);
+ if (rtl_dump_file)
+ dump_flow_info (rtl_dump_file);
if (flag_rerun_cse_after_loop)
{
- /* Running another jump optimization pass before the second
- cse pass sometimes simplifies the RTL enough to allow
- the second CSE pass to do a better job. Jump_optimize can change
- max_reg_num so we must rerun reg_scan afterwards.
- ??? Rework to not call reg_scan so often. */
timevar_push (TV_JUMP);
- /* The previous call to loop_optimize makes some instructions
- trivially dead. We delete those instructions now in the
- hope that doing so will make the heuristics in jump work
- better and possibly speed up compilation. */
- delete_trivially_dead_insns (insns, max_reg_num (), 0);
-
reg_scan (insns, max_reg_num (), 0);
timevar_push (TV_IFCVT);
-
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
cleanup_cfg (CLEANUP_EXPENSIVE);
if_convert (0);
-
timevar_pop(TV_IFCVT);
timevar_pop (TV_JUMP);
-
/* CFG is no longer maintained up-to-date. */
- free_bb_for_insn ();
reg_scan (insns, max_reg_num (), 0);
tem = cse_main (insns, max_reg_num (), 1, rtl_dump_file);
+ purge_all_dead_edges (0);
if (tem)
{
timevar_push (TV_JUMP);
rebuild_jump_labels (insns);
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
cleanup_cfg (CLEANUP_EXPENSIVE);
- /* CFG is no longer maintained up-to-date. */
- free_bb_for_insn ();
timevar_pop (TV_JUMP);
}
}
- close_dump_file (DFI_cse2, print_rtl, insns);
+ close_dump_file (DFI_cse2, print_rtl_with_bb, insns);
timevar_pop (TV_CSE2);
ggc_collect ();
@@ -2951,60 +2990,17 @@ rest_of_compilation (decl)
cse_not_expected = 1;
+ close_dump_file (DFI_life, print_rtl_with_bb, insns);
regclass_init ();
- /* Do control and data flow analysis; wrote some of the results to
- the dump file. */
-
- timevar_push (TV_FLOW);
- open_dump_file (DFI_cfg, decl);
-
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
- cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0)
- | (flag_thread_jumps ? CLEANUP_THREADING : 0));
check_function_return_warnings ();
- /* It may make more sense to mark constant functions after dead code is
- eliminated by life_analyzis, but we need to do it early, as -fprofile-arcs
- may insert code making function non-constant, but we still must consider
- it as constant, otherwise -fbranch-probabilities will not read data back.
-
- life_analyzis rarely eliminates modification of external memory.
- */
- mark_constant_function ();
-
- close_dump_file (DFI_cfg, print_rtl_with_bb, insns);
-
- if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
- {
- timevar_push (TV_BRANCH_PROB);
- open_dump_file (DFI_bp, decl);
-
- branch_prob ();
-
- close_dump_file (DFI_bp, print_rtl_with_bb, insns);
- timevar_pop (TV_BRANCH_PROB);
- }
-
- open_dump_file (DFI_life, decl);
- if (optimize)
- {
- struct loops loops;
-
- /* Discover and record the loop depth at the head of each basic
- block. The loop infrastructure does the real job for us. */
- flow_loops_find (&loops, LOOP_TREE);
-
- /* Estimate using heuristics if no profiling info is available. */
- if (flag_guess_branch_prob)
- estimate_probability (&loops);
-
- if (rtl_dump_file)
- flow_loops_dump (&loops, rtl_dump_file, NULL, 0);
-
- flow_loops_free (&loops);
- }
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
+#endif
life_analysis (insns, rtl_dump_file, PROP_FINAL);
+ if (optimize)
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
timevar_pop (TV_FLOW);
no_new_pseudos = 1;
@@ -3018,12 +3014,14 @@ rest_of_compilation (decl)
if (optimize)
{
+ clear_bb_flags ();
if (initialize_uninitialized_subregs ())
{
/* Insns were inserted, so things might look a bit different. */
insns = get_insns ();
- life_analysis (insns, rtl_dump_file,
- (PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES));
+ update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
+ PROP_LOG_LINKS | PROP_REG_INFO
+ | PROP_DEATH_NOTES);
}
}
@@ -3089,6 +3087,7 @@ rest_of_compilation (decl)
regmove_optimize (insns, max_reg_num (), rtl_dump_file);
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
close_dump_file (DFI_regmove, print_rtl_with_bb, insns);
timevar_pop (TV_REGMOVE);
@@ -3107,13 +3106,7 @@ rest_of_compilation (decl)
timevar_push (TV_MODE_SWITCH);
no_new_pseudos = 0;
- if (optimize_mode_switching (NULL))
- {
- /* We did work, and so had to regenerate global life information.
- Take advantage of this and don't re-recompute register life
- information below. */
- register_life_up_to_date = 1;
- }
+ optimize_mode_switching (NULL);
no_new_pseudos = 1;
timevar_pop (TV_MODE_SWITCH);