basic-block.h (CLEANUP_PRE_SIBCALL): New constant.
* basic-block.h (CLEANUP_PRE_SIBCALL): New constant. * except.c (finish_eh_generation): Update call of cleanup_cfg; do rebuild_jump_labels instead of jump_optimize * sibcall.c (optimize_sibling_and_tail_recursive_call): Likewise. * toplev.c (rest_of_compulation): Likewise for -Wreturn_type. * flow.c (try_optimize_cfg): Remove unneeded code_labels. * flow.c: Include timevar.h (find_basic_block): Push/pop timevar; (cleanup_cfg): Likewise. * timevar.def (TV_CFG, TV_CLEANUP_CFG): New. * Makefile: Add dependencies on timevar.h * integrate.c (save_for_inline): Kill all BASIC_BLOCK notes. (copy_insn_list): Avoid killing of BASIC_BLOCK notes. * rtl.h (delete_trivially_dead_insns): Add new parameter. * toplev.c (rest_of_compilation): Update calls. * cse.c (set_live_p, insn_live_p, dead_libcall_p): Break out from ... (delete_trivially_dead_insns): ... here; accept new argument preserve_basic_blocks; preserve basic blocks if set. * reg-stack.c (stack_regs_mentioned): Return 0 if stack_regs_mentioned_data is not initialized. (reg_to_stack): Make stack_regs_mentioned survive after the reg-stack is completted; do not call cleanup_cfg. * toplev.c (rest_of_compilation): Do cleanup_cfg before bb-reorder; make cleanup_cfg after bb-reorder to output to debug file. From-SVN: r44056
This commit is contained in:
parent
ccef9ef510
commit
4793dca158
@ -1,3 +1,34 @@
|
||||
Mon Jul 16 22:48:00 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* basic-block.h (CLEANUP_PRE_SIBCALL): New constant.
|
||||
* except.c (finish_eh_generation): Update call of cleanup_cfg;
|
||||
do rebuild_jump_labels instead of jump_optimize
|
||||
* sibcall.c (optimize_sibling_and_tail_recursive_call): Likewise.
|
||||
* toplev.c (rest_of_compulation): Likewise for -Wreturn_type.
|
||||
* flow.c (try_optimize_cfg): Remove unneeded code_labels.
|
||||
|
||||
* flow.c: Include timevar.h
|
||||
(find_basic_block): Push/pop timevar;
|
||||
(cleanup_cfg): Likewise.
|
||||
* timevar.def (TV_CFG, TV_CLEANUP_CFG): New.
|
||||
* Makefile: Add dependencies on timevar.h
|
||||
|
||||
* integrate.c (save_for_inline): Kill all BASIC_BLOCK notes.
|
||||
(copy_insn_list): Avoid killing of BASIC_BLOCK notes.
|
||||
|
||||
* rtl.h (delete_trivially_dead_insns): Add new parameter.
|
||||
* toplev.c (rest_of_compilation): Update calls.
|
||||
* cse.c (set_live_p, insn_live_p, dead_libcall_p): Break out from ...
|
||||
(delete_trivially_dead_insns): ... here; accept new argument
|
||||
preserve_basic_blocks; preserve basic blocks if set.
|
||||
|
||||
* reg-stack.c (stack_regs_mentioned): Return 0 if
|
||||
stack_regs_mentioned_data is not initialized.
|
||||
(reg_to_stack): Make stack_regs_mentioned survive after the
|
||||
reg-stack is completted; do not call cleanup_cfg.
|
||||
* toplev.c (rest_of_compilation): Do cleanup_cfg before bb-reorder;
|
||||
make cleanup_cfg after bb-reorder to output to debug file.
|
||||
|
||||
2001-07-16 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* regclass.c (init_reg_sets): Use only 32 bits per initializer
|
||||
|
@ -540,6 +540,8 @@ enum update_life_extent
|
||||
#define CLEANUP_CROSSJUMP 2 /* Do crossjumping. */
|
||||
#define CLEANUP_POST_REGSTACK 4 /* We run after reg-stack and need
|
||||
to care REG_DEAD notes. */
|
||||
#define CLEANUP_PRE_SIBCALL 8 /* Do not get confused by code hidden
|
||||
inside call_placeholders.. */
|
||||
/* Flags for loop discovery. */
|
||||
|
||||
#define LOOP_TREE 1 /* Build loop hierarchy tree. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* config.in. Generated automatically from configure.in by autoheader 2.13. */
|
||||
/* config.in. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
#undef const
|
||||
|
281
gcc/cse.c
281
gcc/cse.c
@ -689,6 +689,9 @@ static struct cse_reg_info * get_cse_reg_info PARAMS ((unsigned int));
|
||||
static int check_dependence PARAMS ((rtx *, void *));
|
||||
|
||||
static void flush_hash_table PARAMS ((void));
|
||||
static bool insn_live_p PARAMS ((rtx, int *));
|
||||
static bool set_live_p PARAMS ((rtx, int *));
|
||||
static bool dead_libcall_p PARAMS ((rtx, int *));
|
||||
|
||||
/* Dump the expressions in the equivalence class indicated by CLASSP.
|
||||
This function is used only for debugging. */
|
||||
@ -7481,6 +7484,98 @@ count_reg_usage (x, counts, dest, incr)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true if set is live. */
|
||||
static bool
|
||||
set_live_p (set, counts)
|
||||
rtx set;
|
||||
int *counts;
|
||||
{
|
||||
#ifdef HAVE_cc0
|
||||
rtx tem;
|
||||
#endif
|
||||
|
||||
if (set_noop_p (set))
|
||||
;
|
||||
|
||||
#ifdef HAVE_cc0
|
||||
else if (GET_CODE (SET_DEST (set)) == CC0
|
||||
&& !side_effects_p (SET_SRC (set))
|
||||
&& ((tem = next_nonnote_insn (insn)) == 0
|
||||
|| !INSN_P (tem)
|
||||
|| !reg_referenced_p (cc0_rtx, PATTERN (tem))))
|
||||
return false;
|
||||
#endif
|
||||
else if (GET_CODE (SET_DEST (set)) != REG
|
||||
|| REGNO (SET_DEST (set)) < FIRST_PSEUDO_REGISTER
|
||||
|| counts[REGNO (SET_DEST (set))] != 0
|
||||
|| side_effects_p (SET_SRC (set))
|
||||
/* An ADDRESSOF expression can turn into a use of the
|
||||
internal arg pointer, so always consider the
|
||||
internal arg pointer live. If it is truly dead,
|
||||
flow will delete the initializing insn. */
|
||||
|| (SET_DEST (set) == current_function_internal_arg_pointer))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return true if insn is live. */
|
||||
|
||||
static bool
|
||||
insn_live_p (insn, counts)
|
||||
rtx insn;
|
||||
int *counts;
|
||||
{
|
||||
int i;
|
||||
if (GET_CODE (PATTERN (insn)) == SET)
|
||||
return set_live_p (PATTERN (insn), counts);
|
||||
else if (GET_CODE (PATTERN (insn)) == PARALLEL)
|
||||
for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
|
||||
{
|
||||
rtx elt = XVECEXP (PATTERN (insn), 0, i);
|
||||
|
||||
if (GET_CODE (elt) == SET)
|
||||
{
|
||||
if (set_live_p (elt, counts))
|
||||
return true;
|
||||
}
|
||||
else if (GET_CODE (elt) != CLOBBER && GET_CODE (elt) != USE)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Return true if libcall is dead as a whole. */
|
||||
|
||||
static bool
|
||||
dead_libcall_p (insn, counts)
|
||||
rtx insn;
|
||||
int *counts;
|
||||
{
|
||||
rtx note;
|
||||
/* See if there's a REG_EQUAL note on this insn and try to
|
||||
replace the source with the REG_EQUAL expression.
|
||||
|
||||
We assume that insns with REG_RETVALs can only be reg->reg
|
||||
copies at this point. */
|
||||
note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
|
||||
if (note)
|
||||
{
|
||||
rtx set = single_set (insn);
|
||||
rtx new = simplify_rtx (XEXP (note, 0));
|
||||
|
||||
if (!new)
|
||||
new = XEXP (note, 0);
|
||||
|
||||
if (set && validate_change (insn, &SET_SRC (set), new, 0))
|
||||
{
|
||||
remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Scan all the insns and delete any that are dead; i.e., they store a register
|
||||
that is never used or they copy a register to itself.
|
||||
|
||||
@ -7490,17 +7585,16 @@ count_reg_usage (x, counts, dest, incr)
|
||||
remaining passes of the compilation are also sped up. */
|
||||
|
||||
void
|
||||
delete_trivially_dead_insns (insns, nreg)
|
||||
delete_trivially_dead_insns (insns, nreg, preserve_basic_blocks)
|
||||
rtx insns;
|
||||
int nreg;
|
||||
int preserve_basic_blocks;
|
||||
{
|
||||
int *counts;
|
||||
rtx insn, prev;
|
||||
#ifdef HAVE_cc0
|
||||
rtx tem;
|
||||
#endif
|
||||
int i;
|
||||
int in_libcall = 0, dead_libcall = 0;
|
||||
basic_block bb;
|
||||
|
||||
/* First count the number of times each register is used. */
|
||||
counts = (int *) xcalloc (nreg, sizeof (int));
|
||||
@ -7518,124 +7612,89 @@ delete_trivially_dead_insns (insns, nreg)
|
||||
if (! INSN_P (insn))
|
||||
insn = prev_real_insn (insn);
|
||||
|
||||
for (; insn; insn = prev)
|
||||
{
|
||||
int live_insn = 0;
|
||||
rtx note;
|
||||
if (!preserve_basic_blocks)
|
||||
for (; insn; insn = prev)
|
||||
{
|
||||
int live_insn = 0;
|
||||
rtx note;
|
||||
|
||||
prev = prev_real_insn (insn);
|
||||
prev = prev_real_insn (insn);
|
||||
|
||||
/* Don't delete any insns that are part of a libcall block unless
|
||||
we can delete the whole libcall block.
|
||||
/* Don't delete any insns that are part of a libcall block unless
|
||||
we can delete the whole libcall block.
|
||||
|
||||
Flow or loop might get confused if we did that. Remember
|
||||
that we are scanning backwards. */
|
||||
if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
|
||||
Flow or loop might get confused if we did that. Remember
|
||||
that we are scanning backwards. */
|
||||
if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
|
||||
{
|
||||
in_libcall = 1;
|
||||
live_insn = 1;
|
||||
dead_libcall = dead_libcall_p (insn, counts);
|
||||
}
|
||||
else if (in_libcall)
|
||||
live_insn = ! dead_libcall;
|
||||
else
|
||||
live_insn = insn_live_p (insn, counts);
|
||||
|
||||
/* If this is a dead insn, delete it and show registers in it aren't
|
||||
being used. */
|
||||
|
||||
if (! live_insn)
|
||||
{
|
||||
count_reg_usage (insn, counts, NULL_RTX, -1);
|
||||
delete_insn (insn);
|
||||
}
|
||||
|
||||
if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
|
||||
{
|
||||
in_libcall = 0;
|
||||
dead_libcall = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
for (bb = BASIC_BLOCK (i), insn = bb->end; insn != bb->head; insn = prev)
|
||||
{
|
||||
in_libcall = 1;
|
||||
live_insn = 1;
|
||||
dead_libcall = 0;
|
||||
int live_insn = 0;
|
||||
rtx note;
|
||||
|
||||
/* See if there's a REG_EQUAL note on this insn and try to
|
||||
replace the source with the REG_EQUAL expression.
|
||||
prev = PREV_INSN (insn);
|
||||
if (!INSN_P (insn))
|
||||
continue;
|
||||
|
||||
We assume that insns with REG_RETVALs can only be reg->reg
|
||||
copies at this point. */
|
||||
note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
|
||||
if (note)
|
||||
/* Don't delete any insns that are part of a libcall block unless
|
||||
we can delete the whole libcall block.
|
||||
|
||||
Flow or loop might get confused if we did that. Remember
|
||||
that we are scanning backwards. */
|
||||
if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
|
||||
{
|
||||
rtx set = single_set (insn);
|
||||
rtx new = simplify_rtx (XEXP (note, 0));
|
||||
in_libcall = 1;
|
||||
live_insn = 1;
|
||||
dead_libcall = dead_libcall_p (insn, counts);
|
||||
}
|
||||
else if (in_libcall)
|
||||
live_insn = ! dead_libcall;
|
||||
else
|
||||
live_insn = insn_live_p (insn, counts);
|
||||
|
||||
if (!new)
|
||||
new = XEXP (note, 0);
|
||||
/* If this is a dead insn, delete it and show registers in it aren't
|
||||
being used. */
|
||||
|
||||
if (set && validate_change (insn, &SET_SRC (set), new, 0))
|
||||
{
|
||||
remove_note (insn,
|
||||
find_reg_note (insn, REG_RETVAL, NULL_RTX));
|
||||
dead_libcall = 1;
|
||||
}
|
||||
if (! live_insn)
|
||||
{
|
||||
count_reg_usage (insn, counts, NULL_RTX, -1);
|
||||
if (insn == bb->end)
|
||||
bb->end = PREV_INSN (insn);
|
||||
flow_delete_insn (insn);
|
||||
}
|
||||
|
||||
if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
|
||||
{
|
||||
in_libcall = 0;
|
||||
dead_libcall = 0;
|
||||
}
|
||||
}
|
||||
else if (in_libcall)
|
||||
live_insn = ! dead_libcall;
|
||||
else if (GET_CODE (PATTERN (insn)) == SET)
|
||||
{
|
||||
if (set_noop_p (PATTERN (insn)))
|
||||
;
|
||||
|
||||
#ifdef HAVE_cc0
|
||||
else if (GET_CODE (SET_DEST (PATTERN (insn))) == CC0
|
||||
&& ! side_effects_p (SET_SRC (PATTERN (insn)))
|
||||
&& ((tem = next_nonnote_insn (insn)) == 0
|
||||
|| ! INSN_P (tem)
|
||||
|| ! reg_referenced_p (cc0_rtx, PATTERN (tem))))
|
||||
;
|
||||
#endif
|
||||
else if (GET_CODE (SET_DEST (PATTERN (insn))) != REG
|
||||
|| REGNO (SET_DEST (PATTERN (insn))) < FIRST_PSEUDO_REGISTER
|
||||
|| counts[REGNO (SET_DEST (PATTERN (insn)))] != 0
|
||||
|| side_effects_p (SET_SRC (PATTERN (insn)))
|
||||
/* An ADDRESSOF expression can turn into a use of the
|
||||
internal arg pointer, so always consider the
|
||||
internal arg pointer live. If it is truly dead,
|
||||
flow will delete the initializing insn. */
|
||||
|| (SET_DEST (PATTERN (insn))
|
||||
== current_function_internal_arg_pointer))
|
||||
live_insn = 1;
|
||||
}
|
||||
else if (GET_CODE (PATTERN (insn)) == PARALLEL)
|
||||
for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
|
||||
{
|
||||
rtx elt = XVECEXP (PATTERN (insn), 0, i);
|
||||
|
||||
if (GET_CODE (elt) == SET)
|
||||
{
|
||||
if (set_noop_p (elt))
|
||||
;
|
||||
|
||||
#ifdef HAVE_cc0
|
||||
else if (GET_CODE (SET_DEST (elt)) == CC0
|
||||
&& ! side_effects_p (SET_SRC (elt))
|
||||
&& ((tem = next_nonnote_insn (insn)) == 0
|
||||
|| ! INSN_P (tem)
|
||||
|| ! reg_referenced_p (cc0_rtx, PATTERN (tem))))
|
||||
;
|
||||
#endif
|
||||
else if (GET_CODE (SET_DEST (elt)) != REG
|
||||
|| REGNO (SET_DEST (elt)) < FIRST_PSEUDO_REGISTER
|
||||
|| counts[REGNO (SET_DEST (elt))] != 0
|
||||
|| side_effects_p (SET_SRC (elt))
|
||||
/* An ADDRESSOF expression can turn into a use of the
|
||||
internal arg pointer, so always consider the
|
||||
internal arg pointer live. If it is truly dead,
|
||||
flow will delete the initializing insn. */
|
||||
|| (SET_DEST (elt)
|
||||
== current_function_internal_arg_pointer))
|
||||
live_insn = 1;
|
||||
}
|
||||
else if (GET_CODE (elt) != CLOBBER && GET_CODE (elt) != USE)
|
||||
live_insn = 1;
|
||||
}
|
||||
else
|
||||
live_insn = 1;
|
||||
|
||||
/* If this is a dead insn, delete it and show registers in it aren't
|
||||
being used. */
|
||||
|
||||
if (! live_insn)
|
||||
{
|
||||
count_reg_usage (insn, counts, NULL_RTX, -1);
|
||||
delete_insn (insn);
|
||||
}
|
||||
|
||||
if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
|
||||
{
|
||||
in_libcall = 0;
|
||||
dead_libcall = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up. */
|
||||
free (counts);
|
||||
|
@ -2347,7 +2347,7 @@ finish_eh_generation ()
|
||||
connect many of the handlers, and then type information will not
|
||||
be effective. Still, this is a win over previous implementations. */
|
||||
|
||||
jump_optimize_minimal (get_insns ());
|
||||
rebuild_jump_labels (get_insns ());
|
||||
find_basic_blocks (get_insns (), max_reg_num (), 0);
|
||||
cleanup_cfg (0);
|
||||
|
||||
@ -2370,7 +2370,7 @@ finish_eh_generation ()
|
||||
|
||||
/* We've totally changed the CFG. Start over. */
|
||||
find_exception_handler_labels ();
|
||||
jump_optimize_minimal (get_insns ());
|
||||
rebuild_jump_labels (get_insns ());
|
||||
find_basic_blocks (get_insns (), max_reg_num (), 0);
|
||||
cleanup_cfg (0);
|
||||
}
|
||||
|
33
gcc/flow.c
33
gcc/flow.c
@ -135,6 +135,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "recog.h"
|
||||
#include "expr.h"
|
||||
#include "ssa.h"
|
||||
#include "timevar.h"
|
||||
|
||||
#include "obstack.h"
|
||||
#include "splay-tree.h"
|
||||
@ -499,6 +500,7 @@ find_basic_blocks (f, nregs, file)
|
||||
FILE *file ATTRIBUTE_UNUSED;
|
||||
{
|
||||
int max_uid;
|
||||
timevar_push (TV_CFG);
|
||||
|
||||
/* Flush out existing data. */
|
||||
if (basic_block_info != NULL)
|
||||
@ -556,6 +558,7 @@ find_basic_blocks (f, nregs, file)
|
||||
#ifdef ENABLE_CHECKING
|
||||
verify_flow_info ();
|
||||
#endif
|
||||
timevar_pop (TV_CFG);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1002,6 +1005,7 @@ void
|
||||
cleanup_cfg (mode)
|
||||
int mode;
|
||||
{
|
||||
timevar_push (TV_CLEANUP_CFG);
|
||||
delete_unreachable_blocks ();
|
||||
if (try_optimize_cfg (mode))
|
||||
delete_unreachable_blocks ();
|
||||
@ -1010,6 +1014,7 @@ cleanup_cfg (mode)
|
||||
/* Kill the data we won't maintain. */
|
||||
free_EXPR_LIST_list (&label_value_list);
|
||||
free_EXPR_LIST_list (&tail_recursion_label_list);
|
||||
timevar_pop (TV_CLEANUP_CFG);
|
||||
}
|
||||
|
||||
/* Create a new basic block consisting of the instructions between
|
||||
@ -2960,6 +2965,14 @@ merge_blocks (e, b, c, mode)
|
||||
int c_has_outgoing_fallthru;
|
||||
int b_has_incoming_fallthru;
|
||||
|
||||
/* Avoid overactive code motion, as the forwarder blocks should eb
|
||||
eliminated by the edge redirection instead. Only exception is the
|
||||
case b is an forwarder block and c has no fallthru edge, but no
|
||||
optimizers should be confused by this extra jump and we are about
|
||||
to kill the jump in bb_reorder pass instead. */
|
||||
if (forwarder_block_p (b) || forwarder_block_p (c))
|
||||
return 0;
|
||||
|
||||
/* We must make sure to not munge nesting of exception regions,
|
||||
lexical blocks, and loop notes.
|
||||
|
||||
@ -3688,6 +3701,26 @@ try_optimize_cfg (mode)
|
||||
b = c;
|
||||
}
|
||||
|
||||
/* Remove code labels no longer used.
|
||||
Don't do the optimization before sibling calls are discovered,
|
||||
as some branches may be hidden inside CALL_PLACEHOLDERs. */
|
||||
if (!(mode & CLEANUP_PRE_SIBCALL)
|
||||
&& b->pred->pred_next == NULL
|
||||
&& (b->pred->flags & EDGE_FALLTHRU)
|
||||
&& GET_CODE (b->head) == CODE_LABEL
|
||||
/* If previous block does end with condjump jumping to next BB,
|
||||
we can't delete the label. */
|
||||
&& (b->pred->src == ENTRY_BLOCK_PTR
|
||||
|| !reg_mentioned_p (b->head, b->pred->src->end)))
|
||||
{
|
||||
rtx label = b->head;
|
||||
b->head = NEXT_INSN (b->head);
|
||||
flow_delete_insn_chain (label, label);
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Deleted label in block %i.\n",
|
||||
b->index);
|
||||
}
|
||||
|
||||
/* A loop because chains of blocks might be combineable. */
|
||||
while ((s = b->succ) != NULL
|
||||
&& s->succ_next == NULL
|
||||
|
@ -427,6 +427,13 @@ save_for_inline (fndecl)
|
||||
|
||||
argvec = initialize_for_inline (fndecl);
|
||||
|
||||
/* Delete basic block notes created by early run of find_basic_block.
|
||||
The notes would be later used by find_basic_blocks to reuse the memory
|
||||
for basic_block structures on already freed obstack. */
|
||||
for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
|
||||
if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK)
|
||||
delete_insn (insn);
|
||||
|
||||
/* If there are insns that copy parms from the stack into pseudo registers,
|
||||
those insns are not copied. `expand_inline_function' must
|
||||
emit the correct code to handle such things. */
|
||||
@ -1552,17 +1559,11 @@ copy_insn_list (insns, map, static_chain_value)
|
||||
discarded because it is important to have only one of
|
||||
each in the current function.
|
||||
|
||||
NOTE_INSN_DELETED notes aren't useful.
|
||||
|
||||
NOTE_INSN_BASIC_BLOCK is discarded because the saved bb
|
||||
pointer (which will soon be dangling) confuses flow's
|
||||
attempts to preserve bb structures during the compilation
|
||||
of a function. */
|
||||
NOTE_INSN_DELETED notes aren't useful. */
|
||||
|
||||
if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END
|
||||
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_BEG
|
||||
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED
|
||||
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK)
|
||||
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED)
|
||||
{
|
||||
copy = emit_note (NOTE_SOURCE_FILE (insn),
|
||||
NOTE_LINE_NUMBER (insn));
|
||||
|
@ -303,7 +303,7 @@ stack_regs_mentioned (insn)
|
||||
unsigned int uid, max;
|
||||
int test;
|
||||
|
||||
if (! INSN_P (insn))
|
||||
if (! INSN_P (insn) || !stack_regs_mentioned_data)
|
||||
return 0;
|
||||
|
||||
uid = INSN_UID (insn);
|
||||
@ -419,6 +419,13 @@ reg_to_stack (first, file)
|
||||
int max_uid;
|
||||
block_info bi;
|
||||
|
||||
/* Clean up previous run. */
|
||||
if (stack_regs_mentioned_data)
|
||||
{
|
||||
VARRAY_FREE (stack_regs_mentioned_data);
|
||||
stack_regs_mentioned_data = 0;
|
||||
}
|
||||
|
||||
if (!optimize)
|
||||
split_all_insns (0);
|
||||
|
||||
@ -479,11 +486,8 @@ reg_to_stack (first, file)
|
||||
VARRAY_CHAR_INIT (stack_regs_mentioned_data, max_uid + 1,
|
||||
"stack_regs_mentioned cache");
|
||||
|
||||
if (convert_regs (file) && optimize)
|
||||
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_CROSSJUMP | CLEANUP_POST_REGSTACK);
|
||||
convert_regs (file);
|
||||
|
||||
/* Clean up. */
|
||||
VARRAY_FREE (stack_regs_mentioned_data);
|
||||
free (bi);
|
||||
}
|
||||
|
||||
|
@ -1689,7 +1689,7 @@ struct cse_basic_block_data;
|
||||
|
||||
extern int rtx_cost PARAMS ((rtx, enum rtx_code));
|
||||
extern int address_cost PARAMS ((rtx, enum machine_mode));
|
||||
extern void delete_trivially_dead_insns PARAMS ((rtx, int));
|
||||
extern void delete_trivially_dead_insns PARAMS ((rtx, int, int));
|
||||
#ifdef BUFSIZ
|
||||
extern int cse_main PARAMS ((rtx, int, int, FILE *));
|
||||
#endif
|
||||
|
@ -565,11 +565,11 @@ optimize_sibling_and_tail_recursive_calls ()
|
||||
ahead and find all the EH labels. */
|
||||
find_exception_handler_labels ();
|
||||
|
||||
jump_optimize_minimal (insns);
|
||||
rebuild_jump_labels (insns);
|
||||
/* We need cfg information to determine which blocks are succeeded
|
||||
only by the epilogue. */
|
||||
find_basic_blocks (insns, max_reg_num (), 0);
|
||||
cleanup_cfg (0);
|
||||
cleanup_cfg (CLEANUP_PRE_SIBCALL);
|
||||
|
||||
/* If there are no basic blocks, then there is nothing to do. */
|
||||
if (n_basic_blocks == 0)
|
||||
|
@ -39,6 +39,10 @@ DEFTIMEVAR (TV_GC , "garbage collection")
|
||||
/* Time spent generating dump files. */
|
||||
DEFTIMEVAR (TV_DUMP , "dump files")
|
||||
|
||||
/* Time spent by constructing CFG. */
|
||||
DEFTIMEVAR (TV_CFG , "cfg construction")
|
||||
/* Time spent by cleaning up CFG. */
|
||||
DEFTIMEVAR (TV_CLEANUP_CFG , "cfg cleanup")
|
||||
/* Timing in various stages of the compiler. */
|
||||
DEFTIMEVAR (TV_CPP , "preprocessing")
|
||||
DEFTIMEVAR (TV_LEX , "lexical analysis")
|
||||
|
28
gcc/toplev.c
28
gcc/toplev.c
@ -2827,17 +2827,18 @@ rest_of_compilation (decl)
|
||||
if (DECL_DEFER_OUTPUT (decl))
|
||||
{
|
||||
/* If -Wreturn-type, we have to do a bit of compilation. We just
|
||||
want to call jump_optimize to figure out whether or not we can
|
||||
want to call cleanup the cfg to figure out whether or not we can
|
||||
fall off the end of the function; we do the minimum amount of
|
||||
work necessary to make that safe. And, we set optimize to zero
|
||||
to keep jump_optimize from working too hard. */
|
||||
work necessary to make that safe. */
|
||||
if (warn_return_type)
|
||||
{
|
||||
int saved_optimize = optimize;
|
||||
|
||||
optimize = 0;
|
||||
rebuild_jump_labels (insns);
|
||||
find_exception_handler_labels ();
|
||||
jump_optimize (insns, !JUMP_NOOP_MOVES, !JUMP_AFTER_REGSCAN);
|
||||
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
|
||||
cleanup_cfg (CLEANUP_PRE_SIBCALL);
|
||||
optimize = saved_optimize;
|
||||
}
|
||||
|
||||
@ -3092,7 +3093,7 @@ rest_of_compilation (decl)
|
||||
|
||||
/* 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 ());
|
||||
delete_trivially_dead_insns (insns, max_reg_num (), 0);
|
||||
|
||||
/* Try to identify useless null pointer tests and delete them. */
|
||||
if (flag_delete_null_pointer_checks)
|
||||
@ -3195,7 +3196,7 @@ rest_of_compilation (decl)
|
||||
trivially dead. We delete those instructions now in the
|
||||
hope that doing so will make the heuristics in loop work
|
||||
better and possibly speed up compilation. */
|
||||
delete_trivially_dead_insns (insns, max_reg_num ());
|
||||
delete_trivially_dead_insns (insns, max_reg_num (), 0);
|
||||
|
||||
/* The regscan pass is currently necessary as the alias
|
||||
analysis code depends on this information. */
|
||||
@ -3228,7 +3229,7 @@ rest_of_compilation (decl)
|
||||
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 ());
|
||||
delete_trivially_dead_insns (insns, max_reg_num (), 0);
|
||||
|
||||
reg_scan (insns, max_reg_num (), 0);
|
||||
jump_optimize (insns, !JUMP_NOOP_MOVES, JUMP_AFTER_REGSCAN);
|
||||
@ -3672,15 +3673,22 @@ rest_of_compilation (decl)
|
||||
|
||||
ggc_collect ();
|
||||
#endif
|
||||
if (optimize > 0 && flag_reorder_blocks)
|
||||
if (optimize > 0)
|
||||
{
|
||||
timevar_push (TV_REORDER_BLOCKS);
|
||||
open_dump_file (DFI_bbro, decl);
|
||||
|
||||
reorder_basic_blocks ();
|
||||
/* Last attempt to optimize CFG, as life analyzis possibly removed
|
||||
some instructions. */
|
||||
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
|
||||
| CLEANUP_CROSSJUMP);
|
||||
if (flag_reorder_blocks)
|
||||
{
|
||||
reorder_basic_blocks ();
|
||||
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK);
|
||||
}
|
||||
|
||||
close_dump_file (DFI_bbro, print_rtl_with_bb, insns);
|
||||
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK);
|
||||
timevar_pop (TV_REORDER_BLOCKS);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user