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]

RFA: Fix PR 22445


The actual failure decribed in the PR is fixed by merely not using mode
in the hashing of CONST_INTs, i.e. that is the one-line change in the last
hunk of the attached patch.  However, when you compare addresses that
are made of sums, commutativity should also taken into account (that
the order matched in the reported instance was basically luck).  That's
what the third (and first) hunk are about.  Finally, I added a comment to
cselib_hash_rtx about the properties of the hash that I am fixing / using
in the aforementioned hunks, and removed the mode parameter to
cselib_hash_rtx, because it seved no purpose anymore.

Successfully tested on the sh-elf-4_1-branch with an i686-pc-linux-gnu
bootstrap/regtest and an i686-pc-linux-gnu X sh-elf regtest.

We've also been using this patch without the mode parameter removal
in a 3.4.3 based compiler for a while.
2005-07-12  J"orn Rennecke <joern.rennecke@st.com>

	* cselib.c (target.h): Include.
	(rtx_equal_for_cselib_p): Allow commutative matches.
	(cselib_hash_rtx): Don't use MODE for CONST_INT hashing.
	Remove MODE parameter.  Changed all callers.

Index: cselib.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cselib.c,v
retrieving revision 1.59.4.1
diff -p -r1.59.4.1 cselib.c
*** cselib.c	6 Jul 2005 21:34:18 -0000	1.59.4.1
--- cselib.c	12 Jul 2005 17:52:23 -0000
*************** Software Foundation, 51 Franklin Street,
*** 41,46 ****
--- 41,47 ----
  #include "cselib.h"
  #include "params.h"
  #include "alloc-pool.h"
+ #include "target.h"
  
  static bool cselib_record_memory;
  static int entry_and_rtx_equal_p (const void *, const void *);
*************** static int discard_useless_locs (void **
*** 54,60 ****
  static int discard_useless_values (void **, void *);
  static void remove_useless_values (void);
  static rtx wrap_constant (enum machine_mode, rtx);
! static unsigned int cselib_hash_rtx (rtx, enum machine_mode, int);
  static cselib_val *new_cselib_val (unsigned int, enum machine_mode);
  static void add_mem_for_addr (cselib_val *, cselib_val *, rtx);
  static cselib_val *cselib_lookup_mem (rtx, int);
--- 55,61 ----
  static int discard_useless_values (void **, void *);
  static void remove_useless_values (void);
  static rtx wrap_constant (enum machine_mode, rtx);
! static unsigned int cselib_hash_rtx (rtx, int);
  static cselib_val *new_cselib_val (unsigned int, enum machine_mode);
  static void add_mem_for_addr (cselib_val *, cselib_val *, rtx);
  static cselib_val *cselib_lookup_mem (rtx, int);
*************** rtx_equal_for_cselib_p (rtx x, rtx y)
*** 499,504 ****
--- 500,513 ----
  	  break;
  
  	case 'e':
+ 	  if (i > 0 && fmt[i-1] == 'e'
+ 	      && targetm.commutative_p (x, UNKNOWN)
+ 	      && rtx_equal_for_cselib_p (XEXP (x, i), XEXP (y, i-1))
+ 	      && rtx_equal_for_cselib_p (XEXP (x, i-1), XEXP (y, i)))
+ 	    {
+ 	      i--;
+ 	      continue;
+ 	    }
  	  if (! rtx_equal_for_cselib_p (XEXP (x, i), XEXP (y, i)))
  	    return 0;
  	  break;
*************** wrap_constant (enum machine_mode mode, r
*** 546,556 ****
     Possible reasons for return 0 are: the object is volatile, or we couldn't
     find a register or memory location in the table and CREATE is zero.  If
     CREATE is nonzero, table elts are created for regs and mem.
!    MODE is used in hashing for CONST_INTs only;
!    otherwise the mode of X is used.  */
  
  static unsigned int
! cselib_hash_rtx (rtx x, enum machine_mode mode, int create)
  {
    cselib_val *e;
    int i, j;
--- 555,576 ----
     Possible reasons for return 0 are: the object is volatile, or we couldn't
     find a register or memory location in the table and CREATE is zero.  If
     CREATE is nonzero, table elts are created for regs and mem.
!    N.B. this hash function returns the same hash value for RTXes that
!    differ only in the order of operands, thus it is suitable for comparisons
!    that take commutativity into account.
!    If we wanted to also support associative rules, we'd have to use a different
!    strategy to avoid returning spurious 0, e.g. return ~(~0U >> 1) .
!    We used to have a MODE argument for hashing for CONST_INTs, but that
!    didn't make sense, since it caused spurious hash differences between
!     (set (reg:SI 1) (const_int))
!     (plus:SI (reg:SI 2) (reg:SI 1))
!    and
!     (plus:SI (reg:SI 2) (const_int))
!    If the mode is important in any context, it must be checked specifically
!    in a comparison anyway, since relying on hash differences is unsafe.  */
  
  static unsigned int
! cselib_hash_rtx (rtx x, int create)
  {
    cselib_val *e;
    int i, j;
*************** cselib_hash_rtx (rtx x, enum machine_mod
*** 572,578 ****
        return e->value;
  
      case CONST_INT:
!       hash += ((unsigned) CONST_INT << 7) + (unsigned) mode + INTVAL (x);
        return hash ? hash : (unsigned int) CONST_INT;
  
      case CONST_DOUBLE:
--- 592,598 ----
        return e->value;
  
      case CONST_INT:
!       hash += ((unsigned) CONST_INT << 7) + INTVAL (x);
        return hash ? hash : (unsigned int) CONST_INT;
  
      case CONST_DOUBLE:
*************** cselib_hash_rtx (rtx x, enum machine_mod
*** 596,602 ****
  	for (i = 0; i < units; ++i)
  	  {
  	    elt = CONST_VECTOR_ELT (x, i);
! 	    hash += cselib_hash_rtx (elt, GET_MODE (elt), 0);
  	  }
  
  	return hash;
--- 616,622 ----
  	for (i = 0; i < units; ++i)
  	  {
  	    elt = CONST_VECTOR_ELT (x, i);
! 	    hash += cselib_hash_rtx (elt, 0);
  	  }
  
  	return hash;
*************** cselib_hash_rtx (rtx x, enum machine_mod
*** 644,650 ****
  	case 'e':
  	  {
  	    rtx tem = XEXP (x, i);
! 	    unsigned int tem_hash = cselib_hash_rtx (tem, 0, create);
  	    
  	    if (tem_hash == 0)
  	      return 0;
--- 664,670 ----
  	case 'e':
  	  {
  	    rtx tem = XEXP (x, i);
! 	    unsigned int tem_hash = cselib_hash_rtx (tem, create);
  	    
  	    if (tem_hash == 0)
  	      return 0;
*************** cselib_hash_rtx (rtx x, enum machine_mod
*** 656,662 ****
  	  for (j = 0; j < XVECLEN (x, i); j++)
  	    {
  	      unsigned int tem_hash
! 		= cselib_hash_rtx (XVECEXP (x, i, j), 0, create);
  	      
  	      if (tem_hash == 0)
  		return 0;
--- 676,682 ----
  	  for (j = 0; j < XVECLEN (x, i); j++)
  	    {
  	      unsigned int tem_hash
! 		= cselib_hash_rtx (XVECEXP (x, i, j), create);
  	      
  	      if (tem_hash == 0)
  		return 0;
*************** cselib_lookup (rtx x, enum machine_mode 
*** 936,942 ****
    if (MEM_P (x))
      return cselib_lookup_mem (x, create);
  
!   hashval = cselib_hash_rtx (x, mode, create);
    /* Can't even create if hashing is not possible.  */
    if (! hashval)
      return 0;
--- 956,962 ----
    if (MEM_P (x))
      return cselib_lookup_mem (x, create);
  
!   hashval = cselib_hash_rtx (x, create);
    /* Can't even create if hashing is not possible.  */
    if (! hashval)
      return 0;

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