Commit b8fca551 by Richard Guenther Committed by Richard Biener

tree.h (force_fit_type_double): Export.

2007-01-08  Richard Guenther  <rguenther@suse.de>

	* tree.h (force_fit_type_double): Export.
	(force_fit_type): Remove.
	* fold-const.c (force_fit_type_double): New function.
	(force_fit_type): Remove.
	(int_const_binop): Use it.
	(fold_convert_const_int_from_int): Likewise.
	(fold_convert_const_int_from_real): Likewise.
	(fold_div_compare): Likewise.
	(fold_sign_changed_comparison): Likewise.
	(fold_unary): Likewise.
	(fold_negate_const): Likewise.
	(fold_abs_const): Likewise. 
	(fold_not_const): Likewise.
	* c-common.c (shorten_compare): Use force_fit_type_double.
	* convert.c (convert_to_pointer): Likewise.

From-SVN: r120597
parent 2ac7cbb5
2007-01-08 Richard Guenther <rguenther@suse.de> 2007-01-08 Richard Guenther <rguenther@suse.de>
* tree.h (force_fit_type_double): Export.
(force_fit_type): Remove.
* fold-const.c (force_fit_type_double): New function.
(force_fit_type): Remove.
(int_const_binop): Use it.
(fold_convert_const_int_from_int): Likewise.
(fold_convert_const_int_from_real): Likewise.
(fold_div_compare): Likewise.
(fold_sign_changed_comparison): Likewise.
(fold_unary): Likewise.
(fold_negate_const): Likewise.
(fold_abs_const): Likewise.
(fold_not_const): Likewise.
* c-common.c (shorten_compare): Use force_fit_type_double.
* convert.c (convert_to_pointer): Likewise.
2007-01-08 Richard Guenther <rguenther@suse.de>
* tree.h (build_int_cst_wide_type): Export. * tree.h (build_int_cst_wide_type): Export.
* tree.c (build_int_cst_wide_type): New function. * tree.c (build_int_cst_wide_type): New function.
(build_int_cst_wide): Fix comment. (build_int_cst_wide): Fix comment.
......
...@@ -2316,12 +2316,11 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr, ...@@ -2316,12 +2316,11 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
{ {
/* Convert primop1 to target type, but do not introduce /* Convert primop1 to target type, but do not introduce
additional overflow. We know primop1 is an int_cst. */ additional overflow. We know primop1 is an int_cst. */
tree tmp = build_int_cst_wide (*restype_ptr, primop1 = force_fit_type_double (*restype_ptr,
TREE_INT_CST_LOW (primop1), TREE_INT_CST_LOW (primop1),
TREE_INT_CST_HIGH (primop1)); TREE_INT_CST_HIGH (primop1), 0,
TREE_OVERFLOW (primop1),
primop1 = force_fit_type (tmp, 0, TREE_OVERFLOW (primop1), TREE_CONSTANT_OVERFLOW (primop1));
TREE_CONSTANT_OVERFLOW (primop1));
} }
if (type != *restype_ptr) if (type != *restype_ptr)
{ {
......
...@@ -44,14 +44,10 @@ convert_to_pointer (tree type, tree expr) ...@@ -44,14 +44,10 @@ convert_to_pointer (tree type, tree expr)
if (TREE_TYPE (expr) == type) if (TREE_TYPE (expr) == type)
return expr; return expr;
/* Propagate overflow to the NULL pointer. */
if (integer_zerop (expr)) if (integer_zerop (expr))
{ return force_fit_type_double (type, 0, 0, 0, TREE_OVERFLOW (expr),
tree t = build_int_cst (type, 0); TREE_CONSTANT_OVERFLOW (expr));
if (TREE_OVERFLOW (expr) || TREE_CONSTANT_OVERFLOW (expr))
t = force_fit_type (t, 0, TREE_OVERFLOW (expr),
TREE_CONSTANT_OVERFLOW (expr));
return t;
}
switch (TREE_CODE (TREE_TYPE (expr))) switch (TREE_CODE (TREE_TYPE (expr)))
{ {
......
...@@ -263,7 +263,9 @@ fit_double_type (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1, ...@@ -263,7 +263,9 @@ fit_double_type (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
return l1 != low0 || h1 != high0; return l1 != low0 || h1 != high0;
} }
/* T is an INT_CST node. OVERFLOWABLE indicates if we are interested /* We force the double-int HIGH:LOW to the range of the type TYPE by
sign or zero extending it.
OVERFLOWABLE indicates if we are interested
in overflow of the value, when >0 we are only interested in signed in overflow of the value, when >0 we are only interested in signed
overflow, for <0 we are interested in any overflow. OVERFLOWED overflow, for <0 we are interested in any overflow. OVERFLOWED
indicates whether overflow has already occurred. CONST_OVERFLOWED indicates whether overflow has already occurred. CONST_OVERFLOWED
...@@ -276,50 +278,54 @@ fit_double_type (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1, ...@@ -276,50 +278,54 @@ fit_double_type (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
We set TREE_CONSTANT_OVERFLOWED if, We set TREE_CONSTANT_OVERFLOWED if,
CONST_OVERFLOWED is nonzero CONST_OVERFLOWED is nonzero
or we set TREE_OVERFLOWED. or we set TREE_OVERFLOWED.
We return either the original T, or a copy. */ We return a new tree node for the extended double-int. The node
is shared if no overflow flags are set. */
tree tree
force_fit_type (tree t, int overflowable, force_fit_type_double (tree type, unsigned HOST_WIDE_INT low,
bool overflowed, bool overflowed_const) HOST_WIDE_INT high, int overflowable,
bool overflowed, bool overflowed_const)
{ {
unsigned HOST_WIDE_INT low;
HOST_WIDE_INT high;
int sign_extended_type; int sign_extended_type;
bool overflow; bool overflow;
gcc_assert (TREE_CODE (t) == INTEGER_CST);
/* Size types *are* sign extended. */ /* Size types *are* sign extended. */
sign_extended_type = (!TYPE_UNSIGNED (TREE_TYPE (t)) sign_extended_type = (!TYPE_UNSIGNED (type)
|| (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE || (TREE_CODE (type) == INTEGER_TYPE
&& TYPE_IS_SIZETYPE (TREE_TYPE (t)))); && TYPE_IS_SIZETYPE (type)));
low = TREE_INT_CST_LOW (t);
high = TREE_INT_CST_HIGH (t);
overflow = fit_double_type (low, high, &low, &high, TREE_TYPE (t)); overflow = fit_double_type (low, high, &low, &high, type);
/* If the value changed, return a new node. */ /* If we need to set overflow flags, return a new unshared node. */
if (overflowed || overflowed_const || overflow) if (overflowed || overflowed_const || overflow)
{ {
t = build_int_cst_wide (TREE_TYPE (t), low, high);
if (overflowed if (overflowed
|| overflowable < 0 || overflowable < 0
|| (overflowable > 0 && sign_extended_type)) || (overflowable > 0 && sign_extended_type))
{ {
t = copy_node (t); tree t = make_node (INTEGER_CST);
TREE_INT_CST_LOW (t) = low;
TREE_INT_CST_HIGH (t) = high;
TREE_TYPE (t) = type;
TREE_OVERFLOW (t) = 1; TREE_OVERFLOW (t) = 1;
TREE_CONSTANT_OVERFLOW (t) = 1; TREE_CONSTANT_OVERFLOW (t) = 1;
return t;
} }
else if (overflowed_const) else if (overflowed_const)
{ {
t = copy_node (t); tree t = make_node (INTEGER_CST);
TREE_INT_CST_LOW (t) = low;
TREE_INT_CST_HIGH (t) = high;
TREE_TYPE (t) = type;
TREE_CONSTANT_OVERFLOW (t) = 1; TREE_CONSTANT_OVERFLOW (t) = 1;
return t;
} }
} }
return t; /* Else build a shared node. */
return build_int_cst_wide (type, low, high);
} }
/* Add two doubleword integers with doubleword result. /* Add two doubleword integers with doubleword result.
...@@ -1601,10 +1607,10 @@ int_const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc) ...@@ -1601,10 +1607,10 @@ int_const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
return NULL_TREE; return NULL_TREE;
} }
t = build_int_cst_wide (TREE_TYPE (arg1), low, hi);
if (notrunc) if (notrunc)
{ {
t = build_int_cst_wide (TREE_TYPE (arg1), low, hi);
/* Propagate overflow flags ourselves. */ /* Propagate overflow flags ourselves. */
if (((!uns || is_sizetype) && overflow) if (((!uns || is_sizetype) && overflow)
| TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2)) | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2))
...@@ -1620,11 +1626,11 @@ int_const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc) ...@@ -1620,11 +1626,11 @@ int_const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
} }
} }
else else
t = force_fit_type (t, 1, t = force_fit_type_double (TREE_TYPE (arg1), low, hi, 1,
((!uns || is_sizetype) && overflow) ((!uns || is_sizetype) && overflow)
| TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2), | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2),
TREE_CONSTANT_OVERFLOW (arg1) TREE_CONSTANT_OVERFLOW (arg1)
| TREE_CONSTANT_OVERFLOW (arg2)); | TREE_CONSTANT_OVERFLOW (arg2));
return t; return t;
} }
...@@ -1896,18 +1902,16 @@ fold_convert_const_int_from_int (tree type, tree arg1) ...@@ -1896,18 +1902,16 @@ fold_convert_const_int_from_int (tree type, tree arg1)
/* Given an integer constant, make new constant with new type, /* Given an integer constant, make new constant with new type,
appropriately sign-extended or truncated. */ appropriately sign-extended or truncated. */
t = build_int_cst_wide (type, TREE_INT_CST_LOW (arg1), t = force_fit_type_double (type, TREE_INT_CST_LOW (arg1),
TREE_INT_CST_HIGH (arg1)); TREE_INT_CST_HIGH (arg1),
/* Don't set the overflow when
t = force_fit_type (t, converting a pointer */
/* Don't set the overflow when !POINTER_TYPE_P (TREE_TYPE (arg1)),
converting a pointer */ (TREE_INT_CST_HIGH (arg1) < 0
!POINTER_TYPE_P (TREE_TYPE (arg1)), && (TYPE_UNSIGNED (type)
(TREE_INT_CST_HIGH (arg1) < 0 < TYPE_UNSIGNED (TREE_TYPE (arg1))))
&& (TYPE_UNSIGNED (type) | TREE_OVERFLOW (arg1),
< TYPE_UNSIGNED (TREE_TYPE (arg1)))) TREE_CONSTANT_OVERFLOW (arg1));
| TREE_OVERFLOW (arg1),
TREE_CONSTANT_OVERFLOW (arg1));
return t; return t;
} }
...@@ -1985,10 +1989,9 @@ fold_convert_const_int_from_real (enum tree_code code, tree type, tree arg1) ...@@ -1985,10 +1989,9 @@ fold_convert_const_int_from_real (enum tree_code code, tree type, tree arg1)
if (! overflow) if (! overflow)
REAL_VALUE_TO_INT (&low, &high, r); REAL_VALUE_TO_INT (&low, &high, r);
t = build_int_cst_wide (type, low, high); t = force_fit_type_double (type, low, high, -1,
overflow | TREE_OVERFLOW (arg1),
t = force_fit_type (t, -1, overflow | TREE_OVERFLOW (arg1), TREE_CONSTANT_OVERFLOW (arg1));
TREE_CONSTANT_OVERFLOW (arg1));
return t; return t;
} }
...@@ -6172,8 +6175,8 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1) ...@@ -6172,8 +6175,8 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1)
TREE_INT_CST_LOW (arg1), TREE_INT_CST_LOW (arg1),
TREE_INT_CST_HIGH (arg1), TREE_INT_CST_HIGH (arg1),
&lpart, &hpart, unsigned_p); &lpart, &hpart, unsigned_p);
prod = build_int_cst_wide (TREE_TYPE (arg00), lpart, hpart); prod = force_fit_type_double (TREE_TYPE (arg00), lpart, hpart,
prod = force_fit_type (prod, -1, overflow, false); -1, overflow, false);
neg_overflow = false; neg_overflow = false;
if (unsigned_p) if (unsigned_p)
...@@ -6188,9 +6191,9 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1) ...@@ -6188,9 +6191,9 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1)
TREE_INT_CST_LOW (tmp), TREE_INT_CST_LOW (tmp),
TREE_INT_CST_HIGH (tmp), TREE_INT_CST_HIGH (tmp),
&lpart, &hpart, unsigned_p); &lpart, &hpart, unsigned_p);
hi = build_int_cst_wide (TREE_TYPE (arg00), lpart, hpart); hi = force_fit_type_double (TREE_TYPE (arg00), lpart, hpart,
hi = force_fit_type (hi, -1, overflow | TREE_OVERFLOW (prod), -1, overflow | TREE_OVERFLOW (prod),
TREE_CONSTANT_OVERFLOW (prod)); TREE_CONSTANT_OVERFLOW (prod));
} }
else if (tree_int_cst_sgn (arg01) >= 0) else if (tree_int_cst_sgn (arg01) >= 0)
{ {
...@@ -6589,7 +6592,7 @@ static tree ...@@ -6589,7 +6592,7 @@ static tree
fold_sign_changed_comparison (enum tree_code code, tree type, fold_sign_changed_comparison (enum tree_code code, tree type,
tree arg0, tree arg1) tree arg0, tree arg1)
{ {
tree arg0_inner, tmp; tree arg0_inner;
tree inner_type, outer_type; tree inner_type, outer_type;
if (TREE_CODE (arg0) != NOP_EXPR if (TREE_CODE (arg0) != NOP_EXPR
...@@ -6624,14 +6627,10 @@ fold_sign_changed_comparison (enum tree_code code, tree type, ...@@ -6624,14 +6627,10 @@ fold_sign_changed_comparison (enum tree_code code, tree type,
return NULL_TREE; return NULL_TREE;
if (TREE_CODE (arg1) == INTEGER_CST) if (TREE_CODE (arg1) == INTEGER_CST)
{ arg1 = force_fit_type_double (inner_type, TREE_INT_CST_LOW (arg1),
tmp = build_int_cst_wide (inner_type, TREE_INT_CST_HIGH (arg1), 0,
TREE_INT_CST_LOW (arg1), TREE_OVERFLOW (arg1),
TREE_INT_CST_HIGH (arg1)); TREE_CONSTANT_OVERFLOW (arg1));
arg1 = force_fit_type (tmp, 0,
TREE_OVERFLOW (arg1),
TREE_CONSTANT_OVERFLOW (arg1));
}
else else
arg1 = fold_convert (inner_type, arg1); arg1 = fold_convert (inner_type, arg1);
...@@ -7563,10 +7562,10 @@ fold_unary (enum tree_code code, tree type, tree op0) ...@@ -7563,10 +7562,10 @@ fold_unary (enum tree_code code, tree type, tree op0)
} }
if (change) if (change)
{ {
tem = build_int_cst_wide (type, TREE_INT_CST_LOW (and1), tem = force_fit_type_double (type, TREE_INT_CST_LOW (and1),
TREE_INT_CST_HIGH (and1)); TREE_INT_CST_HIGH (and1), 0,
tem = force_fit_type (tem, 0, TREE_OVERFLOW (and1), TREE_OVERFLOW (and1),
TREE_CONSTANT_OVERFLOW (and1)); TREE_CONSTANT_OVERFLOW (and1));
return fold_build2 (BIT_AND_EXPR, type, return fold_build2 (BIT_AND_EXPR, type,
fold_convert (type, and0), tem); fold_convert (type, and0), tem);
} }
...@@ -13056,11 +13055,10 @@ fold_negate_const (tree arg0, tree type) ...@@ -13056,11 +13055,10 @@ fold_negate_const (tree arg0, tree type)
int overflow = neg_double (TREE_INT_CST_LOW (arg0), int overflow = neg_double (TREE_INT_CST_LOW (arg0),
TREE_INT_CST_HIGH (arg0), TREE_INT_CST_HIGH (arg0),
&low, &high); &low, &high);
t = build_int_cst_wide (type, low, high); t = force_fit_type_double (type, low, high, 1,
t = force_fit_type (t, 1, (overflow | TREE_OVERFLOW (arg0))
(overflow | TREE_OVERFLOW (arg0)) && !TYPE_UNSIGNED (type),
&& !TYPE_UNSIGNED (type), TREE_CONSTANT_OVERFLOW (arg0));
TREE_CONSTANT_OVERFLOW (arg0));
break; break;
} }
...@@ -13104,9 +13102,9 @@ fold_abs_const (tree arg0, tree type) ...@@ -13104,9 +13102,9 @@ fold_abs_const (tree arg0, tree type)
int overflow = neg_double (TREE_INT_CST_LOW (arg0), int overflow = neg_double (TREE_INT_CST_LOW (arg0),
TREE_INT_CST_HIGH (arg0), TREE_INT_CST_HIGH (arg0),
&low, &high); &low, &high);
t = build_int_cst_wide (type, low, high); t = force_fit_type_double (type, low, high, -1,
t = force_fit_type (t, -1, overflow | TREE_OVERFLOW (arg0), overflow | TREE_OVERFLOW (arg0),
TREE_CONSTANT_OVERFLOW (arg0)); TREE_CONSTANT_OVERFLOW (arg0));
} }
break; break;
...@@ -13134,11 +13132,10 @@ fold_not_const (tree arg0, tree type) ...@@ -13134,11 +13132,10 @@ fold_not_const (tree arg0, tree type)
gcc_assert (TREE_CODE (arg0) == INTEGER_CST); gcc_assert (TREE_CODE (arg0) == INTEGER_CST);
t = build_int_cst_wide (type, t = force_fit_type_double (type, ~TREE_INT_CST_LOW (arg0),
~ TREE_INT_CST_LOW (arg0), ~TREE_INT_CST_HIGH (arg0), 0,
~ TREE_INT_CST_HIGH (arg0)); TREE_OVERFLOW (arg0),
t = force_fit_type (t, 0, TREE_OVERFLOW (arg0), TREE_CONSTANT_OVERFLOW (arg0));
TREE_CONSTANT_OVERFLOW (arg0));
return t; return t;
} }
......
...@@ -4321,7 +4321,8 @@ extern tree fold_ignored_result (tree); ...@@ -4321,7 +4321,8 @@ extern tree fold_ignored_result (tree);
extern tree fold_abs_const (tree, tree); extern tree fold_abs_const (tree, tree);
extern tree fold_indirect_ref_1 (tree, tree); extern tree fold_indirect_ref_1 (tree, tree);
extern tree force_fit_type (tree, int, bool, bool); extern tree force_fit_type_double (tree, unsigned HOST_WIDE_INT, HOST_WIDE_INT,
int, bool, bool);
extern int fit_double_type (unsigned HOST_WIDE_INT, HOST_WIDE_INT, extern int fit_double_type (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, tree); unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, tree);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment