This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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));


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]