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]

[PATCH] Speedup get_ref_base_and_extent (double-int)


This speeds up get_ref_base_and_extent by not using the expensive
alshift routine to convert from bytes to bits but a new lshift
overload that works on the whole double-int and only handles
positive shift counts (no extension necessary).

The issue with shifts of course is that we allow negative
shift counts by design - that leads to weird implementation
issues, for example that lshift_double always sign-extends
(callers should extend according to the sign of the result
instead - but that's not possible in case the lshift ends
up being a rshift ...).  Eventually we should work towards
_not_ allowing negative shifts (and simply truncate/mask those
from user input).

It also moves the self-modify operator implementations from
double-int.h to double-int.c where we can directly dispatch
to the workers.  For multiplication via operators it introduces
an early out as they do not care for the high part of the
multiply result nor for overflow status.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2013-05-03  Richard Biener  <rguenther@suse.de>

	* double-int.h (lshift): New overload without precision
	and arith argument.
	(operator *=, operator +=, operator -=): Move ...
	* double-int.c (operator *=, operator +=, operator -=): ... here
	and implement more efficiently.
	(mul_double_with_sign): Remove.
	(lshift_double): Adjust to take unsinged shift argument, push
	dispatching code to callers.
	(mul_double_wide_with_sign): Add early out for callers that
	are not interested in high parts or overflow.
	(lshift): New function.
	(lshift, rshift, alshift, arshift, llshift, lrshift): Add
	dispatch code here.
	(lrotate, rrotate): Use logical shifts.
	* expr.c (get_inner_reference): Use lshift.
	* fixed-value.c (do_fixed_divide): Likewise.
	* tree-dfa.c (get_ref_base_and_extent): Likewise.
	* tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Likewise.
	(indirect_refs_may_alias_p): Likewise.
	(stmt_kills_ref_p_1): Likewise.

Index: trunk/gcc/double-int.c
===================================================================
*** trunk.orig/gcc/double-int.c	2013-05-03 09:58:05.000000000 +0200
--- trunk/gcc/double-int.c	2013-05-03 10:45:01.765410139 +0200
*************** static int add_double_with_sign (unsigne
*** 34,44 ****
  static int neg_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
  		       unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);
  
- static int mul_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- 				 unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- 				 unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
- 				 bool);
- 
  static int mul_double_wide_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
  				      unsigned HOST_WIDE_INT, HOST_WIDE_INT,
  				      unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
--- 34,39 ----
*************** static int mul_double_wide_with_sign (un
*** 46,56 ****
  				      bool);
  
  #define mul_double(l1,h1,l2,h2,lv,hv) \
!   mul_double_with_sign (l1, h1, l2, h2, lv, hv, false)
! 
! static void lshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
! 			   HOST_WIDE_INT, unsigned int,
! 			   unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool);
  
  static int div_and_round_double (unsigned, int, unsigned HOST_WIDE_INT,
  				 HOST_WIDE_INT, unsigned HOST_WIDE_INT,
--- 41,47 ----
  				      bool);
  
  #define mul_double(l1,h1,l2,h2,lv,hv) \
!   mul_double_wide_with_sign (l1, h1, l2, h2, lv, hv, NULL, NULL, false)
  
  static int div_and_round_double (unsigned, int, unsigned HOST_WIDE_INT,
  				 HOST_WIDE_INT, unsigned HOST_WIDE_INT,
*************** neg_double (unsigned HOST_WIDE_INT l1, H
*** 158,182 ****
      }
  }
  
! /* Multiply two doubleword integers with doubleword result.
     Return nonzero if the operation overflows according to UNSIGNED_P.
     Each argument is given as two `HOST_WIDE_INT' pieces.
     One argument is L1 and H1; the other, L2 and H2.
!    The value is stored as two `HOST_WIDE_INT' pieces in *LV and *HV.  */
! 
! static int
! mul_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
! 		      unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2,
! 		      unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
! 		      bool unsigned_p)
! {
!   unsigned HOST_WIDE_INT toplow;
!   HOST_WIDE_INT tophigh;
! 
!   return mul_double_wide_with_sign (l1, h1, l2, h2,
! 				    lv, hv, &toplow, &tophigh,
! 				    unsigned_p);
! }
  
  static int
  mul_double_wide_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
--- 149,161 ----
      }
  }
  
! /* Multiply two doubleword integers with quadword result.
     Return nonzero if the operation overflows according to UNSIGNED_P.
     Each argument is given as two `HOST_WIDE_INT' pieces.
     One argument is L1 and H1; the other, L2 and H2.
!    The value is stored as four `HOST_WIDE_INT' pieces in *LV and *HV,
!    *LW and *HW.
!    If lw is NULL then only the low part and no overflow is computed.  */
  
  static int
  mul_double_wide_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
*************** mul_double_wide_with_sign (unsigned HOST
*** 215,220 ****
--- 194,204 ----
      }
  
    decode (prod, lv, hv);
+ 
+   /* We are not interested in the wide part nor in overflow.  */
+   if (lw == NULL)
+     return 0;
+ 
    decode (prod + 4, lw, hw);
  
    /* Unsigned overflow is immediate.  */
*************** rshift_double (unsigned HOST_WIDE_INT l1
*** 306,322 ****
  
  static void
  lshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
! 	       HOST_WIDE_INT count, unsigned int prec,
! 	       unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv, bool arith)
  {
    unsigned HOST_WIDE_INT signmask;
  
-   if (count < 0)
-     {
-       rshift_double (l1, h1, absu_hwi (count), prec, lv, hv, arith);
-       return;
-     }
- 
    if (SHIFT_COUNT_TRUNCATED)
      count %= prec;
  
--- 290,300 ----
  
  static void
  lshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
! 	       unsigned HOST_WIDE_INT count, unsigned int prec,
! 	       unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
  {
    unsigned HOST_WIDE_INT signmask;
  
    if (SHIFT_COUNT_TRUNCATED)
      count %= prec;
  
*************** double_int::operator * (double_int b) co
*** 832,837 ****
--- 810,824 ----
    return ret;
  }
  
+ /* Multiplies *this with B and returns a reference to *this.  */
+ 
+ double_int &
+ double_int::operator *= (double_int b)
+ {
+   mul_double (low, high, b.low, b.high, &low, &high);
+   return *this;
+ }
+ 
  /* Returns A * B. If the operation overflows according to UNSIGNED_P,
     *OVERFLOW is set to nonzero.  */
  
*************** double_int
*** 839,847 ****
  double_int::mul_with_sign (double_int b, bool unsigned_p, bool *overflow) const
  {
    const double_int &a = *this;
!   double_int ret;
!   *overflow = mul_double_with_sign (a.low, a.high, b.low, b.high,
!                                     &ret.low, &ret.high, unsigned_p);
    return ret;
  }
  
--- 826,835 ----
  double_int::mul_with_sign (double_int b, bool unsigned_p, bool *overflow) const
  {
    const double_int &a = *this;
!   double_int ret, tem;
!   *overflow = mul_double_wide_with_sign (a.low, a.high, b.low, b.high,
! 					 &ret.low, &ret.high,
! 					 &tem.low, &tem.high, unsigned_p);
    return ret;
  }
  
*************** double_int::operator + (double_int b) co
*** 869,874 ****
--- 857,872 ----
    return ret;
  }
  
+ /* Adds B to *this and returns a reference to *this.  */
+ 
+ double_int &
+ double_int::operator += (double_int b)
+ {
+   add_double (low, high, b.low, b.high, &low, &high);
+   return *this;
+ }
+ 
+ 
  /* Returns A + B. If the operation overflows according to UNSIGNED_P,
     *OVERFLOW is set to nonzero.  */
  
*************** double_int::operator - (double_int b) co
*** 894,899 ****
--- 892,908 ----
    return ret;
  }
  
+ /* Subtracts B from *this and returns a reference to *this.  */
+ 
+ double_int &
+ double_int::operator -= (double_int b)
+ {
+   neg_double (b.low, b.high, &b.low, &b.high);
+   add_double (low, high, b.low, b.high, &low, &high);
+   return *this;
+ }
+ 
+ 
  /* Returns A - B. If the operation overflows via inconsistent sign bits,
     *OVERFLOW is set to nonzero.  */
  
*************** double_int::trailing_zeros () const
*** 1076,1081 ****
--- 1085,1121 ----
    return bits;
  }
  
+ /* Shift A left by COUNT places.  */
+ 
+ double_int
+ double_int::lshift (HOST_WIDE_INT count) const
+ {
+   double_int ret;
+ 
+   gcc_checking_assert (count >= 0);
+ 
+   if (count >= HOST_BITS_PER_DOUBLE_INT)
+     {
+       /* Shifting by the host word size is undefined according to the
+ 	 ANSI standard, so we must handle this as a special case.  */
+       ret.high = 0;
+       ret.low = 0;
+     }
+   else if (count >= HOST_BITS_PER_WIDE_INT)
+     {
+       ret.high = low << (count - HOST_BITS_PER_WIDE_INT);
+       ret.low = 0;
+     }
+   else
+     {
+       ret.high = (((unsigned HOST_WIDE_INT) high << count)
+ 	     | (low >> (HOST_BITS_PER_WIDE_INT - count - 1) >> 1));
+       ret.low = low << count;
+     }
+ 
+   return ret;
+ }
+ 
  /* Shift A left by COUNT places keeping only PREC bits of result.  Shift
     right if COUNT is negative.  ARITH true specifies arithmetic shifting;
     otherwise use logical shift.  */
*************** double_int::trailing_zeros () const
*** 1083,1091 ****
  double_int
  double_int::lshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const
  {
-   const double_int &a = *this;
    double_int ret;
!   lshift_double (a.low, a.high, count, prec, &ret.low, &ret.high, arith);
    return ret;
  }
  
--- 1123,1133 ----
  double_int
  double_int::lshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const
  {
    double_int ret;
!   if (count > 0)
!     lshift_double (low, high, count, prec, &ret.low, &ret.high);
!   else
!     rshift_double (low, high, absu_hwi (count), prec, &ret.low, &ret.high, arith);
    return ret;
  }
  
*************** double_int::lshift (HOST_WIDE_INT count,
*** 1096,1104 ****
  double_int
  double_int::rshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const
  {
-   const double_int &a = *this;
    double_int ret;
!   lshift_double (a.low, a.high, -count, prec, &ret.low, &ret.high, arith);
    return ret;
  }
  
--- 1138,1148 ----
  double_int
  double_int::rshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const
  {
    double_int ret;
!   if (count > 0)
!     rshift_double (low, high, count, prec, &ret.low, &ret.high, arith);
!   else
!     lshift_double (low, high, absu_hwi (count), prec, &ret.low, &ret.high);
    return ret;
  }
  
*************** double_int
*** 1109,1115 ****
  double_int::alshift (HOST_WIDE_INT count, unsigned int prec) const
  {
    double_int r;
!   lshift_double (low, high, count, prec, &r.low, &r.high, true);
    return r;
  }
  
--- 1153,1162 ----
  double_int::alshift (HOST_WIDE_INT count, unsigned int prec) const
  {
    double_int r;
!   if (count > 0)
!     lshift_double (low, high, count, prec, &r.low, &r.high);
!   else
!     rshift_double (low, high, absu_hwi (count), prec, &r.low, &r.high, true);
    return r;
  }
  
*************** double_int
*** 1120,1126 ****
  double_int::arshift (HOST_WIDE_INT count, unsigned int prec) const
  {
    double_int r;
!   lshift_double (low, high, -count, prec, &r.low, &r.high, true);
    return r;
  }
  
--- 1167,1176 ----
  double_int::arshift (HOST_WIDE_INT count, unsigned int prec) const
  {
    double_int r;
!   if (count > 0)
!     rshift_double (low, high, count, prec, &r.low, &r.high, true);
!   else
!     lshift_double (low, high, absu_hwi (count), prec, &r.low, &r.high);
    return r;
  }
  
*************** double_int
*** 1131,1137 ****
  double_int::llshift (HOST_WIDE_INT count, unsigned int prec) const
  {
    double_int r;
!   lshift_double (low, high, count, prec, &r.low, &r.high, false);
    return r;
  }
  
--- 1181,1190 ----
  double_int::llshift (HOST_WIDE_INT count, unsigned int prec) const
  {
    double_int r;
!   if (count > 0)
!     lshift_double (low, high, count, prec, &r.low, &r.high);
!   else
!     rshift_double (low, high, absu_hwi (count), prec, &r.low, &r.high, false);
    return r;
  }
  
*************** double_int
*** 1142,1148 ****
  double_int::lrshift (HOST_WIDE_INT count, unsigned int prec) const
  {
    double_int r;
!   lshift_double (low, high, -count, prec, &r.low, &r.high, false);
    return r;
  }
  
--- 1195,1204 ----
  double_int::lrshift (HOST_WIDE_INT count, unsigned int prec) const
  {
    double_int r;
!   if (count > 0)
!     rshift_double (low, high, count, prec, &r.low, &r.high, false);
!   else
!     lshift_double (low, high, absu_hwi (count), prec, &r.low, &r.high);
    return r;
  }
  
*************** double_int::lrotate (HOST_WIDE_INT count
*** 1158,1165 ****
    if (count < 0)
      count += prec;
  
!   t1 = this->lshift (count, prec, false);
!   t2 = this->rshift (prec - count, prec, false);
  
    return t1 | t2;
  }
--- 1214,1221 ----
    if (count < 0)
      count += prec;
  
!   t1 = this->llshift (count, prec);
!   t2 = this->lrshift (prec - count, prec);
  
    return t1 | t2;
  }
*************** double_int::rrotate (HOST_WIDE_INT count
*** 1176,1183 ****
    if (count < 0)
      count += prec;
  
!   t1 = this->rshift (count, prec, false);
!   t2 = this->lshift (prec - count, prec, false);
  
    return t1 | t2;
  }
--- 1232,1239 ----
    if (count < 0)
      count += prec;
  
!   t1 = this->lrshift (count, prec);
!   t2 = this->llshift (prec - count, prec);
  
    return t1 | t2;
  }
Index: trunk/gcc/double-int.h
===================================================================
*** trunk.orig/gcc/double-int.h	2013-05-03 09:58:05.000000000 +0200
--- trunk/gcc/double-int.h	2013-05-03 10:30:32.676838045 +0200
*************** struct double_int
*** 128,133 ****
--- 128,134 ----
    double_int operator ^ (double_int) const;
    double_int and_not (double_int) const;
  
+   double_int lshift (HOST_WIDE_INT count) const;
    double_int lshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const;
    double_int rshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const;
    double_int alshift (HOST_WIDE_INT count, unsigned int prec) const;
*************** double_int::operator -- ()
*** 257,283 ****
    return *this;
  }
  
- inline double_int &
- double_int::operator *= (double_int b)
- {
-   *this = *this * b;
-   return *this;
- }
- 
- inline double_int &
- double_int::operator += (double_int b)
- {
-   *this = *this + b;
-   return *this;
- }
- 
- inline double_int &
- double_int::operator -= (double_int b)
- {
-   *this = *this - b;
-   return *this;
- }
- 
  inline double_int &
  double_int::operator &= (double_int b)
  {
--- 258,263 ----
Index: trunk/gcc/expr.c
===================================================================
*** trunk.orig/gcc/expr.c	2013-05-03 09:58:05.000000000 +0200
--- trunk/gcc/expr.c	2013-05-03 10:28:12.353297604 +0200
*************** get_inner_reference (tree exp, HOST_WIDE
*** 6704,6712 ****
  	      if (!integer_zerop (off))
  		{
  		  double_int boff, coff = mem_ref_offset (exp);
! 		  boff = coff.alshift (BITS_PER_UNIT == 8
! 				       ? 3 : exact_log2 (BITS_PER_UNIT),
! 				       HOST_BITS_PER_DOUBLE_INT);
  		  bit_offset += boff;
  		}
  	      exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
--- 6704,6711 ----
  	      if (!integer_zerop (off))
  		{
  		  double_int boff, coff = mem_ref_offset (exp);
! 		  boff = coff.lshift (BITS_PER_UNIT == 8
! 				      ? 3 : exact_log2 (BITS_PER_UNIT));
  		  bit_offset += boff;
  		}
  	      exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
*************** get_inner_reference (tree exp, HOST_WIDE
*** 6732,6739 ****
      {
        double_int tem = tree_to_double_int (offset);
        tem = tem.sext (TYPE_PRECISION (sizetype));
!       tem = tem.alshift (BITS_PER_UNIT == 8 ? 3 : exact_log2 (BITS_PER_UNIT),
! 			 HOST_BITS_PER_DOUBLE_INT);
        tem += bit_offset;
        if (tem.fits_shwi ())
  	{
--- 6731,6737 ----
      {
        double_int tem = tree_to_double_int (offset);
        tem = tem.sext (TYPE_PRECISION (sizetype));
!       tem = tem.lshift (BITS_PER_UNIT == 8 ? 3 : exact_log2 (BITS_PER_UNIT));
        tem += bit_offset;
        if (tem.fits_shwi ())
  	{
Index: trunk/gcc/fixed-value.c
===================================================================
*** trunk.orig/gcc/fixed-value.c	2013-05-03 09:58:05.000000000 +0200
--- trunk/gcc/fixed-value.c	2013-05-03 10:28:12.354297614 +0200
*************** do_fixed_divide (FIXED_VALUE_TYPE *f, co
*** 569,582 ****
  	  int leftmost_mod = (mod.high < 0);
  
  	  /* Shift left mod by 1 bit.  */
! 	  mod = mod.llshift (1, HOST_BITS_PER_DOUBLE_INT);
  
  	  /* Test the leftmost bit of s to add to mod.  */
  	  if (s.high < 0)
  	    mod.low += 1;
  
  	  /* Shift left quo_s by 1 bit.  */
! 	  quo_s = quo_s.llshift (1, HOST_BITS_PER_DOUBLE_INT);
  
  	  /* Try to calculate (mod - pos_b).  */
  	  temp = mod - pos_b;
--- 569,582 ----
  	  int leftmost_mod = (mod.high < 0);
  
  	  /* Shift left mod by 1 bit.  */
! 	  mod = mod.lshift (1);
  
  	  /* Test the leftmost bit of s to add to mod.  */
  	  if (s.high < 0)
  	    mod.low += 1;
  
  	  /* Shift left quo_s by 1 bit.  */
! 	  quo_s = quo_s.lshift (1);
  
  	  /* Try to calculate (mod - pos_b).  */
  	  temp = mod - pos_b;
*************** do_fixed_divide (FIXED_VALUE_TYPE *f, co
*** 588,594 ****
  	    }
  
  	  /* Shift left s by 1 bit.  */
! 	  s = s.llshift (1, HOST_BITS_PER_DOUBLE_INT);
  
  	}
  
--- 588,594 ----
  	    }
  
  	  /* Shift left s by 1 bit.  */
! 	  s = s.lshift (1);
  
  	}
  
Index: trunk/gcc/tree-dfa.c
===================================================================
*** trunk.orig/gcc/tree-dfa.c	2013-05-03 09:58:05.000000000 +0200
--- trunk/gcc/tree-dfa.c	2013-05-03 10:28:12.354297614 +0200
*************** get_ref_base_and_extent (tree exp, HOST_
*** 433,441 ****
  	    if (this_offset && TREE_CODE (this_offset) == INTEGER_CST)
  	      {
  		double_int doffset = tree_to_double_int (this_offset);
! 		doffset = doffset.alshift (BITS_PER_UNIT == 8
! 					   ? 3 : exact_log2 (BITS_PER_UNIT),
! 					   HOST_BITS_PER_DOUBLE_INT);
  		doffset += tree_to_double_int (DECL_FIELD_BIT_OFFSET (field));
  		bit_offset = bit_offset + doffset;
  
--- 433,440 ----
  	    if (this_offset && TREE_CODE (this_offset) == INTEGER_CST)
  	      {
  		double_int doffset = tree_to_double_int (this_offset);
! 		doffset = doffset.lshift (BITS_PER_UNIT == 8
! 					  ? 3 : exact_log2 (BITS_PER_UNIT));
  		doffset += tree_to_double_int (DECL_FIELD_BIT_OFFSET (field));
  		bit_offset = bit_offset + doffset;
  
*************** get_ref_base_and_extent (tree exp, HOST_
*** 501,509 ****
  		  = (TREE_INT_CST (index) - TREE_INT_CST (low_bound))
  		    .sext (TYPE_PRECISION (TREE_TYPE (index)));
  		doffset *= tree_to_double_int (unit_size);
! 		doffset = doffset.alshift (BITS_PER_UNIT == 8
! 					   ? 3 : exact_log2 (BITS_PER_UNIT),
! 					   HOST_BITS_PER_DOUBLE_INT);
  		bit_offset = bit_offset + doffset;
  
  		/* An array ref with a constant index up in the structure
--- 500,507 ----
  		  = (TREE_INT_CST (index) - TREE_INT_CST (low_bound))
  		    .sext (TYPE_PRECISION (TREE_TYPE (index)));
  		doffset *= tree_to_double_int (unit_size);
! 		doffset = doffset.lshift (BITS_PER_UNIT == 8
! 					  ? 3 : exact_log2 (BITS_PER_UNIT));
  		bit_offset = bit_offset + doffset;
  
  		/* An array ref with a constant index up in the structure
*************** get_ref_base_and_extent (tree exp, HOST_
*** 552,560 ****
  	      else
  		{
  		  double_int off = mem_ref_offset (exp);
! 		  off = off.alshift (BITS_PER_UNIT == 8
! 				     ? 3 : exact_log2 (BITS_PER_UNIT),
! 				     HOST_BITS_PER_DOUBLE_INT);
  		  off = off + bit_offset;
  		  if (off.fits_shwi ())
  		    {
--- 550,557 ----
  	      else
  		{
  		  double_int off = mem_ref_offset (exp);
! 		  off = off.lshift (BITS_PER_UNIT == 8
! 				    ? 3 : exact_log2 (BITS_PER_UNIT));
  		  off = off + bit_offset;
  		  if (off.fits_shwi ())
  		    {
*************** get_ref_base_and_extent (tree exp, HOST_
*** 583,591 ****
  	      else
  		{
  		  double_int off = mem_ref_offset (exp);
! 		  off = off.alshift (BITS_PER_UNIT == 8
! 				     ? 3 : exact_log2 (BITS_PER_UNIT),
! 				     HOST_BITS_PER_DOUBLE_INT);
  		  off += bit_offset;
  		  if (off.fits_shwi ())
  		    {
--- 580,587 ----
  	      else
  		{
  		  double_int off = mem_ref_offset (exp);
! 		  off = off.lshift (BITS_PER_UNIT == 8
! 				    ? 3 : exact_log2 (BITS_PER_UNIT));
  		  off += bit_offset;
  		  if (off.fits_shwi ())
  		    {
Index: trunk/gcc/tree-ssa-alias.c
===================================================================
*** trunk.orig/gcc/tree-ssa-alias.c	2013-05-03 09:58:05.000000000 +0200
--- trunk/gcc/tree-ssa-alias.c	2013-05-03 10:28:12.355297625 +0200
*************** indirect_ref_may_alias_decl_p (tree ref1
*** 882,890 ****
    /* The offset embedded in MEM_REFs can be negative.  Bias them
       so that the resulting offset adjustment is positive.  */
    moff = mem_ref_offset (base1);
!   moff = moff.alshift (BITS_PER_UNIT == 8
! 		       ? 3 : exact_log2 (BITS_PER_UNIT),
! 		       HOST_BITS_PER_DOUBLE_INT);
    if (moff.is_negative ())
      offset2p += (-moff).low;
    else
--- 882,888 ----
    /* The offset embedded in MEM_REFs can be negative.  Bias them
       so that the resulting offset adjustment is positive.  */
    moff = mem_ref_offset (base1);
!   moff = moff.lshift (BITS_PER_UNIT == 8 ? 3 : exact_log2 (BITS_PER_UNIT));
    if (moff.is_negative ())
      offset2p += (-moff).low;
    else
*************** indirect_ref_may_alias_decl_p (tree ref1
*** 960,968 ****
        || TREE_CODE (dbase2) == TARGET_MEM_REF)
      {
        double_int moff = mem_ref_offset (dbase2);
!       moff = moff.alshift (BITS_PER_UNIT == 8
! 			   ? 3 : exact_log2 (BITS_PER_UNIT),
! 			   HOST_BITS_PER_DOUBLE_INT);
        if (moff.is_negative ())
  	doffset1 -= (-moff).low;
        else
--- 958,964 ----
        || TREE_CODE (dbase2) == TARGET_MEM_REF)
      {
        double_int moff = mem_ref_offset (dbase2);
!       moff = moff.lshift (BITS_PER_UNIT == 8 ? 3 : exact_log2 (BITS_PER_UNIT));
        if (moff.is_negative ())
  	doffset1 -= (-moff).low;
        else
*************** indirect_refs_may_alias_p (tree ref1 ATT
*** 1056,1072 ****
        /* The offset embedded in MEM_REFs can be negative.  Bias them
  	 so that the resulting offset adjustment is positive.  */
        moff = mem_ref_offset (base1);
!       moff = moff.alshift (BITS_PER_UNIT == 8
! 			   ? 3 : exact_log2 (BITS_PER_UNIT),
! 			   HOST_BITS_PER_DOUBLE_INT);
        if (moff.is_negative ())
  	offset2 += (-moff).low;
        else
  	offset1 += moff.low;
        moff = mem_ref_offset (base2);
!       moff = moff.alshift (BITS_PER_UNIT == 8
! 			   ? 3 : exact_log2 (BITS_PER_UNIT),
! 			   HOST_BITS_PER_DOUBLE_INT);
        if (moff.is_negative ())
  	offset1 += (-moff).low;
        else
--- 1052,1064 ----
        /* The offset embedded in MEM_REFs can be negative.  Bias them
  	 so that the resulting offset adjustment is positive.  */
        moff = mem_ref_offset (base1);
!       moff = moff.lshift (BITS_PER_UNIT == 8 ? 3 : exact_log2 (BITS_PER_UNIT));
        if (moff.is_negative ())
  	offset2 += (-moff).low;
        else
  	offset1 += moff.low;
        moff = mem_ref_offset (base2);
!       moff = moff.lshift (BITS_PER_UNIT == 8 ? 3 : exact_log2 (BITS_PER_UNIT));
        if (moff.is_negative ())
  	offset1 += (-moff).low;
        else
*************** stmt_kills_ref_p_1 (gimple stmt, ao_ref
*** 2014,2027 ****
  				       TREE_OPERAND (ref->base, 0)))
  		{
  		  double_int off1 = mem_ref_offset (base);
! 		  off1 = off1.alshift (BITS_PER_UNIT == 8
! 				       ? 3 : exact_log2 (BITS_PER_UNIT),
! 				       HOST_BITS_PER_DOUBLE_INT);
  		  off1 = off1 + double_int::from_shwi (offset);
  		  double_int off2 = mem_ref_offset (ref->base);
! 		  off2 = off2.alshift (BITS_PER_UNIT == 8
! 				       ? 3 : exact_log2 (BITS_PER_UNIT),
! 				       HOST_BITS_PER_DOUBLE_INT);
  		  off2 = off2 + double_int::from_shwi (ref_offset);
  		  if (off1.fits_shwi () && off2.fits_shwi ())
  		    {
--- 2006,2017 ----
  				       TREE_OPERAND (ref->base, 0)))
  		{
  		  double_int off1 = mem_ref_offset (base);
! 		  off1 = off1.lshift (BITS_PER_UNIT == 8
! 				      ? 3 : exact_log2 (BITS_PER_UNIT));
  		  off1 = off1 + double_int::from_shwi (offset);
  		  double_int off2 = mem_ref_offset (ref->base);
! 		  off2 = off2.lshift (BITS_PER_UNIT == 8
! 				      ? 3 : exact_log2 (BITS_PER_UNIT));
  		  off2 = off2 + double_int::from_shwi (ref_offset);
  		  if (off1.fits_shwi () && off2.fits_shwi ())
  		    {


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