diff options
author | Jeffrey A Law <law@cygnus.com> | 1998-02-12 14:26:47 +0000 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1998-02-12 07:26:47 -0700 |
commit | 614bb5d45d8b87b1f0d5c8d8cb1d02a1377e6ede (patch) | |
tree | 12b0cad7f604e9b8c306d6a7900c27a9e978de26 /gcc | |
parent | 00bb4b6208ccd1dfbec9a6ac24a106bafb80ae04 (diff) | |
download | gcc-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')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cse.c | 39 |
2 files changed, 40 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e8fc0c87..8129ee6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +Thu Feb 12 15:26:50 1998 Jeffrey A Law (law@cygnus.com) + + * 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. + Thu Feb 12 14:04:09 1998 Gavin Koch <gavin@cygnus.com> * mips.md (trucndihi2,truncdiqi2): Change these to support @@ -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; + } } } |