diff options
Diffstat (limited to 'gcc/tree-ssa-forwprop.c')
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 361 |
1 files changed, 0 insertions, 361 deletions
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 2d6a9fb..b47f7e2 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -1920,359 +1920,6 @@ simplify_rotate (gimple_stmt_iterator *gsi) return true; } -/* Perform re-associations of the plus or minus statement STMT that are - always permitted. Returns true if the CFG was changed. */ - -static bool -associate_plusminus (gimple_stmt_iterator *gsi) -{ - gimple stmt = gsi_stmt (*gsi); - tree rhs1 = gimple_assign_rhs1 (stmt); - tree rhs2 = gimple_assign_rhs2 (stmt); - enum tree_code code = gimple_assign_rhs_code (stmt); - bool changed; - - /* We can't reassociate at all for saturating types. */ - if (TYPE_SATURATING (TREE_TYPE (rhs1))) - return false; - - /* First contract negates. */ - do - { - changed = false; - - /* A +- (-B) -> A -+ B. */ - if (TREE_CODE (rhs2) == SSA_NAME) - { - gimple def_stmt = SSA_NAME_DEF_STMT (rhs2); - if (is_gimple_assign (def_stmt) - && gimple_assign_rhs_code (def_stmt) == NEGATE_EXPR - && can_propagate_from (def_stmt)) - { - code = (code == MINUS_EXPR) ? PLUS_EXPR : MINUS_EXPR; - gimple_assign_set_rhs_code (stmt, code); - rhs2 = gimple_assign_rhs1 (def_stmt); - gimple_assign_set_rhs2 (stmt, rhs2); - gimple_set_modified (stmt, true); - changed = true; - } - } - - /* (-A) + B -> B - A. */ - if (TREE_CODE (rhs1) == SSA_NAME - && code == PLUS_EXPR) - { - gimple def_stmt = SSA_NAME_DEF_STMT (rhs1); - if (is_gimple_assign (def_stmt) - && gimple_assign_rhs_code (def_stmt) == NEGATE_EXPR - && can_propagate_from (def_stmt)) - { - code = MINUS_EXPR; - gimple_assign_set_rhs_code (stmt, code); - rhs1 = rhs2; - gimple_assign_set_rhs1 (stmt, rhs1); - rhs2 = gimple_assign_rhs1 (def_stmt); - gimple_assign_set_rhs2 (stmt, rhs2); - gimple_set_modified (stmt, true); - changed = true; - } - } - } - while (changed); - - /* We can't reassociate floating-point or fixed-point plus or minus - because of saturation to +-Inf. */ - if (FLOAT_TYPE_P (TREE_TYPE (rhs1)) - || FIXED_POINT_TYPE_P (TREE_TYPE (rhs1))) - goto out; - - /* Second match patterns that allow contracting a plus-minus pair - irrespective of overflow issues. - - (A +- B) - A -> +- B - (A +- B) -+ B -> A - (CST +- A) +- CST -> CST +- A - (A +- CST) +- CST -> A +- CST - ~A + A -> -1 - ~A + 1 -> -A - A - (A +- B) -> -+ B - A +- (B +- A) -> +- B - CST +- (CST +- A) -> CST +- A - CST +- (A +- CST) -> CST +- A - A + ~A -> -1 - (T)(P + A) - (T)P -> (T)A - - via commutating the addition and contracting operations to zero - by reassociation. */ - - if (TREE_CODE (rhs1) == SSA_NAME) - { - gimple def_stmt = SSA_NAME_DEF_STMT (rhs1); - if (is_gimple_assign (def_stmt) && can_propagate_from (def_stmt)) - { - enum tree_code def_code = gimple_assign_rhs_code (def_stmt); - if (def_code == PLUS_EXPR - || def_code == MINUS_EXPR) - { - tree def_rhs1 = gimple_assign_rhs1 (def_stmt); - tree def_rhs2 = gimple_assign_rhs2 (def_stmt); - if (operand_equal_p (def_rhs1, rhs2, 0) - && code == MINUS_EXPR) - { - /* (A +- B) - A -> +- B. */ - code = ((def_code == PLUS_EXPR) - ? TREE_CODE (def_rhs2) : NEGATE_EXPR); - rhs1 = def_rhs2; - rhs2 = NULL_TREE; - gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE); - gcc_assert (gsi_stmt (*gsi) == stmt); - gimple_set_modified (stmt, true); - } - else if (operand_equal_p (def_rhs2, rhs2, 0) - && code != def_code) - { - /* (A +- B) -+ B -> A. */ - code = TREE_CODE (def_rhs1); - rhs1 = def_rhs1; - rhs2 = NULL_TREE; - gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE); - gcc_assert (gsi_stmt (*gsi) == stmt); - gimple_set_modified (stmt, true); - } - else if (CONSTANT_CLASS_P (rhs2) - && CONSTANT_CLASS_P (def_rhs1)) - { - /* (CST +- A) +- CST -> CST +- A. */ - tree cst = fold_binary (code, TREE_TYPE (rhs1), - def_rhs1, rhs2); - if (cst && !TREE_OVERFLOW (cst)) - { - code = def_code; - gimple_assign_set_rhs_code (stmt, code); - rhs1 = cst; - gimple_assign_set_rhs1 (stmt, rhs1); - rhs2 = def_rhs2; - gimple_assign_set_rhs2 (stmt, rhs2); - gimple_set_modified (stmt, true); - } - } - else if (CONSTANT_CLASS_P (rhs2) - && CONSTANT_CLASS_P (def_rhs2)) - { - /* (A +- CST) +- CST -> A +- CST. */ - enum tree_code mix = (code == def_code) - ? PLUS_EXPR : MINUS_EXPR; - tree cst = fold_binary (mix, TREE_TYPE (rhs1), - def_rhs2, rhs2); - if (cst && !TREE_OVERFLOW (cst)) - { - code = def_code; - gimple_assign_set_rhs_code (stmt, code); - rhs1 = def_rhs1; - gimple_assign_set_rhs1 (stmt, rhs1); - rhs2 = cst; - gimple_assign_set_rhs2 (stmt, rhs2); - gimple_set_modified (stmt, true); - } - } - } - else if (def_code == BIT_NOT_EXPR && code == PLUS_EXPR) - { - tree def_rhs1 = gimple_assign_rhs1 (def_stmt); - if (operand_equal_p (def_rhs1, rhs2, 0)) - { - /* ~A + A -> -1. */ - rhs1 = build_all_ones_cst (TREE_TYPE (rhs2)); - rhs2 = NULL_TREE; - code = TREE_CODE (rhs1); - gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE); - gcc_assert (gsi_stmt (*gsi) == stmt); - gimple_set_modified (stmt, true); - } - else if ((TREE_CODE (TREE_TYPE (rhs2)) != COMPLEX_TYPE - && integer_onep (rhs2)) - || (TREE_CODE (rhs2) == COMPLEX_CST - && integer_onep (TREE_REALPART (rhs2)) - && integer_onep (TREE_IMAGPART (rhs2)))) - { - /* ~A + 1 -> -A. */ - code = NEGATE_EXPR; - rhs1 = def_rhs1; - rhs2 = NULL_TREE; - gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE); - gcc_assert (gsi_stmt (*gsi) == stmt); - gimple_set_modified (stmt, true); - } - } - else if (code == MINUS_EXPR - && CONVERT_EXPR_CODE_P (def_code) - && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME - && TREE_CODE (rhs2) == SSA_NAME) - { - /* (T)(P + A) - (T)P -> (T)A. */ - gimple def_stmt2 = SSA_NAME_DEF_STMT (rhs2); - if (is_gimple_assign (def_stmt2) - && can_propagate_from (def_stmt2) - && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt2)) - && TREE_CODE (gimple_assign_rhs1 (def_stmt2)) == SSA_NAME) - { - /* Now we have (T)X - (T)P. */ - tree p = gimple_assign_rhs1 (def_stmt2); - def_stmt2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt)); - if (is_gimple_assign (def_stmt2) - && can_propagate_from (def_stmt2) - && (gimple_assign_rhs_code (def_stmt2) == POINTER_PLUS_EXPR - || gimple_assign_rhs_code (def_stmt2) == PLUS_EXPR) - && gimple_assign_rhs1 (def_stmt2) == p) - { - /* And finally (T)(P + A) - (T)P. */ - tree a = gimple_assign_rhs2 (def_stmt2); - if (TYPE_PRECISION (TREE_TYPE (rhs1)) - <= TYPE_PRECISION (TREE_TYPE (a)) - /* For integer types, if A has a smaller type - than T the result depends on the possible - overflow in P + A. - E.g. T=size_t, A=(unsigned)429497295, P>0. - However, if an overflow in P + A would cause - undefined behavior, we can assume that there - is no overflow. */ - || (INTEGRAL_TYPE_P (TREE_TYPE (p)) - && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (p))) - /* For pointer types, if the conversion of A to the - final type requires a sign- or zero-extension, - then we have to punt - it is not defined which - one is correct. */ - || (POINTER_TYPE_P (TREE_TYPE (p)) - && TREE_CODE (a) == INTEGER_CST - && tree_int_cst_sign_bit (a) == 0)) - { - if (issue_strict_overflow_warning - (WARN_STRICT_OVERFLOW_MISC) - && TYPE_PRECISION (TREE_TYPE (rhs1)) - > TYPE_PRECISION (TREE_TYPE (a)) - && INTEGRAL_TYPE_P (TREE_TYPE (p))) - warning_at (gimple_location (stmt), - OPT_Wstrict_overflow, - "assuming signed overflow does not " - "occur when assuming that " - "(T)(P + A) - (T)P is always (T)A"); - if (useless_type_conversion_p (TREE_TYPE (rhs1), - TREE_TYPE (a))) - code = TREE_CODE (a); - else - code = NOP_EXPR; - rhs1 = a; - rhs2 = NULL_TREE; - gimple_assign_set_rhs_with_ops (gsi, code, rhs1, - rhs2); - gcc_assert (gsi_stmt (*gsi) == stmt); - gimple_set_modified (stmt, true); - } - } - } - } - } - } - - if (rhs2 && TREE_CODE (rhs2) == SSA_NAME) - { - gimple def_stmt = SSA_NAME_DEF_STMT (rhs2); - if (is_gimple_assign (def_stmt) && can_propagate_from (def_stmt)) - { - enum tree_code def_code = gimple_assign_rhs_code (def_stmt); - if (def_code == PLUS_EXPR - || def_code == MINUS_EXPR) - { - tree def_rhs1 = gimple_assign_rhs1 (def_stmt); - tree def_rhs2 = gimple_assign_rhs2 (def_stmt); - if (operand_equal_p (def_rhs1, rhs1, 0) - && code == MINUS_EXPR) - { - /* A - (A +- B) -> -+ B. */ - code = ((def_code == PLUS_EXPR) - ? NEGATE_EXPR : TREE_CODE (def_rhs2)); - rhs1 = def_rhs2; - rhs2 = NULL_TREE; - gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE); - gcc_assert (gsi_stmt (*gsi) == stmt); - gimple_set_modified (stmt, true); - } - else if (operand_equal_p (def_rhs2, rhs1, 0) - && code != def_code) - { - /* A +- (B +- A) -> +- B. */ - code = ((code == PLUS_EXPR) - ? TREE_CODE (def_rhs1) : NEGATE_EXPR); - rhs1 = def_rhs1; - rhs2 = NULL_TREE; - gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE); - gcc_assert (gsi_stmt (*gsi) == stmt); - gimple_set_modified (stmt, true); - } - else if (CONSTANT_CLASS_P (rhs1) - && CONSTANT_CLASS_P (def_rhs1)) - { - /* CST +- (CST +- A) -> CST +- A. */ - tree cst = fold_binary (code, TREE_TYPE (rhs2), - rhs1, def_rhs1); - if (cst && !TREE_OVERFLOW (cst)) - { - code = (code == def_code ? PLUS_EXPR : MINUS_EXPR); - gimple_assign_set_rhs_code (stmt, code); - rhs1 = cst; - gimple_assign_set_rhs1 (stmt, rhs1); - rhs2 = def_rhs2; - gimple_assign_set_rhs2 (stmt, rhs2); - gimple_set_modified (stmt, true); - } - } - else if (CONSTANT_CLASS_P (rhs1) - && CONSTANT_CLASS_P (def_rhs2)) - { - /* CST +- (A +- CST) -> CST +- A. */ - tree cst = fold_binary (def_code == code - ? PLUS_EXPR : MINUS_EXPR, - TREE_TYPE (rhs2), - rhs1, def_rhs2); - if (cst && !TREE_OVERFLOW (cst)) - { - rhs1 = cst; - gimple_assign_set_rhs1 (stmt, rhs1); - rhs2 = def_rhs1; - gimple_assign_set_rhs2 (stmt, rhs2); - gimple_set_modified (stmt, true); - } - } - } - else if (def_code == BIT_NOT_EXPR) - { - tree def_rhs1 = gimple_assign_rhs1 (def_stmt); - if (code == PLUS_EXPR - && operand_equal_p (def_rhs1, rhs1, 0)) - { - /* A + ~A -> -1. */ - rhs1 = build_all_ones_cst (TREE_TYPE (rhs1)); - rhs2 = NULL_TREE; - code = TREE_CODE (rhs1); - gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE); - gcc_assert (gsi_stmt (*gsi) == stmt); - gimple_set_modified (stmt, true); - } - } - } - } - -out: - if (gimple_modified_p (stmt)) - { - fold_stmt_inplace (gsi); - update_stmt (stmt); - return true; - } - - return false; -} - /* Combine an element access with a shuffle. Returns true if there were any changes made, else it returns false. */ @@ -2805,14 +2452,6 @@ pass_forwprop::execute (function *fun) || code == BIT_XOR_EXPR) && simplify_rotate (&gsi)) changed = true; - else if (code == PLUS_EXPR - || code == MINUS_EXPR) - { - changed = associate_plusminus (&gsi); - if (changed - && maybe_clean_or_replace_eh_stmt (stmt, stmt)) - bitmap_set_bit (to_purge, bb->index); - } else if (code == VEC_PERM_EXPR) { int did_something = simplify_permutation (&gsi); |