aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2006-11-12 02:57:10 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2006-11-12 02:57:10 +0000
commit000d8d44b711707b56c75f2d1ebfa6ca046ec7ae (patch)
tree58a441d6fe7ffeccb38541fe24123167cc9fb14f /gcc/fold-const.c
parentafa8f0fb33f62b3e9ea2fad0813372730d18295b (diff)
downloadgcc-000d8d44b711707b56c75f2d1ebfa6ca046ec7ae.zip
gcc-000d8d44b711707b56c75f2d1ebfa6ca046ec7ae.tar.gz
gcc-000d8d44b711707b56c75f2d1ebfa6ca046ec7ae.tar.bz2
fold-const.c (int_binop_types_match_p): New function.
* fold-const.c (int_binop_types_match_p): New function. (size_binop): Relax constraint that both arguments must both have exactly the same sizetype type. Instead use int_binop_types_match_p. (size_diffop): Likewise. (make_range): Use build_int_cst instead of fold_convert. (fold_cond_expr_with_comparison): Use build_int_cst to construct integer constants of the correct type. (fold_div_compare): Likewise. (fold_single_bit_test): Likewise. (fold_binary): Likewise. * stor-layout.c (layout_type) <VECTOR_TYPE>: Ensure that TYPE_SIZE has type bitsizetype and TYPE_SIZE_UNIT has type sizetype. From-SVN: r118718
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c89
1 files changed, 63 insertions, 26 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index b715ad8..08e74a2 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -1372,6 +1372,35 @@ associate_trees (tree t1, tree t2, enum tree_code code, tree type)
fold_convert (type, t2));
}
+/* Check whether TYPE1 and TYPE2 are equivalent integer types, suitable
+ for use in int_const_binop, size_binop and size_diffop. */
+
+static bool
+int_binop_types_match_p (enum tree_code code, tree type1, tree type2)
+{
+ if (TREE_CODE (type1) != INTEGER_TYPE && !POINTER_TYPE_P (type1))
+ return false;
+ if (TREE_CODE (type2) != INTEGER_TYPE && !POINTER_TYPE_P (type2))
+ return false;
+
+ switch (code)
+ {
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ case LROTATE_EXPR:
+ case RROTATE_EXPR:
+ return true;
+
+ default:
+ break;
+ }
+
+ return TYPE_UNSIGNED (type1) == TYPE_UNSIGNED (type2)
+ && TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
+ && TYPE_MODE (type1) == TYPE_MODE (type2);
+}
+
+
/* Combine two integer constants ARG1 and ARG2 under operation CODE
to produce a new constant. Return NULL_TREE if we don't know how
to evaluate CODE at compile-time.
@@ -1733,7 +1762,7 @@ size_int_kind (HOST_WIDE_INT number, enum size_type_kind kind)
/* Combine operands OP1 and OP2 with arithmetic operation CODE. CODE
is a tree code. The type of the result is taken from the operands.
- Both must be the same type integer type and it must be a size type.
+ Both must be equivalent integer types, ala int_binop_types_match_p.
If the operands are constant, so is the result. */
tree
@@ -1744,8 +1773,8 @@ size_binop (enum tree_code code, tree arg0, tree arg1)
if (arg0 == error_mark_node || arg1 == error_mark_node)
return error_mark_node;
- gcc_assert (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type)
- && type == TREE_TYPE (arg1));
+ gcc_assert (int_binop_types_match_p (code, TREE_TYPE (arg0),
+ TREE_TYPE (arg1)));
/* Handle the special case of two integer constants faster. */
if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
@@ -1776,14 +1805,19 @@ size_diffop (tree arg0, tree arg1)
tree type = TREE_TYPE (arg0);
tree ctype;
- gcc_assert (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type)
- && type == TREE_TYPE (arg1));
+ gcc_assert (int_binop_types_match_p (MINUS_EXPR, TREE_TYPE (arg0),
+ TREE_TYPE (arg1)));
/* If the type is already signed, just do the simple thing. */
if (!TYPE_UNSIGNED (type))
return size_binop (MINUS_EXPR, arg0, arg1);
- ctype = type == bitsizetype ? sbitsizetype : ssizetype;
+ if (type == sizetype)
+ ctype = ssizetype;
+ else if (type == bitsizetype)
+ ctype = sbitsizetype;
+ else
+ ctype = lang_hooks.types.signed_type (type);
/* If either operand is not a constant, do the conversions to the signed
type and subtract. The hardware will do the right thing with any
@@ -3978,8 +4012,7 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
high_positive = fold_build2 (RSHIFT_EXPR, arg0_type,
fold_convert (arg0_type,
high_positive),
- fold_convert (arg0_type,
- integer_one_node));
+ build_int_cst (arg0_type, 1));
/* If the low bound is specified, "and" the range with the
range for which the original unsigned value will be
@@ -4625,7 +4658,7 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
OEP_ONLY_CONST)
&& operand_equal_p (arg01,
const_binop (PLUS_EXPR, arg2,
- integer_one_node, 0),
+ build_int_cst (type, 1), 0),
OEP_ONLY_CONST))
return pedantic_non_lvalue (fold_build2 (MIN_EXPR,
type, arg1, arg2));
@@ -4637,7 +4670,7 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
OEP_ONLY_CONST)
&& operand_equal_p (arg01,
const_binop (MINUS_EXPR, arg2,
- integer_one_node, 0),
+ build_int_cst (type, 1), 0),
OEP_ONLY_CONST))
return pedantic_non_lvalue (fold_build2 (MIN_EXPR,
type, arg1, arg2));
@@ -4649,7 +4682,7 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
OEP_ONLY_CONST)
&& operand_equal_p (arg01,
const_binop (MINUS_EXPR, arg2,
- integer_one_node, 0),
+ build_int_cst (type, 1), 0),
OEP_ONLY_CONST))
return pedantic_non_lvalue (fold_build2 (MAX_EXPR,
type, arg1, arg2));
@@ -4661,7 +4694,7 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
OEP_ONLY_CONST)
&& operand_equal_p (arg01,
const_binop (PLUS_EXPR, arg2,
- integer_one_node, 0),
+ build_int_cst (type, 1), 0),
OEP_ONLY_CONST))
return pedantic_non_lvalue (fold_build2 (MAX_EXPR,
type, arg1, arg2));
@@ -6084,7 +6117,8 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1)
if (unsigned_p)
{
- tmp = int_const_binop (MINUS_EXPR, arg01, integer_one_node, 0);
+ tmp = int_const_binop (MINUS_EXPR, arg01,
+ build_int_cst (TREE_TYPE (arg01), 1), 0);
lo = prod;
/* Likewise hi = int_const_binop (PLUS_EXPR, prod, tmp, 0). */
@@ -6099,7 +6133,8 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1)
}
else if (tree_int_cst_sgn (arg01) >= 0)
{
- tmp = int_const_binop (MINUS_EXPR, arg01, integer_one_node, 0);
+ tmp = int_const_binop (MINUS_EXPR, arg01,
+ build_int_cst (TREE_TYPE (arg01), 1), 0);
switch (tree_int_cst_sgn (arg1))
{
case -1:
@@ -6127,7 +6162,8 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1)
/* A negative divisor reverses the relational operators. */
code = swap_tree_comparison (code);
- tmp = int_const_binop (PLUS_EXPR, arg01, integer_one_node, 0);
+ tmp = int_const_binop (PLUS_EXPR, arg01,
+ build_int_cst (TREE_TYPE (arg01), 1), 0);
switch (tree_int_cst_sgn (arg1))
{
case -1:
@@ -6265,7 +6301,7 @@ fold_single_bit_test (enum tree_code code, tree arg0, tree arg1,
enum machine_mode operand_mode = TYPE_MODE (type);
int ops_unsigned;
tree signed_type, unsigned_type, intermediate_type;
- tree tem;
+ tree tem, one;
/* First, see if we can fold the single bit test into a sign-bit
test. */
@@ -6310,13 +6346,13 @@ fold_single_bit_test (enum tree_code code, tree arg0, tree arg1,
inner = build2 (RSHIFT_EXPR, intermediate_type,
inner, size_int (bitnum));
+ one = build_int_cst (intermediate_type, 1);
+
if (code == EQ_EXPR)
- inner = fold_build2 (BIT_XOR_EXPR, intermediate_type,
- inner, integer_one_node);
+ inner = fold_build2 (BIT_XOR_EXPR, intermediate_type, inner, one);
/* Put the AND last so it can combine with more things. */
- inner = build2 (BIT_AND_EXPR, intermediate_type,
- inner, integer_one_node);
+ inner = build2 (BIT_AND_EXPR, intermediate_type, inner, one);
/* Make sure to return the proper type. */
inner = fold_convert (result_type, inner);
@@ -10035,8 +10071,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
if (integer_pow2p (c) && tree_int_cst_sgn (c) > 0)
{
- tree mask = fold_build2 (MINUS_EXPR, TREE_TYPE (arg1),
- arg1, integer_one_node);
+ tree mask = fold_build2 (MINUS_EXPR, TREE_TYPE (arg1), arg1,
+ build_int_cst (TREE_TYPE (arg1), 1));
return fold_build2 (BIT_AND_EXPR, type,
fold_convert (type, arg0),
fold_convert (type, mask));
@@ -10148,9 +10184,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
RROTATE_EXPR by a new constant. */
if (code == LROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST)
{
- tree tem = build_int_cst (NULL_TREE,
+ tree tem = build_int_cst (TREE_TYPE (arg1),
GET_MODE_BITSIZE (TYPE_MODE (type)));
- tem = fold_convert (TREE_TYPE (arg1), tem);
tem = const_binop (MINUS_EXPR, tem, arg1, 0);
return fold_build2 (RROTATE_EXPR, type, arg0, tem);
}
@@ -10970,10 +11005,12 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
switch (code)
{
case GT_EXPR:
- arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
+ arg1 = const_binop (PLUS_EXPR, arg1,
+ build_int_cst (TREE_TYPE (arg1), 1), 0);
return fold_build2 (EQ_EXPR, type, arg0, arg1);
case LE_EXPR:
- arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
+ arg1 = const_binop (PLUS_EXPR, arg1,
+ build_int_cst (TREE_TYPE (arg1), 1), 0);
return fold_build2 (NE_EXPR, type, arg0, arg1);
default:
break;