aboutsummaryrefslogtreecommitdiff
path: root/gcc/cse.c
diff options
context:
space:
mode:
authorJeffrey A Law <law@cygnus.com>1998-02-12 14:26:47 +0000
committerJeff Law <law@gcc.gnu.org>1998-02-12 07:26:47 -0700
commit614bb5d45d8b87b1f0d5c8d8cb1d02a1377e6ede (patch)
tree12b0cad7f604e9b8c306d6a7900c27a9e978de26 /gcc/cse.c
parent00bb4b6208ccd1dfbec9a6ac24a106bafb80ae04 (diff)
downloadgcc-614bb5d45d8b87b1f0d5c8d8cb1d02a1377e6ede.zip
gcc-614bb5d45d8b87b1f0d5c8d8cb1d02a1377e6ede.tar.gz
gcc-614bb5d45d8b87b1f0d5c8d8cb1d02a1377e6ede.tar.bz2
cse.c (delete_dead_from_cse): If a libcall produces a constant result and that result can be substituted into...
* cse.c (delete_dead_from_cse): If a libcall produces a constant result and that result can be substituted into SET_SRC of the insn with the REG_RETVAL note, then perform the substitution and delete the libcall. From-SVN: r17871
Diffstat (limited to 'gcc/cse.c')
-rw-r--r--gcc/cse.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/gcc/cse.c b/gcc/cse.c
index 50b7e14..865451a 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -8754,7 +8754,7 @@ delete_dead_from_cse (insns, nreg)
rtx insn, prev;
rtx tem;
int i;
- int in_libcall = 0;
+ int in_libcall = 0, dead_libcall = 0;
/* First count the number of times each register is used. */
bzero ((char *) counts, sizeof (int) * nreg);
@@ -8767,17 +8767,41 @@ delete_dead_from_cse (insns, nreg)
for (insn = prev_real_insn (get_last_insn ()); insn; insn = prev)
{
int live_insn = 0;
+ rtx note;
prev = prev_real_insn (insn);
- /* Don't delete any insns that are part of a 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))
- in_libcall = 1;
+ {
+ in_libcall = 1;
+ live_insn = 1;
+ dead_libcall = 0;
- if (in_libcall)
- live_insn = 1;
+ /* 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);
+ if (set
+ && validate_change (insn, &SET_SRC (set), XEXP (note, 0), 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 (GET_CODE (SET_DEST (PATTERN (insn))) == REG
@@ -8839,6 +8863,9 @@ delete_dead_from_cse (insns, nreg)
}
if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
- in_libcall = 0;
+ {
+ in_libcall = 0;
+ dead_libcall = 0;
+ }
}
}