From af85b8e458035822a927da15087e975a692dc023 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Thu, 3 Mar 2005 17:27:54 +0000 Subject: [PATCH] * fold-const.c (fold): Remove handling of unary expressions. From-SVN: r95836 --- gcc/ChangeLog | 2 + gcc/fold-const.c | 400 +---------------------------------------------- 2 files changed, 4 insertions(+), 398 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2f78c4d7a51..0196b4eede9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -9,6 +9,8 @@ * tree-phinodes.c (remove_phi_node): Clean up by factoring out calls to release_ssa_name and release_phi_node. + * fold-const.c (fold): Remove handling of unary expressions. + 2005-03-03 Roger Sayle Andrew Pinski diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 42d72969f85..470035994ce 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -7063,30 +7063,7 @@ fold (tree expr) } } - if (code == NOP_EXPR || code == FLOAT_EXPR || code == CONVERT_EXPR) - { - tree subop; - - /* Special case for conversion ops that can have fixed point args. */ - arg0 = TREE_OPERAND (t, 0); - - /* Don't use STRIP_NOPS, because signedness of argument type matters. */ - if (arg0 != 0) - STRIP_SIGN_NOPS (arg0); - - if (arg0 != 0 && TREE_CODE (arg0) == COMPLEX_CST) - subop = TREE_REALPART (arg0); - else - subop = arg0; - - if (subop != 0 && TREE_CODE (subop) != INTEGER_CST - && TREE_CODE (subop) != REAL_CST) - /* Note that TREE_CONSTANT isn't enough: - static var addresses are constant but we can't - do arithmetic on them. */ - wins = 0; - } - else if (IS_EXPR_CODE_CLASS (kind)) + if (IS_EXPR_CODE_CLASS (kind)) { int len = TREE_CODE_LENGTH (code); int i; @@ -7181,71 +7158,7 @@ fold (tree expr) return tem; } - if (TREE_CODE_CLASS (code) == tcc_unary) - { - if (TREE_CODE (arg0) == COMPOUND_EXPR) - return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0), - fold (build1 (code, type, TREE_OPERAND (arg0, 1)))); - else if (TREE_CODE (arg0) == COND_EXPR) - { - tree arg01 = TREE_OPERAND (arg0, 1); - tree arg02 = TREE_OPERAND (arg0, 2); - if (! VOID_TYPE_P (TREE_TYPE (arg01))) - arg01 = fold (build1 (code, type, arg01)); - if (! VOID_TYPE_P (TREE_TYPE (arg02))) - arg02 = fold (build1 (code, type, arg02)); - tem = fold (build3 (COND_EXPR, type, TREE_OPERAND (arg0, 0), - arg01, arg02)); - - /* If this was a conversion, and all we did was to move into - inside the COND_EXPR, bring it back out. But leave it if - it is a conversion from integer to integer and the - result precision is no wider than a word since such a - conversion is cheap and may be optimized away by combine, - while it couldn't if it were outside the COND_EXPR. Then return - so we don't get into an infinite recursion loop taking the - conversion out and then back in. */ - - if ((code == NOP_EXPR || code == CONVERT_EXPR - || code == NON_LVALUE_EXPR) - && TREE_CODE (tem) == COND_EXPR - && TREE_CODE (TREE_OPERAND (tem, 1)) == code - && TREE_CODE (TREE_OPERAND (tem, 2)) == code - && ! VOID_TYPE_P (TREE_OPERAND (tem, 1)) - && ! VOID_TYPE_P (TREE_OPERAND (tem, 2)) - && (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 1), 0)) - == TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 2), 0))) - && (! (INTEGRAL_TYPE_P (TREE_TYPE (tem)) - && (INTEGRAL_TYPE_P - (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 1), 0)))) - && TYPE_PRECISION (TREE_TYPE (tem)) <= BITS_PER_WORD) - || flag_syntax_only)) - tem = build1 (code, type, - build3 (COND_EXPR, - TREE_TYPE (TREE_OPERAND - (TREE_OPERAND (tem, 1), 0)), - TREE_OPERAND (tem, 0), - TREE_OPERAND (TREE_OPERAND (tem, 1), 0), - TREE_OPERAND (TREE_OPERAND (tem, 2), 0))); - return tem; - } - else if (COMPARISON_CLASS_P (arg0)) - { - if (TREE_CODE (type) == BOOLEAN_TYPE) - { - arg0 = copy_node (arg0); - TREE_TYPE (arg0) = type; - return arg0; - } - else if (TREE_CODE (type) != INTEGER_TYPE) - return fold (build3 (COND_EXPR, type, arg0, - fold (build1 (code, type, - integer_one_node)), - fold (build1 (code, type, - integer_zero_node)))); - } - } - else if (TREE_CODE_CLASS (code) == tcc_comparison + if (TREE_CODE_CLASS (code) == tcc_comparison && TREE_CODE (arg0) == COMPOUND_EXPR) return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0), fold (build2 (code, type, TREE_OPERAND (arg0, 1), arg1))); @@ -7288,194 +7201,6 @@ fold (tree expr) case CONST_DECL: return fold (DECL_INITIAL (t)); - case NOP_EXPR: - case FLOAT_EXPR: - case CONVERT_EXPR: - case FIX_TRUNC_EXPR: - case FIX_CEIL_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - if (TREE_TYPE (TREE_OPERAND (t, 0)) == type) - return TREE_OPERAND (t, 0); - - /* Handle cases of two conversions in a row. */ - if (TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR - || TREE_CODE (TREE_OPERAND (t, 0)) == CONVERT_EXPR) - { - tree inside_type = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)); - tree inter_type = TREE_TYPE (TREE_OPERAND (t, 0)); - int inside_int = INTEGRAL_TYPE_P (inside_type); - int inside_ptr = POINTER_TYPE_P (inside_type); - int inside_float = FLOAT_TYPE_P (inside_type); - unsigned int inside_prec = TYPE_PRECISION (inside_type); - int inside_unsignedp = TYPE_UNSIGNED (inside_type); - int inter_int = INTEGRAL_TYPE_P (inter_type); - int inter_ptr = POINTER_TYPE_P (inter_type); - int inter_float = FLOAT_TYPE_P (inter_type); - unsigned int inter_prec = TYPE_PRECISION (inter_type); - int inter_unsignedp = TYPE_UNSIGNED (inter_type); - int final_int = INTEGRAL_TYPE_P (type); - int final_ptr = POINTER_TYPE_P (type); - int final_float = FLOAT_TYPE_P (type); - unsigned int final_prec = TYPE_PRECISION (type); - int final_unsignedp = TYPE_UNSIGNED (type); - - /* In addition to the cases of two conversions in a row - handled below, if we are converting something to its own - type via an object of identical or wider precision, neither - conversion is needed. */ - if (TYPE_MAIN_VARIANT (inside_type) == TYPE_MAIN_VARIANT (type) - && ((inter_int && final_int) || (inter_float && final_float)) - && inter_prec >= final_prec) - return fold (build1 (code, type, - TREE_OPERAND (TREE_OPERAND (t, 0), 0))); - - /* Likewise, if the intermediate and final types are either both - float or both integer, we don't need the middle conversion if - it is wider than the final type and doesn't change the signedness - (for integers). Avoid this if the final type is a pointer - since then we sometimes need the inner conversion. Likewise if - the outer has a precision not equal to the size of its mode. */ - if ((((inter_int || inter_ptr) && (inside_int || inside_ptr)) - || (inter_float && inside_float)) - && inter_prec >= inside_prec - && (inter_float || inter_unsignedp == inside_unsignedp) - && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type)) - && TYPE_MODE (type) == TYPE_MODE (inter_type)) - && ! final_ptr) - return fold (build1 (code, type, - TREE_OPERAND (TREE_OPERAND (t, 0), 0))); - - /* If we have a sign-extension of a zero-extended value, we can - replace that by a single zero-extension. */ - if (inside_int && inter_int && final_int - && inside_prec < inter_prec && inter_prec < final_prec - && inside_unsignedp && !inter_unsignedp) - return fold (build1 (code, type, - TREE_OPERAND (TREE_OPERAND (t, 0), 0))); - - /* Two conversions in a row are not needed unless: - - some conversion is floating-point (overstrict for now), or - - the intermediate type is narrower than both initial and - final, or - - the intermediate type and innermost type differ in signedness, - and the outermost type is wider than the intermediate, or - - the initial type is a pointer type and the precisions of the - intermediate and final types differ, or - - the final type is a pointer type and the precisions of the - initial and intermediate types differ. */ - if (! inside_float && ! inter_float && ! final_float - && (inter_prec > inside_prec || inter_prec > final_prec) - && ! (inside_int && inter_int - && inter_unsignedp != inside_unsignedp - && inter_prec < final_prec) - && ((inter_unsignedp && inter_prec > inside_prec) - == (final_unsignedp && final_prec > inter_prec)) - && ! (inside_ptr && inter_prec != final_prec) - && ! (final_ptr && inside_prec != inter_prec) - && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type)) - && TYPE_MODE (type) == TYPE_MODE (inter_type)) - && ! final_ptr) - return fold (build1 (code, type, - TREE_OPERAND (TREE_OPERAND (t, 0), 0))); - } - - if (TREE_CODE (TREE_OPERAND (t, 0)) == MODIFY_EXPR - && TREE_CONSTANT (TREE_OPERAND (TREE_OPERAND (t, 0), 1)) - /* Detect assigning a bitfield. */ - && !(TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)) == COMPONENT_REF - && DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (t, 0), 0), 1)))) - { - /* Don't leave an assignment inside a conversion - unless assigning a bitfield. */ - tree prev = TREE_OPERAND (t, 0); - tem = copy_node (t); - TREE_OPERAND (tem, 0) = TREE_OPERAND (prev, 1); - /* First do the assignment, then return converted constant. */ - tem = build2 (COMPOUND_EXPR, TREE_TYPE (tem), prev, fold (tem)); - TREE_NO_WARNING (tem) = 1; - TREE_USED (tem) = 1; - return tem; - } - - /* Convert (T)(x & c) into (T)x & (T)c, if c is an integer - constants (if x has signed type, the sign bit cannot be set - in c). This folds extension into the BIT_AND_EXPR. */ - if (INTEGRAL_TYPE_P (type) - && TREE_CODE (type) != BOOLEAN_TYPE - && TREE_CODE (TREE_OPERAND (t, 0)) == BIT_AND_EXPR - && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 1)) == INTEGER_CST) - { - tree and = TREE_OPERAND (t, 0); - tree and0 = TREE_OPERAND (and, 0), and1 = TREE_OPERAND (and, 1); - int change = 0; - - if (TYPE_UNSIGNED (TREE_TYPE (and)) - || (TYPE_PRECISION (type) - <= TYPE_PRECISION (TREE_TYPE (and)))) - change = 1; - else if (TYPE_PRECISION (TREE_TYPE (and1)) - <= HOST_BITS_PER_WIDE_INT - && host_integerp (and1, 1)) - { - unsigned HOST_WIDE_INT cst; - - cst = tree_low_cst (and1, 1); - cst &= (HOST_WIDE_INT) -1 - << (TYPE_PRECISION (TREE_TYPE (and1)) - 1); - change = (cst == 0); -#ifdef LOAD_EXTEND_OP - if (change - && !flag_syntax_only - && (LOAD_EXTEND_OP (TYPE_MODE (TREE_TYPE (and0))) - == ZERO_EXTEND)) - { - tree uns = lang_hooks.types.unsigned_type (TREE_TYPE (and0)); - and0 = fold_convert (uns, and0); - and1 = fold_convert (uns, and1); - } -#endif - } - if (change) - { - tem = build_int_cst_wide (type, TREE_INT_CST_LOW (and1), - TREE_INT_CST_HIGH (and1)); - tem = force_fit_type (tem, 0, TREE_OVERFLOW (and1), - TREE_CONSTANT_OVERFLOW (and1)); - return fold (build2 (BIT_AND_EXPR, type, - fold_convert (type, and0), tem)); - } - } - - /* Convert (T1)((T2)X op Y) into (T1)X op Y, for pointer types T1 and - T2 being pointers to types of the same size. */ - if (POINTER_TYPE_P (TREE_TYPE (t)) - && BINARY_CLASS_P (arg0) - && TREE_CODE (TREE_OPERAND (arg0, 0)) == NOP_EXPR - && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg0, 0)))) - { - tree arg00 = TREE_OPERAND (arg0, 0); - tree t0 = TREE_TYPE (t); - tree t1 = TREE_TYPE (arg00); - tree tt0 = TREE_TYPE (t0); - tree tt1 = TREE_TYPE (t1); - tree s0 = TYPE_SIZE (tt0); - tree s1 = TYPE_SIZE (tt1); - - if (s0 && s1 && operand_equal_p (s0, s1, OEP_ONLY_CONST)) - return build2 (TREE_CODE (arg0), t0, fold_convert (t0, arg00), - TREE_OPERAND (arg0, 1)); - } - - tem = fold_convert_const (code, type, arg0); - return tem ? tem : t; - - case VIEW_CONVERT_EXPR: - if (TREE_CODE (TREE_OPERAND (t, 0)) == VIEW_CONVERT_EXPR) - return build1 (VIEW_CONVERT_EXPR, type, - TREE_OPERAND (TREE_OPERAND (t, 0), 0)); - return t; - case COMPONENT_REF: if (TREE_CODE (arg0) == CONSTRUCTOR && ! type_contains_placeholder_p (TREE_TYPE (arg0))) @@ -7496,80 +7221,6 @@ fold (tree expr) } return t; - case NEGATE_EXPR: - if (negate_expr_p (arg0)) - return fold_convert (type, negate_expr (arg0)); - /* Convert - (~A) to A + 1. */ - if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == BIT_NOT_EXPR) - return fold (build2 (PLUS_EXPR, type, TREE_OPERAND (arg0, 0), - build_int_cst (type, 1))); - return t; - - case ABS_EXPR: - if (TREE_CODE (arg0) == INTEGER_CST || TREE_CODE (arg0) == REAL_CST) - return fold_abs_const (arg0, type); - else if (TREE_CODE (arg0) == NEGATE_EXPR) - return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg0, 0))); - /* Convert fabs((double)float) into (double)fabsf(float). */ - else if (TREE_CODE (arg0) == NOP_EXPR - && TREE_CODE (type) == REAL_TYPE) - { - tree targ0 = strip_float_extensions (arg0); - if (targ0 != arg0) - return fold_convert (type, fold (build1 (ABS_EXPR, - TREE_TYPE (targ0), - targ0))); - } - else if (tree_expr_nonnegative_p (arg0)) - return arg0; - - /* Strip sign ops from argument. */ - if (TREE_CODE (type) == REAL_TYPE) - { - tem = fold_strip_sign_ops (arg0); - if (tem) - return fold (build1 (ABS_EXPR, type, fold_convert (type, tem))); - } - return t; - - case CONJ_EXPR: - if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE) - return fold_convert (type, arg0); - else if (TREE_CODE (arg0) == COMPLEX_EXPR) - return build2 (COMPLEX_EXPR, type, - TREE_OPERAND (arg0, 0), - negate_expr (TREE_OPERAND (arg0, 1))); - else if (TREE_CODE (arg0) == COMPLEX_CST) - return build_complex (type, TREE_REALPART (arg0), - negate_expr (TREE_IMAGPART (arg0))); - else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR) - return fold (build2 (TREE_CODE (arg0), type, - fold (build1 (CONJ_EXPR, type, - TREE_OPERAND (arg0, 0))), - fold (build1 (CONJ_EXPR, type, - TREE_OPERAND (arg0, 1))))); - else if (TREE_CODE (arg0) == CONJ_EXPR) - return TREE_OPERAND (arg0, 0); - return t; - - case BIT_NOT_EXPR: - if (TREE_CODE (arg0) == INTEGER_CST) - return fold_not_const (arg0, type); - else if (TREE_CODE (arg0) == BIT_NOT_EXPR) - return TREE_OPERAND (arg0, 0); - /* Convert ~ (-A) to A - 1. */ - else if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR) - return fold (build2 (MINUS_EXPR, type, TREE_OPERAND (arg0, 0), - build_int_cst (type, 1))); - /* Convert ~ (A - 1) or ~ (A + -1) to -A. */ - else if (INTEGRAL_TYPE_P (type) - && ((TREE_CODE (arg0) == MINUS_EXPR - && integer_onep (TREE_OPERAND (arg0, 1))) - || (TREE_CODE (arg0) == PLUS_EXPR - && integer_all_onesp (TREE_OPERAND (arg0, 1))))) - return fold (build1 (NEGATE_EXPR, type, TREE_OPERAND (arg0, 0))); - return t; - case PLUS_EXPR: /* A + (-B) -> A - B */ if (TREE_CODE (arg1) == NEGATE_EXPR) @@ -8907,21 +8558,6 @@ fold (tree expr) return omit_one_operand (type, arg1, arg0); goto associate; - case TRUTH_NOT_EXPR: - /* The argument to invert_truthvalue must have Boolean type. */ - if (TREE_CODE (TREE_TYPE (arg0)) != BOOLEAN_TYPE) - arg0 = fold_convert (boolean_type_node, arg0); - - /* Note that the operand of this must be an int - and its values must be 0 or 1. - ("true" is a fixed value perhaps depending on the language, - but we don't handle values other than 1 correctly yet.) */ - tem = invert_truthvalue (arg0); - /* Avoid infinite recursion. */ - if (TREE_CODE (tem) == TRUTH_NOT_EXPR) - return t; - return fold_convert (type, tem); - case TRUTH_ANDIF_EXPR: /* Note that the operands of this must be ints and their values must be 0 or 1. @@ -10194,38 +9830,6 @@ fold (tree expr) return build_complex (type, arg0, arg1); return t; - case REALPART_EXPR: - if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE) - return t; - else if (TREE_CODE (arg0) == COMPLEX_EXPR) - return omit_one_operand (type, TREE_OPERAND (arg0, 0), - TREE_OPERAND (arg0, 1)); - else if (TREE_CODE (arg0) == COMPLEX_CST) - return TREE_REALPART (arg0); - else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR) - return fold (build2 (TREE_CODE (arg0), type, - fold (build1 (REALPART_EXPR, type, - TREE_OPERAND (arg0, 0))), - fold (build1 (REALPART_EXPR, type, - TREE_OPERAND (arg0, 1))))); - return t; - - case IMAGPART_EXPR: - if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE) - return fold_convert (type, integer_zero_node); - else if (TREE_CODE (arg0) == COMPLEX_EXPR) - return omit_one_operand (type, TREE_OPERAND (arg0, 1), - TREE_OPERAND (arg0, 0)); - else if (TREE_CODE (arg0) == COMPLEX_CST) - return TREE_IMAGPART (arg0); - else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR) - return fold (build2 (TREE_CODE (arg0), type, - fold (build1 (IMAGPART_EXPR, type, - TREE_OPERAND (arg0, 0))), - fold (build1 (IMAGPART_EXPR, type, - TREE_OPERAND (arg0, 1))))); - return t; - case CALL_EXPR: /* Check for a built-in function. */ if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR