diff options
author | Roger Sayle <roger@eyesopen.com> | 2006-11-12 02:57:10 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2006-11-12 02:57:10 +0000 |
commit | 000d8d44b711707b56c75f2d1ebfa6ca046ec7ae (patch) | |
tree | 58a441d6fe7ffeccb38541fe24123167cc9fb14f /gcc/fold-const.c | |
parent | afa8f0fb33f62b3e9ea2fad0813372730d18295b (diff) | |
download | gcc-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.c | 89 |
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; |