diff options
Diffstat (limited to 'gcc/cse.c')
-rw-r--r-- | gcc/cse.c | 89 |
1 files changed, 29 insertions, 60 deletions
diff --git a/gcc/cse.c b/gcc/cse.c index 557e8086d7f..7a05dad0307 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -37,6 +37,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "toplev.h" #include "output.h" #include "ggc.h" +#include "timevar.h" /* The basic idea of common subexpression elimination is to go through the code, keeping a record of expressions that would @@ -7605,81 +7606,42 @@ dead_libcall_p (insn) move dead invariants out of loops or make givs for dead quantities. The remaining passes of the compilation are also sped up. */ -void -delete_trivially_dead_insns (insns, nreg, preserve_basic_blocks) +int +delete_trivially_dead_insns (insns, nreg) rtx insns; int nreg; - int preserve_basic_blocks; { int *counts; rtx insn, prev; - int i; int in_libcall = 0, dead_libcall = 0; - basic_block bb; + int ndead = 0, nlastdead, niterations = 0; + timevar_push (TV_DELETE_TRIVIALLY_DEAD); /* First count the number of times each register is used. */ counts = (int *) xcalloc (nreg, sizeof (int)); for (insn = next_real_insn (insns); insn; insn = next_real_insn (insn)) count_reg_usage (insn, counts, NULL_RTX, 1); - /* Go from the last insn to the first and delete insns that only set unused - registers or copy a register to itself. As we delete an insn, remove - usage counts for registers it uses. - - The first jump optimization pass may leave a real insn as the last - insn in the function. We must not skip that insn or we may end - up deleting code that is not really dead. */ - insn = get_last_insn (); - if (! INSN_P (insn)) - insn = prev_real_insn (insn); - - if (!preserve_basic_blocks) - for (; insn; insn = prev) - { - int live_insn = 0; - - 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. - - 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); - } - 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_related_insns (insn); - } + do + { + nlastdead = ndead; + niterations++; + /* Go from the last insn to the first and delete insns that only set unused + registers or copy a register to itself. As we delete an insn, remove + usage counts for registers it uses. + + The first jump optimization pass may leave a real insn as the last + insn in the function. We must not skip that insn or we may end + up deleting code that is not really dead. */ + insn = get_last_insn (); + if (! INSN_P (insn)) + insn = prev_real_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) + for (; insn; insn = prev) { int live_insn = 0; - prev = PREV_INSN (insn); - if (!INSN_P (insn)) - continue; + 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. @@ -7703,7 +7665,8 @@ delete_trivially_dead_insns (insns, nreg, preserve_basic_blocks) if (! live_insn) { count_reg_usage (insn, counts, NULL_RTX, -1); - delete_insn (insn); + delete_insn_and_edges (insn); + ndead++; } if (find_reg_note (insn, REG_LIBCALL, NULL_RTX)) @@ -7712,7 +7675,13 @@ delete_trivially_dead_insns (insns, nreg, preserve_basic_blocks) dead_libcall = 0; } } + } while (ndead != nlastdead); + if (rtl_dump_file && ndead) + fprintf (rtl_dump_file, "Deleted %i trivially dead insns; %i iterations\n", + ndead, niterations); /* Clean up. */ free (counts); + timevar_pop (TV_DELETE_TRIVIALLY_DEAD); + return ndead; } |