summaryrefslogtreecommitdiff
path: root/gcc/cse.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cse.c')
-rw-r--r--gcc/cse.c89
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;
}