This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
fix sparc peephole2 predicates
- From: Dan Nicolaescu <dann at godzilla dot ICS dot UCI dot EDU>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Richard Henderson <rth at redhat dot com>
- Date: Wed, 19 Dec 2001 14:28:50 -0800
- Subject: fix sparc peephole2 predicates
Currently the sparc ldd peephole2 code will happily convert a sequence
like:
ld [%o0], %o0
ld [%o0 + 4], %o1
to:
ldd [%o0], %o0
which is obviously wrong.
The fix is to pass the register to mems_ok_for_ldd_peep so that it can
check that the same register is not used for both computing the
address and as destination of a load.
Stores don't have the same problem.
I also moved all the MEM_VOLATILE_P checks to mems_ok_for_ldd_peep.
Bootstraped on sparc-sun-solaris2.8
2001-12-19 Dan Nicolaescu <dann@ics.uci.edu>
* config/sparc/sparc.md (ldd peephole2s): For load peepholes pass
the destination register as a parameter to mems_ok_for_ldd_peep.
For store peepholes pass NULL_RTX.
Move all volatile checks ...
* config/sparc/sparc.c (mems_ok_for_ldd_peep): ... here.
Add a register parameter, check it's not the same as base for an
address.
* config/sparc/sparc-protos.h (mems_ok_for_ldd_peep): Add
parameter.
*** sparc.md.~1.139.~ Tue Dec 18 16:59:02 2001
--- sparc.md Wed Dec 19 09:00:53 2001
***************
*** 8923,8931 ****
(set (match_operand:SI 1 "memory_operand" "")
(const_int 0))]
"TARGET_V9
! && ! MEM_VOLATILE_P (operands[0])
! && ! MEM_VOLATILE_P (operands[1])
! && mems_ok_for_ldd_peep (operands[0], operands[1])"
[(set (match_dup 0)
(const_int 0))]
"operands[0] = change_address (operands[0], DImode, NULL);")
--- 8923,8929 ----
(set (match_operand:SI 1 "memory_operand" "")
(const_int 0))]
"TARGET_V9
! && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
[(set (match_dup 0)
(const_int 0))]
"operands[0] = change_address (operands[0], DImode, NULL);")
***************
*** 8936,8944 ****
(set (match_operand:SI 1 "memory_operand" "")
(const_int 0))]
"TARGET_V9
! && ! MEM_VOLATILE_P (operands[0])
! && ! MEM_VOLATILE_P (operands[1])
! && mems_ok_for_ldd_peep (operands[1], operands[0])"
[(set (match_dup 1)
(const_int 0))]
"operands[1] = change_address (operands[1], DImode, NULL);")
--- 8934,8940 ----
(set (match_operand:SI 1 "memory_operand" "")
(const_int 0))]
"TARGET_V9
! && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
[(set (match_dup 1)
(const_int 0))]
"operands[1] = change_address (operands[1], DImode, NULL);")
***************
*** 8949,8957 ****
(set (match_operand:SI 2 "register_operand" "")
(match_operand:SI 3 "memory_operand" ""))]
"registers_ok_for_ldd_peep (operands[0], operands[2])
! && ! MEM_VOLATILE_P (operands[1])
! && ! MEM_VOLATILE_P (operands[3])
! && mems_ok_for_ldd_peep (operands[1], operands[3])"
[(set (match_dup 0)
(match_dup 1))]
"operands[1] = change_address (operands[1], DImode, NULL);
--- 8945,8951 ----
(set (match_operand:SI 2 "register_operand" "")
(match_operand:SI 3 "memory_operand" ""))]
"registers_ok_for_ldd_peep (operands[0], operands[2])
! && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
[(set (match_dup 0)
(match_dup 1))]
"operands[1] = change_address (operands[1], DImode, NULL);
***************
*** 8963,8971 ****
(set (match_operand:SI 2 "memory_operand" "")
(match_operand:SI 3 "register_operand" ""))]
"registers_ok_for_ldd_peep (operands[1], operands[3])
! && ! MEM_VOLATILE_P (operands[0])
! && ! MEM_VOLATILE_P (operands[2])
! && mems_ok_for_ldd_peep (operands[0], operands[2])"
[(set (match_dup 0)
(match_dup 1))]
"operands[0] = change_address (operands[0], DImode, NULL);
--- 8957,8963 ----
(set (match_operand:SI 2 "memory_operand" "")
(match_operand:SI 3 "register_operand" ""))]
"registers_ok_for_ldd_peep (operands[1], operands[3])
! && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
[(set (match_dup 0)
(match_dup 1))]
"operands[0] = change_address (operands[0], DImode, NULL);
***************
*** 8977,8985 ****
(set (match_operand:SF 2 "register_operand" "")
(match_operand:SF 3 "memory_operand" ""))]
"registers_ok_for_ldd_peep (operands[0], operands[2])
! && ! MEM_VOLATILE_P (operands[1])
! && ! MEM_VOLATILE_P (operands[3])
! && mems_ok_for_ldd_peep (operands[1], operands[3])"
[(set (match_dup 0)
(match_dup 1))]
"operands[1] = change_address (operands[1], DFmode, NULL);
--- 8969,8975 ----
(set (match_operand:SF 2 "register_operand" "")
(match_operand:SF 3 "memory_operand" ""))]
"registers_ok_for_ldd_peep (operands[0], operands[2])
! && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
[(set (match_dup 0)
(match_dup 1))]
"operands[1] = change_address (operands[1], DFmode, NULL);
***************
*** 8991,8999 ****
(set (match_operand:SF 2 "memory_operand" "")
(match_operand:SF 3 "register_operand" ""))]
"registers_ok_for_ldd_peep (operands[1], operands[3])
! && ! MEM_VOLATILE_P (operands[0])
! && ! MEM_VOLATILE_P (operands[2])
! && mems_ok_for_ldd_peep (operands[0], operands[2])"
[(set (match_dup 0)
(match_dup 1))]
"operands[0] = change_address (operands[0], DFmode, NULL);
--- 8981,8987 ----
(set (match_operand:SF 2 "memory_operand" "")
(match_operand:SF 3 "register_operand" ""))]
"registers_ok_for_ldd_peep (operands[1], operands[3])
! && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
[(set (match_dup 0)
(match_dup 1))]
"operands[0] = change_address (operands[0], DFmode, NULL);
***************
*** 9005,9013 ****
(set (match_operand:SI 2 "register_operand" "")
(match_operand:SI 3 "memory_operand" ""))]
"registers_ok_for_ldd_peep (operands[2], operands[0])
! && ! MEM_VOLATILE_P (operands[3])
! && ! MEM_VOLATILE_P (operands[1])
! && mems_ok_for_ldd_peep (operands[3], operands[1])"
[(set (match_dup 2)
(match_dup 3))]
"operands[3] = change_address (operands[3], DImode, NULL);
--- 8993,8999 ----
(set (match_operand:SI 2 "register_operand" "")
(match_operand:SI 3 "memory_operand" ""))]
"registers_ok_for_ldd_peep (operands[2], operands[0])
! && mems_ok_for_ldd_peep (operands[3], operands[1], operands[2])"
[(set (match_dup 2)
(match_dup 3))]
"operands[3] = change_address (operands[3], DImode, NULL);
***************
*** 9019,9027 ****
(set (match_operand:SI 2 "memory_operand" "")
(match_operand:SI 3 "register_operand" ""))]
"registers_ok_for_ldd_peep (operands[3], operands[1])
! && ! MEM_VOLATILE_P (operands[2])
! && ! MEM_VOLATILE_P (operands[0])
! && mems_ok_for_ldd_peep (operands[2], operands[0])"
[(set (match_dup 2)
(match_dup 3))]
"operands[2] = change_address (operands[2], DImode, NULL);
--- 9005,9011 ----
(set (match_operand:SI 2 "memory_operand" "")
(match_operand:SI 3 "register_operand" ""))]
"registers_ok_for_ldd_peep (operands[3], operands[1])
! && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
[(set (match_dup 2)
(match_dup 3))]
"operands[2] = change_address (operands[2], DImode, NULL);
***************
*** 9034,9042 ****
(set (match_operand:SF 2 "register_operand" "")
(match_operand:SF 3 "memory_operand" ""))]
"registers_ok_for_ldd_peep (operands[2], operands[0])
! && ! MEM_VOLATILE_P (operands[3])
! && ! MEM_VOLATILE_P (operands[1])
! && mems_ok_for_ldd_peep (operands[3], operands[1])"
[(set (match_dup 2)
(match_dup 3))]
"operands[3] = change_address (operands[3], DFmode, NULL);
--- 9018,9024 ----
(set (match_operand:SF 2 "register_operand" "")
(match_operand:SF 3 "memory_operand" ""))]
"registers_ok_for_ldd_peep (operands[2], operands[0])
! && mems_ok_for_ldd_peep (operands[3], operands[1], operands[2])"
[(set (match_dup 2)
(match_dup 3))]
"operands[3] = change_address (operands[3], DFmode, NULL);
***************
*** 9048,9056 ****
(set (match_operand:SF 2 "memory_operand" "")
(match_operand:SF 3 "register_operand" ""))]
"registers_ok_for_ldd_peep (operands[3], operands[1])
! && ! MEM_VOLATILE_P (operands[2])
! && ! MEM_VOLATILE_P (operands[0])
! && mems_ok_for_ldd_peep (operands[2], operands[0])"
[(set (match_dup 2)
(match_dup 3))]
"operands[2] = change_address (operands[2], DFmode, NULL);
--- 9030,9036 ----
(set (match_operand:SF 2 "memory_operand" "")
(match_operand:SF 3 "register_operand" ""))]
"registers_ok_for_ldd_peep (operands[3], operands[1])
! && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
[(set (match_dup 2)
(match_dup 3))]
"operands[2] = change_address (operands[2], DFmode, NULL);
*** sparc.c.~1.173.~ Mon Dec 17 14:56:00 2001
--- sparc.c Wed Dec 19 11:45:12 2001
***************
*** 5673,5699 ****
}
/* Return 1 if the addresses in mem1 and mem2 are suitable for use in
! an ldd or std insn.
!
This can only happen when addr1 and addr2, the addresses in mem1
and mem2, are consecutive memory locations (addr1 + 4 == addr2).
! addr1 must also be aligned on a 64-bit boundary. */
int
! mems_ok_for_ldd_peep (mem1, mem2)
! rtx mem1, mem2;
{
rtx addr1, addr2;
unsigned int reg1;
int offset1;
! addr1 = XEXP (mem1, 0);
! addr2 = XEXP (mem2, 0);
/* mem1 should be aligned on a 64-bit boundary */
if (MEM_ALIGN (mem1) < 64)
return 0;
/* Extract a register number and offset (if used) from the first addr. */
if (GET_CODE (addr1) == PLUS)
{
--- 5673,5713 ----
}
/* Return 1 if the addresses in mem1 and mem2 are suitable for use in
! an ldd or std insn.
!
This can only happen when addr1 and addr2, the addresses in mem1
and mem2, are consecutive memory locations (addr1 + 4 == addr2).
! addr1 must also be aligned on a 64-bit boundary.
!
! Also iff dependent_reg_rtx is not null it should not be used to
! compute the address for mem1, i.e. we cannot optimize a sequence
! like:
! ld [%o0], %o0
! ld [%o0 + 4], %o1
! to
! ldd [%o0], o0
! For stores we don't have a similar problem, so dependent_reg_rtx is
! NULL_RTX. */
int
! mems_ok_for_ldd_peep (mem1, mem2, dependent_reg_rtx)
! rtx mem1, mem2, dependent_reg_rtx;
{
rtx addr1, addr2;
unsigned int reg1;
int offset1;
! /* the mems cannot be volatile */
! if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
! return 0;
/* mem1 should be aligned on a 64-bit boundary */
if (MEM_ALIGN (mem1) < 64)
return 0;
+ addr1 = XEXP (mem1, 0);
+ addr2 = XEXP (mem2, 0);
+
/* Extract a register number and offset (if used) from the first addr. */
if (GET_CODE (addr1) == PLUS)
{
***************
*** 5729,5734 ****
--- 5743,5751 ----
if (reg1 != REGNO (XEXP (addr2, 0)))
return 0;
+ if (dependent_reg_rtx != NULL_RTX && reg1 == REGNO (dependent_reg_rtx))
+ return 0;
+
/* The first offset must be evenly divisible by 8 to ensure the
address is 64 bit aligned. */
if (offset1 % 8 != 0)
*** sparc-protos.h.~1.16.~ Mon Dec 17 10:45:46 2001
--- sparc-protos.h Wed Dec 19 00:55:21 2001
***************
*** 91,97 ****
extern char *output_v9branch PARAMS ((rtx, int, int, int, int, int, rtx));
extern void emit_v9_brxx_insn PARAMS ((enum rtx_code, rtx, rtx));
extern void print_operand PARAMS ((FILE *, rtx, int));
! extern int mems_ok_for_ldd_peep PARAMS ((rtx, rtx));
extern int arith_double_4096_operand PARAMS ((rtx, enum machine_mode));
extern int arith_4096_operand PARAMS ((rtx, enum machine_mode));
extern int zero_operand PARAMS ((rtx, enum machine_mode));
--- 91,97 ----
extern char *output_v9branch PARAMS ((rtx, int, int, int, int, int, rtx));
extern void emit_v9_brxx_insn PARAMS ((enum rtx_code, rtx, rtx));
extern void print_operand PARAMS ((FILE *, rtx, int));
! extern int mems_ok_for_ldd_peep PARAMS ((rtx, rtx, rtx));
extern int arith_double_4096_operand PARAMS ((rtx, enum machine_mode));
extern int arith_4096_operand PARAMS ((rtx, enum machine_mode));
extern int zero_operand PARAMS ((rtx, enum machine_mode));