diff options
author | Jan Hubicka <jh@suse.cz> | 2002-03-06 11:17:23 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2002-03-06 10:17:23 +0000 |
commit | 3dec4024284c5108d43f436b4696edc0f40db749 (patch) | |
tree | 1a7be85532d6be381af338d07dbdca5f8fd08db0 /gcc/cse.c | |
parent | 9533dec17344558707c2338385daeab4474305d0 (diff) | |
download | gcc-3dec4024284c5108d43f436b4696edc0f40db749.zip gcc-3dec4024284c5108d43f436b4696edc0f40db749.tar.gz gcc-3dec4024284c5108d43f436b4696edc0f40db749.tar.bz2 |
cfgrtl.c (delete_insn_and_edges, [...]): New.
* cfgrtl.c (delete_insn_and_edges, delete_insn_chain_and_edges): New.
* rtl.h (delete_insn_and_edges, delete_insn_chain_and_edges): Declare
* basic-block.h (update_life_info, update_life_info_in_dirty_blocks,
delete_noop_moves): Return indeger.
* flow.c (ndead): New variable.
(propagate_block_delete_insn): Use delete_insn_and_edges; remove
BB argument; update callers.
(propagate_block_delete_libcall): Use delete_insn_chain_and_edges.
(life_analysis): Do not call purge_all_dead_edges.
(update_life_info): Return number of deleted insns; print statistics.
(update_life_info_in_dirty_blocks): likewise.
(delete_noop_moves): Use delete_insn_and_edges; print statistics;
return number of insns deleted.
* cse.c: Include timevar.h
(delete_trivially_dead_insns): Kill preserve_basic_blocks argument;
iterate until stabilizes; print statistics; return number of killed
insns.
* Makefile.in: (cse.o): Add timevar.h dependency
* rtl.h (delete_trivially_dead_insns): New.
* timever.def: Add TV_DELETE_TRIVIALLY_DEAD timer.
* toplev.c (rest_of_compilation): Update callers.
* cfgcleanup.c (try_optimize_cfg): Kill blocks.
(try_optimize_cfg): Do not update liveness.
(cleanup-cfg): Loop until try_optimize_cfg and dead code
removal stabilizes; use delete_trivially_dead_insns.
* cfgrtl.c (verify_flow_info): Sanity check outgoing edges.
From-SVN: r50355
Diffstat (limited to 'gcc/cse.c')
-rw-r--r-- | gcc/cse.c | 89 |
1 files changed, 29 insertions, 60 deletions
@@ -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; } |