diff options
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/builtins.c | 44 | ||||
-rw-r--r-- | gcc/fold-const.c | 356 | ||||
-rw-r--r-- | gcc/tree-complex.c | 62 | ||||
-rw-r--r-- | gcc/tree.h | 3 |
5 files changed, 71 insertions, 411 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 40e204c462c..f3dff19d71e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2005-06-16 Richard Henderson <rth@redhat.com> + + PR tree-opt/22035 + * builtins.c (fold_builtin_complex_mul): Remove. + (fold_builtin_complex_div): Remove. + (fold_builtin_1): Don't call them. + * fold-const.c (fold_complex_add, fold_complex_mult_parts, + fold_complex_mult, fold_complex_div_parts, fold_complex_div): Remove. + (fold_binary): Don't call them. Don't expand complex comparisons to + elementary comparisons. + * tree-complex.c (init_dont_simulate_again): Enhance search for + stmts that require decomposition. + (complex_visit_stmt): Handle RETURN_EXPR properly. + (create_components): Handle no referenced variables properly. + * tree.h (fold_complex_mult_parts): Remove. + (fold_complex_div_parts): Remove. + 2005-06-16 Richard Guenther <rguenth@gcc.gnu.org> * doc/extend.texi: Document sseregparm target attribute. diff --git a/gcc/builtins.c b/gcc/builtins.c index cdc5cebcbc6..b0e3f40a942 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -8430,44 +8430,6 @@ fold_builtin_unordered_cmp (tree fndecl, tree arglist, fold (build2 (code, type, arg0, arg1)))); } -/* Fold a call to one of the external complex multiply libcalls. */ - -static tree -fold_builtin_complex_mul (tree type, tree arglist) -{ - tree ar, ai, br, bi; - - if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, REAL_TYPE, - REAL_TYPE, VOID_TYPE)) - return NULL; - - ar = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist); - ai = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist); - br = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist); - bi = TREE_VALUE (arglist); - - return fold_complex_mult_parts (type, ar, ai, br, bi); -} - -/* Fold a call to one of the external complex division libcalls. */ - -static tree -fold_builtin_complex_div (tree type, tree arglist) -{ - tree ar, ai, br, bi; - - if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, REAL_TYPE, - REAL_TYPE, VOID_TYPE)) - return NULL; - - ar = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist); - ai = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist); - br = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist); - bi = TREE_VALUE (arglist); - - return fold_complex_div_parts (type, ar, ai, br, bi, RDIV_EXPR); -} - /* Used by constant folding to simplify calls to builtin functions. EXP is the CALL_EXPR of a call to a builtin function. IGNORE is true if the result of the function call is ignored. This function returns NULL_TREE @@ -8826,12 +8788,6 @@ fold_builtin_1 (tree fndecl, tree arglist, bool ignore) break; default: - if (fcode >= BUILT_IN_COMPLEX_MUL_MIN - && fcode <= BUILT_IN_COMPLEX_MUL_MAX) - return fold_builtin_complex_mul (type, arglist); - if (fcode >= BUILT_IN_COMPLEX_DIV_MIN - && fcode <= BUILT_IN_COMPLEX_DIV_MAX) - return fold_builtin_complex_div (type, arglist); break; } diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 2c1bd15b365..8433d1dfd98 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -6493,300 +6493,6 @@ fold_to_nonsharp_ineq_using_bound (tree ineq, tree bound) return fold_build2 (GE_EXPR, type, a, y); } -/* Fold complex addition when both components are accessible by parts. - Return non-null if successful. CODE should be PLUS_EXPR for addition, - or MINUS_EXPR for subtraction. */ - -static tree -fold_complex_add (tree type, tree ac, tree bc, enum tree_code code) -{ - tree ar, ai, br, bi, rr, ri, inner_type; - - if (TREE_CODE (ac) == COMPLEX_EXPR) - ar = TREE_OPERAND (ac, 0), ai = TREE_OPERAND (ac, 1); - else if (TREE_CODE (ac) == COMPLEX_CST) - ar = TREE_REALPART (ac), ai = TREE_IMAGPART (ac); - else - return NULL; - - if (TREE_CODE (bc) == COMPLEX_EXPR) - br = TREE_OPERAND (bc, 0), bi = TREE_OPERAND (bc, 1); - else if (TREE_CODE (bc) == COMPLEX_CST) - br = TREE_REALPART (bc), bi = TREE_IMAGPART (bc); - else - return NULL; - - inner_type = TREE_TYPE (type); - - rr = fold_build2 (code, inner_type, ar, br); - ri = fold_build2 (code, inner_type, ai, bi); - - return fold_build2 (COMPLEX_EXPR, type, rr, ri); -} - -/* Perform some simplifications of complex multiplication when one or more - of the components are constants or zeros. Return non-null if successful. */ - -tree -fold_complex_mult_parts (tree type, tree ar, tree ai, tree br, tree bi) -{ - tree rr, ri, inner_type, zero; - bool ar0, ai0, br0, bi0, bi1; - - inner_type = TREE_TYPE (type); - zero = NULL; - - if (SCALAR_FLOAT_TYPE_P (inner_type)) - { - ar0 = ai0 = br0 = bi0 = bi1 = false; - - /* We're only interested in +0.0 here, thus we don't use real_zerop. */ - - if (TREE_CODE (ar) == REAL_CST - && REAL_VALUES_IDENTICAL (TREE_REAL_CST (ar), dconst0)) - ar0 = true, zero = ar; - - if (TREE_CODE (ai) == REAL_CST - && REAL_VALUES_IDENTICAL (TREE_REAL_CST (ai), dconst0)) - ai0 = true, zero = ai; - - if (TREE_CODE (br) == REAL_CST - && REAL_VALUES_IDENTICAL (TREE_REAL_CST (br), dconst0)) - br0 = true, zero = br; - - if (TREE_CODE (bi) == REAL_CST) - { - if (REAL_VALUES_IDENTICAL (TREE_REAL_CST (bi), dconst0)) - bi0 = true, zero = bi; - else if (REAL_VALUES_IDENTICAL (TREE_REAL_CST (bi), dconst1)) - bi1 = true; - } - } - else - { - ar0 = integer_zerop (ar); - if (ar0) - zero = ar; - ai0 = integer_zerop (ai); - if (ai0) - zero = ai; - br0 = integer_zerop (br); - if (br0) - zero = br; - bi0 = integer_zerop (bi); - if (bi0) - { - zero = bi; - bi1 = false; - } - else - bi1 = integer_onep (bi); - } - - /* We won't optimize anything below unless something is zero. */ - if (zero == NULL) - return NULL; - - if (ai0 && br0 && bi1) - { - rr = zero; - ri = ar; - } - else if (ai0 && bi0) - { - rr = fold_build2 (MULT_EXPR, inner_type, ar, br); - ri = zero; - } - else if (ai0 && br0) - { - rr = zero; - ri = fold_build2 (MULT_EXPR, inner_type, ar, bi); - } - else if (ar0 && bi0) - { - rr = zero; - ri = fold_build2 (MULT_EXPR, inner_type, ai, br); - } - else if (ar0 && br0) - { - rr = fold_build2 (MULT_EXPR, inner_type, ai, bi); - rr = fold_build1 (NEGATE_EXPR, inner_type, rr); - ri = zero; - } - else if (bi0) - { - rr = fold_build2 (MULT_EXPR, inner_type, ar, br); - ri = fold_build2 (MULT_EXPR, inner_type, ai, br); - } - else if (ai0) - { - rr = fold_build2 (MULT_EXPR, inner_type, ar, br); - ri = fold_build2 (MULT_EXPR, inner_type, ar, bi); - } - else if (br0) - { - rr = fold_build2 (MULT_EXPR, inner_type, ai, bi); - rr = fold_build1 (NEGATE_EXPR, inner_type, rr); - ri = fold_build2 (MULT_EXPR, inner_type, ar, bi); - } - else if (ar0) - { - rr = fold_build2 (MULT_EXPR, inner_type, ai, bi); - rr = fold_build1 (NEGATE_EXPR, inner_type, rr); - ri = fold_build2 (MULT_EXPR, inner_type, ai, br); - } - else - return NULL; - - return fold_build2 (COMPLEX_EXPR, type, rr, ri); -} - -static tree -fold_complex_mult (tree type, tree ac, tree bc) -{ - tree ar, ai, br, bi; - - if (TREE_CODE (ac) == COMPLEX_EXPR) - ar = TREE_OPERAND (ac, 0), ai = TREE_OPERAND (ac, 1); - else if (TREE_CODE (ac) == COMPLEX_CST) - ar = TREE_REALPART (ac), ai = TREE_IMAGPART (ac); - else - return NULL; - - if (TREE_CODE (bc) == COMPLEX_EXPR) - br = TREE_OPERAND (bc, 0), bi = TREE_OPERAND (bc, 1); - else if (TREE_CODE (bc) == COMPLEX_CST) - br = TREE_REALPART (bc), bi = TREE_IMAGPART (bc); - else - return NULL; - - return fold_complex_mult_parts (type, ar, ai, br, bi); -} - -/* Perform some simplifications of complex division when one or more of - the components are constants or zeros. Return non-null if successful. */ - -tree -fold_complex_div_parts (tree type, tree ar, tree ai, tree br, tree bi, - enum tree_code code) -{ - tree rr, ri, inner_type, zero; - bool ar0, ai0, br0, bi0, bi1; - - inner_type = TREE_TYPE (type); - zero = NULL; - - if (SCALAR_FLOAT_TYPE_P (inner_type)) - { - ar0 = ai0 = br0 = bi0 = bi1 = false; - - /* We're only interested in +0.0 here, thus we don't use real_zerop. */ - - if (TREE_CODE (ar) == REAL_CST - && REAL_VALUES_IDENTICAL (TREE_REAL_CST (ar), dconst0)) - ar0 = true, zero = ar; - - if (TREE_CODE (ai) == REAL_CST - && REAL_VALUES_IDENTICAL (TREE_REAL_CST (ai), dconst0)) - ai0 = true, zero = ai; - - if (TREE_CODE (br) == REAL_CST - && REAL_VALUES_IDENTICAL (TREE_REAL_CST (br), dconst0)) - br0 = true, zero = br; - - if (TREE_CODE (bi) == REAL_CST) - { - if (REAL_VALUES_IDENTICAL (TREE_REAL_CST (bi), dconst0)) - bi0 = true, zero = bi; - else if (REAL_VALUES_IDENTICAL (TREE_REAL_CST (bi), dconst1)) - bi1 = true; - } - } - else - { - ar0 = integer_zerop (ar); - if (ar0) - zero = ar; - ai0 = integer_zerop (ai); - if (ai0) - zero = ai; - br0 = integer_zerop (br); - if (br0) - zero = br; - bi0 = integer_zerop (bi); - if (bi0) - { - zero = bi; - bi1 = false; - } - else - bi1 = integer_onep (bi); - } - - /* We won't optimize anything below unless something is zero. */ - if (zero == NULL) - return NULL; - - if (ai0 && bi0) - { - rr = fold_build2 (code, inner_type, ar, br); - ri = zero; - } - else if (ai0 && br0) - { - rr = zero; - ri = fold_build2 (code, inner_type, ar, bi); - ri = fold_build1 (NEGATE_EXPR, inner_type, ri); - } - else if (ar0 && bi0) - { - rr = zero; - ri = fold_build2 (code, inner_type, ai, br); - } - else if (ar0 && br0) - { - rr = fold_build2 (code, inner_type, ai, bi); - ri = zero; - } - else if (bi0) - { - rr = fold_build2 (code, inner_type, ar, br); - ri = fold_build2 (code, inner_type, ai, br); - } - else if (br0) - { - rr = fold_build2 (code, inner_type, ai, bi); - ri = fold_build2 (code, inner_type, ar, bi); - ri = fold_build1 (NEGATE_EXPR, inner_type, ri); - } - else - return NULL; - - return fold_build2 (COMPLEX_EXPR, type, rr, ri); -} - -static tree -fold_complex_div (tree type, tree ac, tree bc, enum tree_code code) -{ - tree ar, ai, br, bi; - - if (TREE_CODE (ac) == COMPLEX_EXPR) - ar = TREE_OPERAND (ac, 0), ai = TREE_OPERAND (ac, 1); - else if (TREE_CODE (ac) == COMPLEX_CST) - ar = TREE_REALPART (ac), ai = TREE_IMAGPART (ac); - else - return NULL; - - if (TREE_CODE (bc) == COMPLEX_EXPR) - br = TREE_OPERAND (bc, 0), bi = TREE_OPERAND (bc, 1); - else if (TREE_CODE (bc) == COMPLEX_CST) - br = TREE_REALPART (bc), bi = TREE_IMAGPART (bc); - else - return NULL; - - return fold_complex_div_parts (type, ar, ai, br, bi, code); -} - /* Fold a unary expression of code CODE and type TYPE with operand OP0. Return the folded expression if folding is successful. Otherwise, return NULL_TREE. */ @@ -7418,13 +7124,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) && integer_onep (arg1)) return fold_build1 (NEGATE_EXPR, type, TREE_OPERAND (arg0, 0)); - if (TREE_CODE (type) == COMPLEX_TYPE) - { - tem = fold_complex_add (type, arg0, arg1, PLUS_EXPR); - if (tem) - return tem; - } - if (! FLOAT_TYPE_P (type)) { if (integer_zerop (arg1)) @@ -7870,13 +7569,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) && integer_all_onesp (arg0)) return fold_build1 (BIT_NOT_EXPR, type, arg1); - if (TREE_CODE (type) == COMPLEX_TYPE) - { - tem = fold_complex_add (type, arg0, arg1, MINUS_EXPR); - if (tem) - return tem; - } - if (! FLOAT_TYPE_P (type)) { if (! wins && integer_zerop (arg0)) @@ -8033,13 +7725,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) negate_expr (arg0), TREE_OPERAND (arg1, 0)); - if (TREE_CODE (type) == COMPLEX_TYPE) - { - tem = fold_complex_mult (type, arg0, arg1); - if (tem) - return tem; - } - if (! FLOAT_TYPE_P (type)) { if (integer_zerop (arg1)) @@ -8501,13 +8186,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) TREE_OPERAND (arg1, 0)); } - if (TREE_CODE (type) == COMPLEX_TYPE) - { - tem = fold_complex_div (type, arg0, arg1, code); - if (tem) - return tem; - } - if (flag_unsafe_math_optimizations) { enum built_in_function fcode = builtin_mathfn_code (arg1); @@ -8631,12 +8309,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) && 0 != (tem = extract_muldiv (op0, arg1, code, NULL_TREE))) return fold_convert (type, tem); - if (TREE_CODE (type) == COMPLEX_TYPE) - { - tem = fold_complex_div (type, arg0, arg1, code); - if (tem) - return tem; - } goto binary; case CEIL_MOD_EXPR: @@ -9926,34 +9598,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) } } - /* If this is a comparison of complex values and either or both sides - are a COMPLEX_EXPR or COMPLEX_CST, it is best to split up the - comparisons and join them with a TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR. - This may prevent needless evaluations. */ - if ((code == EQ_EXPR || code == NE_EXPR) - && TREE_CODE (TREE_TYPE (arg0)) == COMPLEX_TYPE - && (TREE_CODE (arg0) == COMPLEX_EXPR - || TREE_CODE (arg1) == COMPLEX_EXPR - || TREE_CODE (arg0) == COMPLEX_CST - || TREE_CODE (arg1) == COMPLEX_CST)) - { - tree subtype = TREE_TYPE (TREE_TYPE (arg0)); - tree real0, imag0, real1, imag1; - - arg0 = save_expr (arg0); - arg1 = save_expr (arg1); - real0 = fold_build1 (REALPART_EXPR, subtype, arg0); - imag0 = fold_build1 (IMAGPART_EXPR, subtype, arg0); - real1 = fold_build1 (REALPART_EXPR, subtype, arg1); - imag1 = fold_build1 (IMAGPART_EXPR, subtype, arg1); - - return fold_build2 ((code == EQ_EXPR ? TRUTH_ANDIF_EXPR - : TRUTH_ORIF_EXPR), - type, - fold_build2 (code, type, real0, real1), - fold_build2 (code, type, imag0, imag1)); - } - /* Optimize comparisons of strlen vs zero to a compare of the first character of the string vs zero. To wit, strlen(ptr) == 0 => *ptr == 0 diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c index 1fa76a900c3..a4c7329d3dd 100644 --- a/gcc/tree-complex.c +++ b/gcc/tree-complex.c @@ -150,7 +150,7 @@ init_dont_simulate_again (void) basic_block bb; block_stmt_iterator bsi; tree phi; - bool saw_a_complex_value = false; + bool saw_a_complex_op = false; FOR_EACH_BB (bb) { @@ -159,21 +159,62 @@ init_dont_simulate_again (void) for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) { - tree stmt = bsi_stmt (bsi); + tree orig_stmt, stmt, rhs = NULL; bool dsa = true; - if (TREE_CODE (stmt) == MODIFY_EXPR - && is_complex_reg (TREE_OPERAND (stmt, 0))) + orig_stmt = stmt = bsi_stmt (bsi); + switch (TREE_CODE (stmt)) { - dsa = false; - saw_a_complex_value = true; + case RETURN_EXPR: + stmt = TREE_OPERAND (stmt, 0); + if (!stmt || TREE_CODE (stmt) != MODIFY_EXPR) + break; + /* FALLTHRU */ + + case MODIFY_EXPR: + dsa = !is_complex_reg (TREE_OPERAND (stmt, 0)); + rhs = TREE_OPERAND (stmt, 1); + break; + + case COND_EXPR: + rhs = TREE_OPERAND (stmt, 0); + break; + + default: + break; } - DONT_SIMULATE_AGAIN (stmt) = dsa; + if (rhs) + switch (TREE_CODE (rhs)) + { + case EQ_EXPR: + case NE_EXPR: + rhs = TREE_OPERAND (rhs, 0); + /* FALLTHRU */ + + case PLUS_EXPR: + case MINUS_EXPR: + case MULT_EXPR: + case TRUNC_DIV_EXPR: + case CEIL_DIV_EXPR: + case FLOOR_DIV_EXPR: + case ROUND_DIV_EXPR: + case RDIV_EXPR: + case NEGATE_EXPR: + case CONJ_EXPR: + if (TREE_CODE (TREE_TYPE (rhs)) == COMPLEX_TYPE) + saw_a_complex_op = true; + break; + + default: + break; + } + + DONT_SIMULATE_AGAIN (orig_stmt) = dsa; } } - return saw_a_complex_value; + return saw_a_complex_op; } @@ -189,6 +230,8 @@ complex_visit_stmt (tree stmt, edge *taken_edge_p ATTRIBUTE_UNUSED, /* These conditions should be satisfied due to the initial filter set up in init_dont_simulate_again. */ + if (TREE_CODE (stmt) == RETURN_EXPR) + stmt = TREE_OPERAND (stmt, 0); gcc_assert (TREE_CODE (stmt) == MODIFY_EXPR); lhs = TREE_OPERAND (stmt, 0); @@ -308,6 +351,9 @@ create_components (void) size_t k, n; n = num_referenced_vars; + if (n == 0) + return; + complex_variable_components = VEC_alloc (tree, heap, 2*n); VEC_safe_grow (tree, heap, complex_variable_components, 2*n); diff --git a/gcc/tree.h b/gcc/tree.h index e2e646fa54f..c434f2fe509 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -3611,9 +3611,6 @@ extern tree build_fold_indirect_ref (tree); extern tree fold_indirect_ref (tree); extern tree constant_boolean_node (int, tree); extern tree build_low_bits_mask (tree, unsigned); -extern tree fold_complex_mult_parts (tree, tree, tree, tree, tree); -extern tree fold_complex_div_parts (tree, tree, tree, tree, tree, - enum tree_code); extern bool tree_swap_operands_p (tree, tree, bool); extern enum tree_code swap_tree_comparison (enum tree_code); |