diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-07-16 20:54:44 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-07-16 20:54:44 +0000 |
commit | 6d866f03ce390aa6f6be2c215b8a4cd5f9cdb0e8 (patch) | |
tree | f2d3118471d29556bb961862c3ae6d62df08e484 /gcc/cse.c | |
parent | 45b51429826bb7a81ef960b120d00b526d15215b (diff) | |
download | gcc-6d866f03ce390aa6f6be2c215b8a4cd5f9cdb0e8.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44056 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cse.c')
-rw-r--r-- | gcc/cse.c | 273 |
1 files changed, 166 insertions, 107 deletions
diff --git a/gcc/cse.c b/gcc/cse.c index 266f258d758..70360d86993 100644 --- a/gcc/cse.c +++ b/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; - - prev = prev_real_insn (insn); + if (!preserve_basic_blocks) + for (; insn; insn = prev) + { + int live_insn = 0; + rtx note; - /* Don't delete any insns that are part of a libcall block unless - we can delete the whole libcall block. + prev = prev_real_insn (insn); - 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 = 0; + /* Don't delete any insns that are part of a libcall block unless + we can delete the whole libcall block. - /* See if there's a REG_EQUAL note on this insn and try to - replace the source with the REG_EQUAL expression. + 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); - 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 this is a dead insn, delete it and show registers in it aren't + being used. */ - if (!new) - new = XEXP (note, 0); + if (! live_insn) + { + count_reg_usage (insn, counts, NULL_RTX, -1); + delete_insn (insn); + } - if (set && validate_change (insn, &SET_SRC (set), new, 0)) - { - remove_note (insn, - find_reg_note (insn, REG_RETVAL, NULL_RTX)); - dead_libcall = 1; - } - } - } - else if (in_libcall) - live_insn = ! dead_libcall; - else if (GET_CODE (PATTERN (insn)) == SET) + 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) { - if (set_noop_p (PATTERN (insn))) - ; + int live_insn = 0; + rtx note; -#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); + prev = PREV_INSN (insn); + if (!INSN_P (insn)) + continue; - if (GET_CODE (elt) == SET) - { - if (set_noop_p (elt)) - ; + /* Don't delete any insns that are part of a libcall block unless + we can delete the whole libcall block. -#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) + 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; - } - else - 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 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 (! 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; + if (find_reg_note (insn, REG_LIBCALL, NULL_RTX)) + { + in_libcall = 0; + dead_libcall = 0; + } } - } /* Clean up. */ free (counts); |