basic-block.h (BB_REACHABLE): Renumber.

* 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

From-SVN: r50127
This commit is contained in:
Jan Hubicka 2002-02-28 10:11:01 +00:00 committed by Jan Hubicka
parent bde131d34d
commit 38c1593d57
14 changed files with 276 additions and 230 deletions

View File

@ -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.

View File

@ -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));

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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. */

View File

@ -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.

View File

@ -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);

View File

@ -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. */

View File

@ -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);

View File

@ -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 ();

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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,71 +2891,14 @@ 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 ();
}
if (optimize > 0)
{
timevar_push (TV_CSE2);
open_dump_file (DFI_cse2, decl);
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);
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);
timevar_pop (TV_CSE2);
ggc_collect ();
}
cse_not_expected = 1;
regclass_init ();
/* Do control and data flow analysis; wrote some of the results to
the dump file. */
@ -2960,9 +2906,10 @@ rest_of_compilation (decl)
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));
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
@ -2975,22 +2922,17 @@ rest_of_compilation (decl)
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)
/* 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);
@ -3003,8 +2945,62 @@ rest_of_compilation (decl)
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)
{
timevar_push (TV_JUMP);
reg_scan (insns, max_reg_num (), 0);
timevar_push (TV_IFCVT);
cleanup_cfg (CLEANUP_EXPENSIVE);
if_convert (0);
timevar_pop(TV_IFCVT);
timevar_pop (TV_JUMP);
/* CFG is no longer maintained up-to-date. */
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);
cleanup_cfg (CLEANUP_EXPENSIVE);
timevar_pop (TV_JUMP);
}
}
close_dump_file (DFI_cse2, print_rtl_with_bb, insns);
timevar_pop (TV_CSE2);
ggc_collect ();
}
cse_not_expected = 1;
close_dump_file (DFI_life, print_rtl_with_bb, insns);
regclass_init ();
check_function_return_warnings ();
#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);