This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Additional patch to further improve delete_computation.
- To: gcc-patches at gcc dot gnu dot org
- Subject: Additional patch to further improve delete_computation.
- From: John Wehle <john at feith dot com>
- Date: Sun, 8 Aug 1999 18:26:40 -0400 (EDT)
This patch allows delete_computation to remove calls to constant
functions. For example using -O2 -fno-schedule-insns2 on a x86
platform to compile:
long
func(long long a, long long b)
{
long long c;
c = a / b;
if (c)
return 0;
c -= c;
return c;
}
without the patch produces:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
movl 16(%ebp),%eax
movl 20(%ebp),%edx
pushl %edx
pushl %eax
movl 8(%ebp),%eax
movl 12(%ebp),%edx
pushl %edx
pushl %eax
call __divdi3
xorl %eax,%eax
leave
ret
with the patch:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
movl 16(%ebp),%eax
movl 20(%ebp),%edx
pushl %edx
pushl %eax
movl 8(%ebp),%eax
movl 12(%ebp),%edx
pushl %edx
pushl %eax
xorl %eax,%eax
leave
ret
This patch passes make bootstrap and make check on FreeBSD-3.2 x86.
Notes:
1) Unfortunately at the moment I don't see a straight forward way
to avoid pushing the arguements on the stack (helpful little
things such as REG_LIBCALL and REG_RETVAL notes are not around),
however with enough analysis it's probably doable.
ChangeLog:
Sun Aug 8 00:03:55 EDT 1999 John Wehle (john@feith.com)
* jump.c (delete_prior_computation): Also check calls
to constant functions. Don't bother checking for a
REG_UNUSED note before adding it.
(delete_computation): Handle multi-word hard registers
when synthesizing missing REG_DEAD notes for a register
which is both set and used by an insn.
Enjoy!
-- John Wehle
-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/jump.c.ORIGINAL Fri Aug 6 16:58:16 1999
--- gcc/jump.c Sat Aug 7 23:56:40 1999
*************** delete_prior_computation (note, insn)
*** 3824,3834 ****
rtx reg = XEXP (note, 0);
for (our_prev = prev_nonnote_insn (insn);
! our_prev && GET_CODE (our_prev) == INSN;
our_prev = prev_nonnote_insn (our_prev))
{
rtx pat = PATTERN (our_prev);
/* If we reach a SEQUENCE, it is too complex to try to
do anything with it, so give up. */
if (GET_CODE (pat) == SEQUENCE)
--- 3824,3842 ----
rtx reg = XEXP (note, 0);
for (our_prev = prev_nonnote_insn (insn);
! our_prev && (GET_CODE (our_prev) == INSN
! || GET_CODE (our_prev) == CALL_INSN);
our_prev = prev_nonnote_insn (our_prev))
{
rtx pat = PATTERN (our_prev);
+ /* If we reach a CALL which is not calling a const function
+ or the callee pops the arguments, then give up. */
+ if (GET_CODE (our_prev) == CALL_INSN
+ && (! CONST_CALL_P (our_prev)
+ || GET_CODE (pat) != SET || GET_CODE (SET_SRC (pat)) != CALL))
+ break;
+
/* If we reach a SEQUENCE, it is too complex to try to
do anything with it, so give up. */
if (GET_CODE (pat) == SEQUENCE)
*************** delete_prior_computation (note, insn)
*** 3842,3848 ****
if (reg_set_p (reg, pat))
{
! if (side_effects_p (pat))
break;
if (GET_CODE (pat) == PARALLEL)
--- 3850,3856 ----
if (reg_set_p (reg, pat))
{
! if (side_effects_p (pat) && GET_CODE (our_prev) != CALL_INSN)
break;
if (GET_CODE (pat) == PARALLEL)
*************** delete_prior_computation (note, insn)
*** 3885,3892 ****
insns. Write REG_UNUSED notes for those parts that were not
needed. */
else if (dest_regno <= regno
! && dest_endregno >= endregno
! && ! find_regno_note (our_prev, REG_UNUSED, REGNO(reg)))
{
int i;
--- 3893,3899 ----
insns. Write REG_UNUSED notes for those parts that were not
needed. */
else if (dest_regno <= regno
! && dest_endregno >= endregno)
{
int i;
*************** delete_computation (insn)
*** 3972,3978 ****
--- 3979,4008 ----
}
#endif
+ /* The REG_DEAD note may have been omitted for a register
+ which is both set and used by the insn. */
set = single_set (insn);
+ if (set && GET_CODE (SET_DEST (set)) == REG)
+ {
+ int dest_regno = REGNO (SET_DEST (set));
+ int dest_endregno
+ = dest_regno + (dest_regno < FIRST_PSEUDO_REGISTER
+ ? HARD_REGNO_NREGS (dest_regno,
+ GET_MODE (SET_DEST (set))) : 1);
+ int i;
+
+ for (i = dest_regno; i < dest_endregno; i++)
+ {
+ if (! refers_to_regno_p (i, i + 1, SET_SRC (set), NULL_PTR)
+ || find_regno_note (insn, REG_DEAD, i))
+ continue;
+
+ note = gen_rtx_EXPR_LIST (REG_DEAD, (i < FIRST_PSEUDO_REGISTER
+ ? gen_rtx_REG (reg_raw_mode[i], i)
+ : SET_DEST (set)), NULL_RTX);
+ delete_prior_computation (note, insn);
+ }
+ }
for (note = REG_NOTES (insn); note; note = next)
{
*************** delete_computation (insn)
*** 3983,4001 ****
|| GET_CODE (XEXP (note, 0)) != REG)
continue;
- if (set && reg_overlap_mentioned_p (SET_DEST (set), XEXP (note, 0)))
- set = NULL_RTX;
-
- delete_prior_computation (note, insn);
- }
-
- /* The REG_DEAD note may have been omitted for a register
- which is both set and used by the insn. */
- if (set
- && GET_CODE (SET_DEST (set)) == REG
- && reg_mentioned_p (SET_DEST (set), SET_SRC (set)))
- {
- note = gen_rtx_EXPR_LIST (REG_DEAD, SET_DEST (set), NULL_RTX);
delete_prior_computation (note, insn);
}
--- 4013,4018 ----
-------------------------------------------------------------------------
| Feith Systems | Voice: 1-215-646-8000 | Email: john@feith.com |
| John Wehle | Fax: 1-215-540-5495 | |
-------------------------------------------------------------------------