From 000d8d44b711707b56c75f2d1ebfa6ca046ec7ae Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Sun, 12 Nov 2006 02:57:10 +0000 Subject: [PATCH] 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) : Ensure that TYPE_SIZE has type bitsizetype and TYPE_SIZE_UNIT has type sizetype. From-SVN: r118718 --- gcc/ChangeLog | 16 ++++++++++ gcc/fold-const.c | 89 +++++++++++++++++++++++++++++++++++++++---------------- gcc/stor-layout.c | 5 ++-- 3 files changed, 81 insertions(+), 29 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3cca0dc..7a7013d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2006-11-11 Roger Sayle + + * 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) : Ensure that TYPE_SIZE + has type bitsizetype and TYPE_SIZE_UNIT has type sizetype. + 2006-11-11 Andrew Pinski PR rtl-opt/28812 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; diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 51db310..ccbf9f7 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -1617,7 +1617,6 @@ layout_type (tree type) case VECTOR_TYPE: { int nunits = TYPE_VECTOR_SUBPARTS (type); - tree nunits_tree = build_int_cst (NULL_TREE, nunits); tree innertype = TREE_TYPE (type); gcc_assert (!(nunits & (nunits - 1))); @@ -1655,9 +1654,9 @@ layout_type (tree type) TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type)); TYPE_SIZE_UNIT (type) = int_const_binop (MULT_EXPR, TYPE_SIZE_UNIT (innertype), - nunits_tree, 0); + size_int (nunits), 0); TYPE_SIZE (type) = int_const_binop (MULT_EXPR, TYPE_SIZE (innertype), - nunits_tree, 0); + bitsize_int (nunits), 0); /* Always naturally align vectors. This prevents ABI changes depending on whether or not native vector modes are supported. */ -- 2.7.4