public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Remove VRPs use of TYPE_MIN/MAX_VALUE
@ 2011-04-11 11:17 Richard Guenther
  2011-04-11 13:28 ` Eric Botcazou
  0 siblings, 1 reply; 6+ messages in thread
From: Richard Guenther @ 2011-04-11 11:17 UTC (permalink / raw)
  To: gcc-patches


The middle-end treats conversions between integral types that differ
in TYPE_MIN/MAX_VALUE but not in TYPE_PRECISION or signedness as useless.
This is inconsistent with VRP extracting range information from such
types (and it is not clear how NOP conversions behave here anyway).

The following patch thus simply removes VRPs looking at TYPE_MIN/MAX_VALUE
in favor of using a canonical min/max value based on signedness and
precision.  This exposes a latent bug in upper_bound_in_type and
lower_bound_in_type which do not properly sign-extend sizetype constants.

This makes PR33738 and its testcase moot, thus the patch removes it.

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

Richard.

2011-04-11  Richard Guenther  <rguenther@suse.de>

	* tree.c (upper_bound_in_type): Properly create canonicalized
	constants.
	(lower_bound_in_type): Likewise.
	* tree-vrp.c (vrp_val_max): Use upper_bound_in_type.
	(vrp_val_min): Use lower_bound_in_type.
	(set_value_range_to_nonnegative): Use vrp_val_min and vrp_val_max
	where appropriate.
	(extract_range_from_assert): Likewise.
	(vrp_int_const_binop): Likewise.
	(extract_range_from_unary_expr): Likewise.
	(adjust_range_with_scev): Likewise.
	(extract_code_and_val_from_cond_with_ops): Likewise.
	(vrp_visit_phi_node): Likewise.
	(test_for_singularity): Likewise.

	* g++.dg/warn/pr33738.C: Remove.

Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c	(revision 172252)
--- gcc/tree-vrp.c	(working copy)
*************** static VEC (switch_update, heap) *to_upd
*** 161,170 ****
  static inline tree
  vrp_val_max (const_tree type)
  {
!   if (!INTEGRAL_TYPE_P (type))
!     return NULL_TREE;
  
!   return TYPE_MAX_VALUE (type);
  }
  
  /* Return the minimum value for TYPE.  */
--- 161,170 ----
  static inline tree
  vrp_val_max (const_tree type)
  {
!   if (INTEGRAL_TYPE_P (type))
!     return upper_bound_in_type (CONST_CAST_TREE (type), CONST_CAST_TREE (type));
  
!   return NULL_TREE;
  }
  
  /* Return the minimum value for TYPE.  */
*************** vrp_val_max (const_tree type)
*** 172,181 ****
  static inline tree
  vrp_val_min (const_tree type)
  {
!   if (!INTEGRAL_TYPE_P (type))
!     return NULL_TREE;
  
!   return TYPE_MIN_VALUE (type);
  }
  
  /* Return whether VAL is equal to the maximum value of its type.  This
--- 172,181 ----
  static inline tree
  vrp_val_min (const_tree type)
  {
!   if (INTEGRAL_TYPE_P (type))
!     return lower_bound_in_type (CONST_CAST_TREE (type), CONST_CAST_TREE (type));
  
!   return NULL_TREE;
  }
  
  /* Return whether VAL is equal to the maximum value of its type.  This
*************** set_value_range_to_nonnegative (value_ra
*** 565,571 ****
    set_value_range (vr, VR_RANGE, zero,
  		   (overflow_infinity
  		    ? positive_overflow_infinity (type)
! 		    : TYPE_MAX_VALUE (type)),
  		   vr->equiv);
  }
  
--- 565,571 ----
    set_value_range (vr, VR_RANGE, zero,
  		   (overflow_infinity
  		    ? positive_overflow_infinity (type)
! 		    : vrp_val_max (type)),
  		   vr->equiv);
  }
  
*************** extract_range_from_assert (value_range_t
*** 1627,1633 ****
      }
    else if (cond_code == LE_EXPR || cond_code == LT_EXPR)
      {
!       min = TYPE_MIN_VALUE (type);
  
        if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
  	max = limit;
--- 1627,1633 ----
      }
    else if (cond_code == LE_EXPR || cond_code == LT_EXPR)
      {
!       min = vrp_val_min (type);
  
        if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
  	max = limit;
*************** extract_range_from_assert (value_range_t
*** 1662,1668 ****
      }
    else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
      {
!       max = TYPE_MAX_VALUE (type);
  
        if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
  	min = limit;
--- 1662,1668 ----
      }
    else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
      {
!       max = vrp_val_max (type);
  
        if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
  	min = limit;
*************** vrp_int_const_binop (enum tree_code code
*** 2079,2089 ****
  	  || code == ROUND_DIV_EXPR)
  	return (needs_overflow_infinity (TREE_TYPE (res))
  		? positive_overflow_infinity (TREE_TYPE (res))
! 		: TYPE_MAX_VALUE (TREE_TYPE (res)));
        else
  	return (needs_overflow_infinity (TREE_TYPE (res))
  		? negative_overflow_infinity (TREE_TYPE (res))
! 		: TYPE_MIN_VALUE (TREE_TYPE (res)));
      }
  
    return res;
--- 2079,2089 ----
  	  || code == ROUND_DIV_EXPR)
  	return (needs_overflow_infinity (TREE_TYPE (res))
  		? positive_overflow_infinity (TREE_TYPE (res))
! 		: vrp_val_max (TREE_TYPE (res)));
        else
  	return (needs_overflow_infinity (TREE_TYPE (res))
  		? negative_overflow_infinity (TREE_TYPE (res))
! 		: vrp_val_min (TREE_TYPE (res)));
      }
  
    return res;
*************** extract_range_from_unary_expr (value_ran
*** 2878,2885 ****
  	  && TYPE_PRECISION (inner_type) < TYPE_PRECISION (outer_type))
  	{
  	  vr0.type = VR_RANGE;
! 	  vr0.min = TYPE_MIN_VALUE (inner_type);
! 	  vr0.max = TYPE_MAX_VALUE (inner_type);
  	}
  
        /* If VR0 is a constant range or anti-range and the conversion is
--- 2878,2885 ----
  	  && TYPE_PRECISION (inner_type) < TYPE_PRECISION (outer_type))
  	{
  	  vr0.type = VR_RANGE;
! 	  vr0.min = vrp_val_min (inner_type);
! 	  vr0.max = vrp_val_max (inner_type);
  	}
  
        /* If VR0 is a constant range or anti-range and the conversion is
*************** extract_range_from_unary_expr (value_ran
*** 2964,2970 ****
  	    }
  	}
        else
! 	min = TYPE_MIN_VALUE (type);
  
        if (is_positive_overflow_infinity (vr0.min))
  	max = negative_overflow_infinity (type);
--- 2964,2970 ----
  	    }
  	}
        else
! 	min = vrp_val_min (type);
  
        if (is_positive_overflow_infinity (vr0.min))
  	max = negative_overflow_infinity (type);
*************** extract_range_from_unary_expr (value_ran
*** 2983,2989 ****
  	    }
  	}
        else
! 	max = TYPE_MIN_VALUE (type);
      }
    else if (code == NEGATE_EXPR
  	   && TYPE_UNSIGNED (type))
--- 2983,2989 ----
  	    }
  	}
        else
! 	max = vrp_val_min (type);
      }
    else if (code == NEGATE_EXPR
  	   && TYPE_UNSIGNED (type))
*************** extract_range_from_unary_expr (value_ran
*** 3025,3031 ****
        else if (!vrp_val_is_min (vr0.min))
  	min = fold_unary_to_constant (code, type, vr0.min);
        else if (!needs_overflow_infinity (type))
! 	min = TYPE_MAX_VALUE (type);
        else if (supports_overflow_infinity (type))
  	min = positive_overflow_infinity (type);
        else
--- 3025,3031 ----
        else if (!vrp_val_is_min (vr0.min))
  	min = fold_unary_to_constant (code, type, vr0.min);
        else if (!needs_overflow_infinity (type))
! 	min = vrp_val_max (type);
        else if (supports_overflow_infinity (type))
  	min = positive_overflow_infinity (type);
        else
*************** extract_range_from_unary_expr (value_ran
*** 3039,3045 ****
        else if (!vrp_val_is_min (vr0.max))
  	max = fold_unary_to_constant (code, type, vr0.max);
        else if (!needs_overflow_infinity (type))
! 	max = TYPE_MAX_VALUE (type);
        else if (supports_overflow_infinity (type)
  	       /* We shouldn't generate [+INF, +INF] as set_value_range
  		  doesn't like this and ICEs.  */
--- 3039,3045 ----
        else if (!vrp_val_is_min (vr0.max))
  	max = fold_unary_to_constant (code, type, vr0.max);
        else if (!needs_overflow_infinity (type))
! 	max = vrp_val_max (type);
        else if (supports_overflow_infinity (type)
  	       /* We shouldn't generate [+INF, +INF] as set_value_range
  		  doesn't like this and ICEs.  */
*************** extract_range_from_unary_expr (value_ran
*** 3069,3075 ****
  	         TYPE_MIN_VALUE, remember -TYPE_MIN_VALUE = TYPE_MIN_VALUE.  */
  	      if (TYPE_OVERFLOW_WRAPS (type))
  		{
! 		  tree type_min_value = TYPE_MIN_VALUE (type);
  
  		  min = (vr0.min != type_min_value
  			 ? int_const_binop (PLUS_EXPR, type_min_value,
--- 3069,3075 ----
  	         TYPE_MIN_VALUE, remember -TYPE_MIN_VALUE = TYPE_MIN_VALUE.  */
  	      if (TYPE_OVERFLOW_WRAPS (type))
  		{
! 		  tree type_min_value = vrp_val_min (type);
  
  		  min = (vr0.min != type_min_value
  			 ? int_const_binop (PLUS_EXPR, type_min_value,
*************** extract_range_from_unary_expr (value_ran
*** 3081,3087 ****
  		  if (overflow_infinity_range_p (&vr0))
  		    min = negative_overflow_infinity (type);
  		  else
! 		    min = TYPE_MIN_VALUE (type);
  		}
  	    }
  	  else
--- 3081,3087 ----
  		  if (overflow_infinity_range_p (&vr0))
  		    min = negative_overflow_infinity (type);
  		  else
! 		    min = vrp_val_min (type);
  		}
  	    }
  	  else
*************** extract_range_from_unary_expr (value_ran
*** 3102,3108 ****
  		    }
  		}
  	      else
! 		max = TYPE_MAX_VALUE (type);
  	    }
  	}
  
--- 3102,3108 ----
  		    }
  		}
  	      else
! 		max = vrp_val_max (type);
  	    }
  	}
  
*************** adjust_range_with_scev (value_range_t *v
*** 3386,3396 ****
    if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
      tmin = lower_bound_in_type (type, type);
    else
!     tmin = TYPE_MIN_VALUE (type);
    if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
      tmax = upper_bound_in_type (type, type);
    else
!     tmax = TYPE_MAX_VALUE (type);
  
    /* Try to use estimated number of iterations for the loop to constrain the
       final value in the evolution.
--- 3386,3396 ----
    if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
      tmin = lower_bound_in_type (type, type);
    else
!     tmin = vrp_val_min (type);
    if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
      tmax = upper_bound_in_type (type, type);
    else
!     tmax = vrp_val_max (type);
  
    /* Try to use estimated number of iterations for the loop to constrain the
       final value in the evolution.
*************** extract_code_and_val_from_cond_with_ops
*** 4304,4311 ****
    if ((comp_code == GT_EXPR || comp_code == LT_EXPR)
        && INTEGRAL_TYPE_P (TREE_TYPE (val)))
      {
!       tree min = TYPE_MIN_VALUE (TREE_TYPE (val));
!       tree max = TYPE_MAX_VALUE (TREE_TYPE (val));
  
        if (comp_code == GT_EXPR
  	  && (!max
--- 4304,4311 ----
    if ((comp_code == GT_EXPR || comp_code == LT_EXPR)
        && INTEGRAL_TYPE_P (TREE_TYPE (val)))
      {
!       tree min = vrp_val_min (TREE_TYPE (val));
!       tree max = vrp_val_max (TREE_TYPE (val));
  
        if (comp_code == GT_EXPR
  	  && (!max
*************** vrp_visit_phi_node (gimple phi)
*** 6661,6667 ****
  	{
  	  if (!needs_overflow_infinity (TREE_TYPE (vr_result.min))
  	      || !vrp_var_may_overflow (lhs, phi))
! 	    vr_result.min = TYPE_MIN_VALUE (TREE_TYPE (vr_result.min));
  	  else if (supports_overflow_infinity (TREE_TYPE (vr_result.min)))
  	    vr_result.min =
  		negative_overflow_infinity (TREE_TYPE (vr_result.min));
--- 6661,6667 ----
  	{
  	  if (!needs_overflow_infinity (TREE_TYPE (vr_result.min))
  	      || !vrp_var_may_overflow (lhs, phi))
! 	    vr_result.min = vrp_val_min (TREE_TYPE (vr_result.min));
  	  else if (supports_overflow_infinity (TREE_TYPE (vr_result.min)))
  	    vr_result.min =
  		negative_overflow_infinity (TREE_TYPE (vr_result.min));
*************** vrp_visit_phi_node (gimple phi)
*** 6673,6679 ****
  	{
  	  if (!needs_overflow_infinity (TREE_TYPE (vr_result.max))
  	      || !vrp_var_may_overflow (lhs, phi))
! 	    vr_result.max = TYPE_MAX_VALUE (TREE_TYPE (vr_result.max));
  	  else if (supports_overflow_infinity (TREE_TYPE (vr_result.max)))
  	    vr_result.max =
  		positive_overflow_infinity (TREE_TYPE (vr_result.max));
--- 6673,6679 ----
  	{
  	  if (!needs_overflow_infinity (TREE_TYPE (vr_result.max))
  	      || !vrp_var_may_overflow (lhs, phi))
! 	    vr_result.max = vrp_val_max (TREE_TYPE (vr_result.max));
  	  else if (supports_overflow_infinity (TREE_TYPE (vr_result.max)))
  	    vr_result.max =
  		positive_overflow_infinity (TREE_TYPE (vr_result.max));
*************** test_for_singularity (enum tree_code con
*** 7095,7101 ****
      {
        /* This should not be negative infinity; there is no overflow
  	 here.  */
!       min = TYPE_MIN_VALUE (TREE_TYPE (op0));
  
        max = op1;
        if (cond_code == LT_EXPR && !is_overflow_infinity (max))
--- 7095,7101 ----
      {
        /* This should not be negative infinity; there is no overflow
  	 here.  */
!       min = vrp_val_min (TREE_TYPE (op0));
  
        max = op1;
        if (cond_code == LT_EXPR && !is_overflow_infinity (max))
*************** test_for_singularity (enum tree_code con
*** 7110,7116 ****
      {
        /* This should not be positive infinity; there is no overflow
  	 here.  */
!       max = TYPE_MAX_VALUE (TREE_TYPE (op0));
  
        min = op1;
        if (cond_code == GT_EXPR && !is_overflow_infinity (min))
--- 7110,7116 ----
      {
        /* This should not be positive infinity; there is no overflow
  	 here.  */
!       max = vrp_val_max (TREE_TYPE (op0));
  
        min = op1;
        if (cond_code == GT_EXPR && !is_overflow_infinity (min))
Index: gcc/tree.c
===================================================================
*** gcc/tree.c	(revision 172252)
--- gcc/tree.c	(working copy)
*************** signed_type_for (tree type)
*** 10008,10014 ****
  tree
  upper_bound_in_type (tree outer, tree inner)
  {
!   unsigned HOST_WIDE_INT lo, hi;
    unsigned int det = 0;
    unsigned oprec = TYPE_PRECISION (outer);
    unsigned iprec = TYPE_PRECISION (inner);
--- 10008,10014 ----
  tree
  upper_bound_in_type (tree outer, tree inner)
  {
!   double_int high;
    unsigned int det = 0;
    unsigned oprec = TYPE_PRECISION (outer);
    unsigned iprec = TYPE_PRECISION (inner);
*************** upper_bound_in_type (tree outer, tree in
*** 10055,10072 ****
    /* Compute 2^^prec - 1.  */
    if (prec <= HOST_BITS_PER_WIDE_INT)
      {
!       hi = 0;
!       lo = ((~(unsigned HOST_WIDE_INT) 0)
  	    >> (HOST_BITS_PER_WIDE_INT - prec));
      }
    else
      {
!       hi = ((~(unsigned HOST_WIDE_INT) 0)
  	    >> (2 * HOST_BITS_PER_WIDE_INT - prec));
!       lo = ~(unsigned HOST_WIDE_INT) 0;
      }
  
!   return build_int_cst_wide (outer, lo, hi);
  }
  
  /* Returns the smallest value obtainable by casting something in INNER type to
--- 10055,10072 ----
    /* Compute 2^^prec - 1.  */
    if (prec <= HOST_BITS_PER_WIDE_INT)
      {
!       high.high = 0;
!       high.low = ((~(unsigned HOST_WIDE_INT) 0)
  	    >> (HOST_BITS_PER_WIDE_INT - prec));
      }
    else
      {
!       high.high = ((~(unsigned HOST_WIDE_INT) 0)
  	    >> (2 * HOST_BITS_PER_WIDE_INT - prec));
!       high.low = ~(unsigned HOST_WIDE_INT) 0;
      }
  
!   return double_int_to_tree (outer, high);
  }
  
  /* Returns the smallest value obtainable by casting something in INNER type to
*************** upper_bound_in_type (tree outer, tree in
*** 10075,10081 ****
  tree
  lower_bound_in_type (tree outer, tree inner)
  {
!   unsigned HOST_WIDE_INT lo, hi;
    unsigned oprec = TYPE_PRECISION (outer);
    unsigned iprec = TYPE_PRECISION (inner);
  
--- 10075,10081 ----
  tree
  lower_bound_in_type (tree outer, tree inner)
  {
!   double_int low;
    unsigned oprec = TYPE_PRECISION (outer);
    unsigned iprec = TYPE_PRECISION (inner);
  
*************** lower_bound_in_type (tree outer, tree in
*** 10086,10092 ****
  	 contains all values of INNER type.  In particular, both INNER
  	 and OUTER types have zero in common.  */
        || (oprec > iprec && TYPE_UNSIGNED (inner)))
!     lo = hi = 0;
    else
      {
        /* If we are widening a signed type to another signed type, we
--- 10086,10092 ----
  	 contains all values of INNER type.  In particular, both INNER
  	 and OUTER types have zero in common.  */
        || (oprec > iprec && TYPE_UNSIGNED (inner)))
!     low.low = low.high = 0;
    else
      {
        /* If we are widening a signed type to another signed type, we
*************** lower_bound_in_type (tree outer, tree in
*** 10097,10114 ****
  
        if (prec <= HOST_BITS_PER_WIDE_INT)
  	{
! 	  hi = ~(unsigned HOST_WIDE_INT) 0;
! 	  lo = (~(unsigned HOST_WIDE_INT) 0) << (prec - 1);
  	}
        else
  	{
! 	  hi = ((~(unsigned HOST_WIDE_INT) 0)
  		<< (prec - HOST_BITS_PER_WIDE_INT - 1));
! 	  lo = 0;
  	}
      }
  
!   return build_int_cst_wide (outer, lo, hi);
  }
  
  /* Return nonzero if two operands that are suitable for PHI nodes are
--- 10097,10114 ----
  
        if (prec <= HOST_BITS_PER_WIDE_INT)
  	{
! 	  low.high = ~(unsigned HOST_WIDE_INT) 0;
! 	  low.low = (~(unsigned HOST_WIDE_INT) 0) << (prec - 1);
  	}
        else
  	{
! 	  low.high = ((~(unsigned HOST_WIDE_INT) 0)
  		<< (prec - HOST_BITS_PER_WIDE_INT - 1));
! 	  low.low = 0;
  	}
      }
  
!   return double_int_to_tree (outer, low);
  }
  
  /* Return nonzero if two operands that are suitable for PHI nodes are

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Remove VRPs use of TYPE_MIN/MAX_VALUE
  2011-04-11 11:17 [PATCH] Remove VRPs use of TYPE_MIN/MAX_VALUE Richard Guenther
@ 2011-04-11 13:28 ` Eric Botcazou
  2011-04-11 14:09   ` Richard Guenther
  0 siblings, 1 reply; 6+ messages in thread
From: Eric Botcazou @ 2011-04-11 13:28 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches

> The middle-end treats conversions between integral types that differ
> in TYPE_MIN/MAX_VALUE but not in TYPE_PRECISION or signedness as useless.
> This is inconsistent with VRP extracting range information from such
> types (and it is not clear how NOP conversions behave here anyway).

IIRC we agreed, by the time I fixed the Ada compiler, that the IL shouldn't 
contain types with non-canonical bounds, except for constructs that don't 
generate code like the TYPE_DOMAIN of arrays.  My understanding is that this 
has been the case (modulo bugs) for some time now, so I don't understand your 
remark about NOP conversions.

> The following patch thus simply removes VRPs looking at TYPE_MIN/MAX_VALUE
> in favor of using a canonical min/max value based on signedness and
> precision.  This exposes a latent bug in upper_bound_in_type and
> lower_bound_in_type which do not properly sign-extend sizetype constants.

Wouldn't it be better performance-wise to keep using TYPE_MIN/MAX_VALUE and add 
an appropriate check for non-standard types at the end of gimplification?

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Remove VRPs use of TYPE_MIN/MAX_VALUE
  2011-04-11 13:28 ` Eric Botcazou
@ 2011-04-11 14:09   ` Richard Guenther
  2011-04-11 15:25     ` Eric Botcazou
  0 siblings, 1 reply; 6+ messages in thread
From: Richard Guenther @ 2011-04-11 14:09 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches

On Mon, 11 Apr 2011, Eric Botcazou wrote:

> > The middle-end treats conversions between integral types that differ
> > in TYPE_MIN/MAX_VALUE but not in TYPE_PRECISION or signedness as useless.
> > This is inconsistent with VRP extracting range information from such
> > types (and it is not clear how NOP conversions behave here anyway).
> 
> IIRC we agreed, by the time I fixed the Ada compiler, that the IL shouldn't 
> contain types with non-canonical bounds, except for constructs that don't 
> generate code like the TYPE_DOMAIN of arrays.  My understanding is that this 
> has been the case (modulo bugs) for some time now, so I don't understand your 
> remark about NOP conversions.

Such types are still there for enumeral type kinds.  Also the C family
frontends leak arithmetic in array TYPE_DOMAIN types.
 
> > The following patch thus simply removes VRPs looking at TYPE_MIN/MAX_VALUE
> > in favor of using a canonical min/max value based on signedness and
> > precision.  This exposes a latent bug in upper_bound_in_type and
> > lower_bound_in_type which do not properly sign-extend sizetype constants.
> 
> Wouldn't it be better performance-wise to keep using TYPE_MIN/MAX_VALUE and add 
> an appropriate check for non-standard types at the end of gimplification?

I don't see how we can do this for ENUM types.  We use the 
TYPE_MIN/MAX_VALUEs for debug information.

I tried to assert this for INTEGER_TYPEs only, but as noted above the
C family leaks TYPE_DOMAIN arithmetic.

Richard.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Remove VRPs use of TYPE_MIN/MAX_VALUE
  2011-04-11 14:09   ` Richard Guenther
@ 2011-04-11 15:25     ` Eric Botcazou
  2011-04-11 15:43       ` Richard Guenther
  0 siblings, 1 reply; 6+ messages in thread
From: Eric Botcazou @ 2011-04-11 15:25 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches

> Such types are still there for enumeral type kinds.  Also the C family
> frontends leak arithmetic in array TYPE_DOMAIN types.

The arithmetic needs to be fixed to use the base type instead (i.e. TREE_TYPE 
of type, which is guaranteed to be sizetype for TYPE_DOMAIN types).

> I don't see how we can do this for ENUM types.  We use the
> TYPE_MIN/MAX_VALUEs for debug information.

Like Ada. There is a hook (get_subrange_bounds), see subrange_type_for_debug_p.

> I tried to assert this for INTEGER_TYPEs only, but as noted above the
> C family leaks TYPE_DOMAIN arithmetic.

Gigi used to do so as well, now it always uses the base type.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Remove VRPs use of TYPE_MIN/MAX_VALUE
  2011-04-11 15:25     ` Eric Botcazou
@ 2011-04-11 15:43       ` Richard Guenther
  2011-04-11 21:37         ` Eric Botcazou
  0 siblings, 1 reply; 6+ messages in thread
From: Richard Guenther @ 2011-04-11 15:43 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches

On Mon, 11 Apr 2011, Eric Botcazou wrote:

> > Such types are still there for enumeral type kinds.  Also the C family
> > frontends leak arithmetic in array TYPE_DOMAIN types.
> 
> The arithmetic needs to be fixed to use the base type instead (i.e. TREE_TYPE 
> of type, which is guaranteed to be sizetype for TYPE_DOMAIN types).
> 
> > I don't see how we can do this for ENUM types.  We use the
> > TYPE_MIN/MAX_VALUEs for debug information.
> 
> Like Ada. There is a hook (get_subrange_bounds), see subrange_type_for_debug_p.

Hm, I see.  Nothing I want to change at this moment though - for C
and C++ this kind of changes would leak into their internal ASTs :/

> > I tried to assert this for INTEGER_TYPEs only, but as noted above the
> > C family leaks TYPE_DOMAIN arithmetic.
> 
> Gigi used to do so as well, now it always uses the base type.

Yes, I know - it's good that at least Ada behaves well there now.

Is your concern the cost of calling lower/upper_bound_in_type?

Richard.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Remove VRPs use of TYPE_MIN/MAX_VALUE
  2011-04-11 15:43       ` Richard Guenther
@ 2011-04-11 21:37         ` Eric Botcazou
  0 siblings, 0 replies; 6+ messages in thread
From: Eric Botcazou @ 2011-04-11 21:37 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches

> Is your concern the cost of calling lower/upper_bound_in_type?

Yes, all the more so if other uses of TYPE_MIN/MAX_VALUE get replaced over 
time.  IMO this is going backwards.  The Ada compiler heavily uses types with 
non-canonical bounds and was changed so it's hard to believe that this isn't 
doable for the C family of compilers.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-04-11 21:37 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-11 11:17 [PATCH] Remove VRPs use of TYPE_MIN/MAX_VALUE Richard Guenther
2011-04-11 13:28 ` Eric Botcazou
2011-04-11 14:09   ` Richard Guenther
2011-04-11 15:25     ` Eric Botcazou
2011-04-11 15:43       ` Richard Guenther
2011-04-11 21:37         ` Eric Botcazou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).