This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch to allow CSEing of pure calls
- To: gcc-patches at gcc dot gnu dot org
- Subject: Patch to allow CSEing of pure calls
- From: John Wehle <john at feith dot com>
- Date: Sat, 9 Sep 2000 23:01:48 -0400 (EDT)
Currently on the x86 CSE doesn't handle:
static int __attribute__((pure))
subr(int *a, int b, int c)
{
return *a + b / c;
}
int
func(int a, int b, int c)
{
return subr(&a, b, c) + subr(&a, b, c);
}
This patch passes make bootstrap and make check on FreeBSD-3.5 x86.
ChangeLog:
Sat Sep 9 20:20:35 EDT 2000 John Wehle (john@feith.com)
* cse.c (canon_hash): Handle USE of BLKmode memory.
(cse_insn): Outgoing arguments for a libcall don't
affect any recorded expressions.
Enjoy!
-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/cse.c.ORIGINAL Fri Sep 8 21:33:45 2000
--- gcc/cse.c Sat Sep 9 20:15:09 2000
*************** canon_hash (x, mode)
*** 2331,2336 ****
--- 2331,2358 ----
x = XEXP (x, 0);
goto repeat;
+ case USE:
+ /* A USE that mentions non-volatile memory needs special
+ handling since the MEM may be BLKmode which normally
+ prevents an entry from being made. Pure call's are
+ marked by a USE which mentions BLKmode memory. */
+ if (GET_CODE (XEXP (x, 0)) == MEM
+ && ! MEM_VOLATILE_P (XEXP (x, 0)))
+ {
+ hash += (unsigned)USE;
+ x = XEXP (x, 0);
+
+ if (! RTX_UNCHANGING_P (x) || FIXED_BASE_PLUS_P (XEXP (x, 0)))
+ hash_arg_in_memory = 1;
+
+ /* Now that we have already found this special case,
+ might as well speed it up as much as possible. */
+ hash += (unsigned) MEM;
+ x = XEXP (x, 0);
+ goto repeat;
+ }
+ break;
+
case PRE_DEC:
case PRE_INC:
case POST_DEC:
*************** cse_insn (insn, libcall_insn)
*** 5732,5740 ****
else if (do_not_record)
{
! if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG
! || GET_CODE (dest) == MEM)
invalidate (dest, VOIDmode);
else if (GET_CODE (dest) == STRICT_LOW_PART
|| GET_CODE (dest) == ZERO_EXTRACT)
invalidate (XEXP (dest, 0), GET_MODE (dest));
--- 5754,5768 ----
else if (do_not_record)
{
! if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG)
invalidate (dest, VOIDmode);
+ else if (GET_CODE (dest) == MEM)
+ {
+ /* Outgoing arguments for a libcall don't
+ affect any recorded expressions. */
+ if (! libcall_insn || insn == libcall_insn)
+ invalidate (dest, VOIDmode);
+ }
else if (GET_CODE (dest) == STRICT_LOW_PART
|| GET_CODE (dest) == ZERO_EXTRACT)
invalidate (XEXP (dest, 0), GET_MODE (dest));
*************** cse_insn (insn, libcall_insn)
*** 5891,5899 ****
previous quantity's chain.
Needed for memory if this is a nonvarying address, unless
we have just done an invalidate_memory that covers even those. */
! if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG
! || GET_CODE (dest) == MEM)
invalidate (dest, VOIDmode);
else if (GET_CODE (dest) == STRICT_LOW_PART
|| GET_CODE (dest) == ZERO_EXTRACT)
invalidate (XEXP (dest, 0), GET_MODE (dest));
--- 5919,5933 ----
previous quantity's chain.
Needed for memory if this is a nonvarying address, unless
we have just done an invalidate_memory that covers even those. */
! if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG)
invalidate (dest, VOIDmode);
+ else if (GET_CODE (dest) == MEM)
+ {
+ /* Outgoing arguments for a libcall don't
+ affect any recorded expressions. */
+ if (! libcall_insn || insn == libcall_insn)
+ invalidate (dest, VOIDmode);
+ }
else if (GET_CODE (dest) == STRICT_LOW_PART
|| GET_CODE (dest) == ZERO_EXTRACT)
invalidate (XEXP (dest, 0), GET_MODE (dest));
-------------------------------------------------------------------------
| Feith Systems | Voice: 1-215-646-8000 | Email: john@feith.com |
| John Wehle | Fax: 1-215-540-5495 | |
-------------------------------------------------------------------------