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]

Re: patch to canonize unsigned tree-csts


Thanks for doing this.

Kenneth Zadeck <zadeck@naturalbridge.com> writes:
> @@ -1204,11 +1204,11 @@ wide_int_to_tree (tree type, const wide_
>      }
>  
>    wide_int cst = wide_int::from (pcst, prec, sgn);
> -  int len = int (cst.get_len ());
> -  int small_prec = prec & (HOST_BITS_PER_WIDE_INT - 1);
> +  unsigned int len = int (cst.get_len ());

The cast to int is redundant now (get_len () is unsigned int).

> @@ -5172,39 +5173,48 @@ wi::int_traits <const_tree>::get_precisi
>    return TYPE_PRECISION (TREE_TYPE (tcst));
>  }
>  
> -/* Convert the tree_cst X into a wide_int.  */
> +/* Convert the tree_cst X into a wide_int of PRECISION.  */
>  inline wi::storage_ref
>  wi::int_traits <const_tree>::decompose (HOST_WIDE_INT *scratch,
>  					unsigned int precision, const_tree x)
>  {
> -  unsigned int xprecision = get_precision (x);
>    unsigned int len = TREE_INT_CST_NUNITS (x);
>    const HOST_WIDE_INT *val = (const HOST_WIDE_INT *) &TREE_INT_CST_ELT (x, 0);
>    unsigned int max_len = ((precision + HOST_BITS_PER_WIDE_INT - 1)
>  			  / HOST_BITS_PER_WIDE_INT);
> -  /* Truncate the constant if necessary.  */
> -  if (len > max_len)
> -    return wi::storage_ref (val, max_len, precision);
> +  unsigned int xprecision = get_precision (x);
> +
> +  gcc_assert (precision >= xprecision);
>  
> -  if (precision <= xprecision)
> +  /* Got to be careful of precision 0 values.  */
> +  if (precision)
> +    len = MIN (len, max_len);
> +  if (TYPE_SIGN (TREE_TYPE (x)) == UNSIGNED)
>      {
> -      if (precision < HOST_BITS_PER_WIDE_INT 
> -	  && TYPE_SIGN (TREE_TYPE (x)) == UNSIGNED)
> +      unsigned int small_prec = precision & (HOST_BITS_PER_WIDE_INT - 1);
> +      if (small_prec)
> +	{
> +	  /* We have to futz with this because the canonization for
> +	     short unsigned numbers in wide-int is different from the
> +	     canonized short unsigned numbers in the tree-cst.  */
> +	  if (len == max_len) 
> +	    {
> +	      for (unsigned int i = 0; i < len - 1; i++)
> +		scratch[i] = val[i];
> +	      scratch[len - 1] = sext_hwi (val[len - 1], precision);
> +	      return wi::storage_ref (scratch, len, precision);
> +	    }
> +	}
> +
> +      if (precision < xprecision + HOST_BITS_PER_WIDE_INT)
>  	{
> -	  /* The rep of wide-int is signed, so if the value comes from
> -	     an unsigned int_cst, we have to sign extend it to make it
> -	     correct.  */
> -	  scratch[0] = sext_hwi (val[0], precision);
> -	  return wi::storage_ref (scratch, 1, precision);
> +	  len = wi::force_to_size (scratch, val, len, xprecision, precision, UNSIGNED);
> +	  return wi::storage_ref (scratch, len, precision);
>  	}

AFAICT, with the assert, this last case is only needed when
!small_prec && precision == xprecision, and the only situation it
handles is where the top bit is set.  Is that right?  If so,
we can use the original val as-is and just trim the length.  I.e.

      if (small_prec)
        ;
      else if (precision == xprecision)
        while (len >= 0 && val[len - 1] == -1)
          len--;

Sorry if I've got that wrong -- it's taking a while to page the
wide-int stuff back in.

Thanks,
Richard


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