gcc/ChangeLog.gimple-classes: * gimple-fold.c (fold_gimple_assign): Strengthen local "stmt" from gimple to gassign * via a checked cast. (gsi_replace_with_seq_vops): Add a checked cast within region guarded by gimple_assign_single_p. (get_maxval_strlen): Within case GIMPLE_ASSIGN, introduce local gassign * "def_assign" via a checked cast, and use it in place of "def_stmt" for typesafety. (replace_stmt_with_simplification): Add a checked cast. (fold_stmt_1): In two switch statements, within case GIMPLE_ASSIGN, introduce locals gassign * "assign_stmt" via checked casts, and use them in place of "stmt" for typesafety. (same_bool_comparison_p): Replace "is_gimple_assign" with dyn_cast, introducing local "assign_s" and using it in place of "s" for typesafety. (and_var_with_comparison): Strengthen local "stmt" from gimple to gassign * by replacing an is_gimple_assign with a dyn_cast. (and_var_with_comparison_1): Strengthen param "stmt" and local "s" from gimple to gassign *, replacing is_gimple_assign calls with dyn_cast. (or_var_with_comparison): Strengthen local "stmt" from gimple to gassign * by replacing an is_gimple_assign with a dyn_cast. (or_var_with_comparison_1): Strengthen param "stmt" and local "s" from gimple to gassign *, replacing is_gimple_assign calls with dyn_cast. (gimple_fold_stmt_to_constant_1): Within case GIMPLE_ASSIGN, introduce local "assign_stmt" and use in place of "stmt" for typesafety. (gimple_val_nonnegative_real_p): Replace is_gimple_assign with a dyn_cast, introducing local "def_assign" and using it in place of "def_stmt" for typesafety. --- gcc/ChangeLog.gimple-classes | 33 +++++++++ gcc/gimple-fold.c | 166 +++++++++++++++++++++++-------------------- 2 files changed, 123 insertions(+), 76 deletions(-)
diff --git a/gcc/ChangeLog.gimple-classes b/gcc/ChangeLog.gimple-classes index dc1315e..be9aa76 100644 --- a/gcc/ChangeLog.gimple-classes +++ b/gcc/ChangeLog.gimple-classes @@ -1,5 +1,38 @@ 2014-11-03 David Malcolm <dmalc...@redhat.com> + * gimple-fold.c (fold_gimple_assign): Strengthen local "stmt" from + gimple to gassign * via a checked cast. + (gsi_replace_with_seq_vops): Add a checked cast within region + guarded by gimple_assign_single_p. + (get_maxval_strlen): Within case GIMPLE_ASSIGN, introduce local + gassign * "def_assign" via a checked cast, and use it in place of + "def_stmt" for typesafety. + (replace_stmt_with_simplification): Add a checked cast. + (fold_stmt_1): In two switch statements, within case + GIMPLE_ASSIGN, introduce locals gassign * "assign_stmt" via + checked casts, and use them in place of "stmt" for typesafety. + (same_bool_comparison_p): Replace "is_gimple_assign" with + dyn_cast, introducing local "assign_s" and using it in place of + "s" for typesafety. + (and_var_with_comparison): Strengthen local "stmt" from gimple to + gassign * by replacing an is_gimple_assign with a dyn_cast. + (and_var_with_comparison_1): Strengthen param "stmt" and local "s" + from gimple to gassign *, replacing is_gimple_assign calls with + dyn_cast. + (or_var_with_comparison): Strengthen local "stmt" from gimple to + gassign * by replacing an is_gimple_assign with a dyn_cast. + (or_var_with_comparison_1): Strengthen param "stmt" and local "s" + from gimple to gassign *, replacing is_gimple_assign calls with + dyn_cast. + (gimple_fold_stmt_to_constant_1): Within case GIMPLE_ASSIGN, + introduce local "assign_stmt" and use in place of "stmt" for + typesafety. + (gimple_val_nonnegative_real_p): Replace is_gimple_assign with a + dyn_cast, introducing local "def_assign" and using it in place of + "def_stmt" for typesafety. + +2014-11-03 David Malcolm <dmalc...@redhat.com> + * gimple-ssa-isolate-paths.c (insert_trap_and_remove_trailing_statements): Replace a call to is_gimple_assign with a dyn_cast, introducing a local diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index c5f1e07..3b85686 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -302,7 +302,7 @@ maybe_fold_reference (tree expr, bool is_lhs) static tree fold_gimple_assign (gimple_stmt_iterator *si) { - gimple stmt = gsi_stmt (*si); + gassign *stmt = as_a <gassign *> (gsi_stmt (*si)); enum tree_code subcode = gimple_assign_rhs_code (stmt); location_t loc = gimple_location (stmt); @@ -600,7 +600,7 @@ gsi_replace_with_seq_vops (gimple_stmt_iterator *si_p, gimple_seq stmts) { gimple new_stmt = gsi_stmt (i); if ((gimple_assign_single_p (new_stmt) - && !is_gimple_reg (gimple_assign_lhs (new_stmt))) + && !is_gimple_reg (gimple_assign_lhs (as_a <gassign *> (new_stmt)))) || (is_gimple_call (new_stmt) && (gimple_call_flags (new_stmt) & (ECF_NOVOPS | ECF_PURE | ECF_CONST | ECF_NORETURN)) == 0)) @@ -1364,22 +1364,25 @@ get_maxval_strlen (tree arg, tree *length, bitmap *visited, int type) switch (gimple_code (def_stmt)) { case GIMPLE_ASSIGN: - /* The RHS of the statement defining VAR must either have a - constant length or come from another SSA_NAME with a constant - length. */ - if (gimple_assign_single_p (def_stmt) - || gimple_assign_unary_nop_p (def_stmt)) - { - tree rhs = gimple_assign_rhs1 (def_stmt); - return get_maxval_strlen (rhs, length, visited, type); - } - else if (gimple_assign_rhs_code (def_stmt) == COND_EXPR) - { - tree op2 = gimple_assign_rhs2 (def_stmt); - tree op3 = gimple_assign_rhs3 (def_stmt); - return get_maxval_strlen (op2, length, visited, type) - && get_maxval_strlen (op3, length, visited, type); - } + { + gassign *def_assign = as_a <gassign *> (def_stmt); + /* The RHS of the statement defining VAR must either have a + constant length or come from another SSA_NAME with a constant + length. */ + if (gimple_assign_single_p (def_assign) + || gimple_assign_unary_nop_p (def_assign)) + { + tree rhs = gimple_assign_rhs1 (def_assign); + return get_maxval_strlen (rhs, length, visited, type); + } + else if (gimple_assign_rhs_code (def_assign) == COND_EXPR) + { + tree op2 = gimple_assign_rhs2 (def_assign); + tree op3 = gimple_assign_rhs3 (def_assign); + return get_maxval_strlen (op2, length, visited, type) + && get_maxval_strlen (op3, length, visited, type); + } + } return false; case GIMPLE_PHI: @@ -2874,7 +2877,8 @@ replace_stmt_with_simplification (gimple_stmt_iterator *gsi, || gimple_num_ops (stmt) <= get_gimple_rhs_num_ops (rcode)) { maybe_build_generic_op (rcode, - TREE_TYPE (gimple_assign_lhs (stmt)), + TREE_TYPE (gimple_assign_lhs ( + as_a <gassign *> (stmt))), &ops[0], ops[1], ops[2]); gimple_assign_set_rhs_with_ops_1 (gsi, rcode, ops[0], ops[1], ops[2]); @@ -3012,18 +3016,21 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree)) switch (gimple_code (stmt)) { case GIMPLE_ASSIGN: - if (gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS) - { - tree *rhs = gimple_assign_rhs1_ptr (stmt); - if ((REFERENCE_CLASS_P (*rhs) - || TREE_CODE (*rhs) == ADDR_EXPR) - && maybe_canonicalize_mem_ref_addr (rhs)) - changed = true; - tree *lhs = gimple_assign_lhs_ptr (stmt); - if (REFERENCE_CLASS_P (*lhs) - && maybe_canonicalize_mem_ref_addr (lhs)) - changed = true; - } + { + gassign *assign_stmt = as_a <gassign *> (stmt); + if (gimple_assign_rhs_class (assign_stmt) == GIMPLE_SINGLE_RHS) + { + tree *rhs = gimple_assign_rhs1_ptr (assign_stmt); + if ((REFERENCE_CLASS_P (*rhs) + || TREE_CODE (*rhs) == ADDR_EXPR) + && maybe_canonicalize_mem_ref_addr (rhs)) + changed = true; + tree *lhs = gimple_assign_lhs_ptr (assign_stmt); + if (REFERENCE_CLASS_P (*lhs) + && maybe_canonicalize_mem_ref_addr (lhs)) + changed = true; + } + } break; case GIMPLE_CALL: { @@ -3101,20 +3108,22 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree)) { case GIMPLE_ASSIGN: { + gassign *assign_stmt = as_a <gassign *> (stmt); unsigned old_num_ops = gimple_num_ops (stmt); - enum tree_code subcode = gimple_assign_rhs_code (stmt); - tree lhs = gimple_assign_lhs (stmt); + enum tree_code subcode = gimple_assign_rhs_code (assign_stmt); + tree lhs = gimple_assign_lhs (assign_stmt); tree new_rhs; /* First canonicalize operand order. This avoids building new trees if this is the only thing fold would later do. */ if ((commutative_tree_code (subcode) || commutative_ternary_tree_code (subcode)) - && tree_swap_operands_p (gimple_assign_rhs1 (stmt), - gimple_assign_rhs2 (stmt), false)) + && tree_swap_operands_p (gimple_assign_rhs1 (assign_stmt), + gimple_assign_rhs2 (assign_stmt), false)) { - tree tem = gimple_assign_rhs1 (stmt); - gimple_assign_set_rhs1 (stmt, gimple_assign_rhs2 (stmt)); - gimple_assign_set_rhs2 (stmt, tem); + tree tem = gimple_assign_rhs1 (assign_stmt); + gimple_assign_set_rhs1 (assign_stmt, + gimple_assign_rhs2 (assign_stmt)); + gimple_assign_set_rhs2 (assign_stmt, tem); changed = true; } new_rhs = fold_gimple_assign (gsi); @@ -3336,6 +3345,7 @@ same_bool_comparison_p (const_tree expr, enum tree_code code, const_tree op1, const_tree op2) { gimple s; + gassign *assign_s; /* The obvious case. */ if (TREE_CODE (expr) == code @@ -3352,10 +3362,10 @@ same_bool_comparison_p (const_tree expr, enum tree_code code, return ((code == NE_EXPR && integer_zerop (op2)) || (code == EQ_EXPR && integer_nonzerop (op2))); s = SSA_NAME_DEF_STMT (expr); - if (is_gimple_assign (s) - && gimple_assign_rhs_code (s) == code - && operand_equal_p (gimple_assign_rhs1 (s), op1, 0) - && operand_equal_p (gimple_assign_rhs2 (s), op2, 0)) + if ((assign_s = dyn_cast <gassign *> (s)) + && gimple_assign_rhs_code (assign_s) == code + && operand_equal_p (gimple_assign_rhs1 (assign_s), op1, 0) + && operand_equal_p (gimple_assign_rhs2 (assign_s), op2, 0)) return true; } @@ -3365,21 +3375,22 @@ same_bool_comparison_p (const_tree expr, enum tree_code code, && TREE_CODE (TREE_TYPE (op1)) == BOOLEAN_TYPE) { s = SSA_NAME_DEF_STMT (op1); - if (is_gimple_assign (s) - && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison) + if ((assign_s = dyn_cast <gassign *> (s)) + && (TREE_CODE_CLASS (gimple_assign_rhs_code (assign_s)) + == tcc_comparison)) { - enum tree_code c = gimple_assign_rhs_code (s); + enum tree_code c = gimple_assign_rhs_code (assign_s); if ((c == NE_EXPR && integer_zerop (op2)) || (c == EQ_EXPR && integer_nonzerop (op2))) return same_bool_comparison_p (expr, c, - gimple_assign_rhs1 (s), - gimple_assign_rhs2 (s)); + gimple_assign_rhs1 (assign_s), + gimple_assign_rhs2 (assign_s)); if ((c == EQ_EXPR && integer_zerop (op2)) || (c == NE_EXPR && integer_nonzerop (op2))) return same_bool_comparison_p (expr, invert_tree_comparison (c, false), - gimple_assign_rhs1 (s), - gimple_assign_rhs2 (s)); + gimple_assign_rhs1 (assign_s), + gimple_assign_rhs2 (assign_s)); } } return false; @@ -3422,7 +3433,7 @@ static tree and_var_with_comparison (tree var, bool invert, enum tree_code code2, tree op2a, tree op2b); static tree -and_var_with_comparison_1 (gimple stmt, +and_var_with_comparison_1 (gassign *stmt, enum tree_code code2, tree op2a, tree op2b); static tree or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, @@ -3431,7 +3442,7 @@ static tree or_var_with_comparison (tree var, bool invert, enum tree_code code2, tree op2a, tree op2b); static tree -or_var_with_comparison_1 (gimple stmt, +or_var_with_comparison_1 (gassign *stmt, enum tree_code code2, tree op2a, tree op2b); /* Helper function for and_comparisons_1: try to simplify the AND of the @@ -3444,10 +3455,11 @@ and_var_with_comparison (tree var, bool invert, enum tree_code code2, tree op2a, tree op2b) { tree t; - gimple stmt = SSA_NAME_DEF_STMT (var); + gassign *stmt; /* We can only deal with variables whose definitions are assignments. */ - if (!is_gimple_assign (stmt)) + stmt = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (var)); + if (!stmt) return NULL_TREE; /* If we have an inverted comparison, apply DeMorgan's law and rewrite @@ -3467,7 +3479,7 @@ and_var_with_comparison (tree var, bool invert, Return NULL_EXPR if we can't simplify this to a single expression. */ static tree -and_var_with_comparison_1 (gimple stmt, +and_var_with_comparison_1 (gassign *stmt, enum tree_code code2, tree op2a, tree op2b) { tree var = gimple_assign_lhs (stmt); @@ -3515,7 +3527,7 @@ and_var_with_comparison_1 (gimple stmt, { tree inner1 = gimple_assign_rhs1 (stmt); tree inner2 = gimple_assign_rhs2 (stmt); - gimple s; + gassign *s; tree t; tree partial = NULL_TREE; bool is_and = (innercode == BIT_AND_EXPR); @@ -3543,7 +3555,7 @@ and_var_with_comparison_1 (gimple stmt, /* Next, redistribute/reassociate the AND across the inner tests. Compute the first partial result, (inner1 AND (op2a code op2b)) */ if (TREE_CODE (inner1) == SSA_NAME - && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1)) + && (s = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (inner1))) && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison && (t = maybe_fold_and_comparisons (gimple_assign_rhs_code (s), gimple_assign_rhs1 (s), @@ -3575,7 +3587,7 @@ and_var_with_comparison_1 (gimple stmt, /* Compute the second partial result, (inner2 AND (op2a code op2b)) */ if (TREE_CODE (inner2) == SSA_NAME - && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2)) + && (s = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (inner2))) && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison && (t = maybe_fold_and_comparisons (gimple_assign_rhs_code (s), gimple_assign_rhs1 (s), @@ -3907,10 +3919,11 @@ or_var_with_comparison (tree var, bool invert, enum tree_code code2, tree op2a, tree op2b) { tree t; - gimple stmt = SSA_NAME_DEF_STMT (var); + gassign *stmt; /* We can only deal with variables whose definitions are assignments. */ - if (!is_gimple_assign (stmt)) + stmt = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (var)); + if (!stmt) return NULL_TREE; /* If we have an inverted comparison, apply DeMorgan's law and rewrite @@ -3930,7 +3943,7 @@ or_var_with_comparison (tree var, bool invert, Return NULL_EXPR if we can't simplify this to a single expression. */ static tree -or_var_with_comparison_1 (gimple stmt, +or_var_with_comparison_1 (gassign *stmt, enum tree_code code2, tree op2a, tree op2b) { tree var = gimple_assign_lhs (stmt); @@ -3978,7 +3991,7 @@ or_var_with_comparison_1 (gimple stmt, { tree inner1 = gimple_assign_rhs1 (stmt); tree inner2 = gimple_assign_rhs2 (stmt); - gimple s; + gassign *s; tree t; tree partial = NULL_TREE; bool is_or = (innercode == BIT_IOR_EXPR); @@ -4006,7 +4019,7 @@ or_var_with_comparison_1 (gimple stmt, /* Next, redistribute/reassociate the OR across the inner tests. Compute the first partial result, (inner1 OR (op2a code op2b)) */ if (TREE_CODE (inner1) == SSA_NAME - && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1)) + && (s = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (inner1))) && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison && (t = maybe_fold_or_comparisons (gimple_assign_rhs_code (s), gimple_assign_rhs1 (s), @@ -4038,7 +4051,7 @@ or_var_with_comparison_1 (gimple stmt, /* Compute the second partial result, (inner2 OR (op2a code op2b)) */ if (TREE_CODE (inner2) == SSA_NAME - && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2)) + && (s = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (inner2))) && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison && (t = maybe_fold_or_comparisons (gimple_assign_rhs_code (s), gimple_assign_rhs1 (s), @@ -4379,13 +4392,14 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree)) { case GIMPLE_ASSIGN: { - enum tree_code subcode = gimple_assign_rhs_code (stmt); + gassign *assign_stmt = as_a <gassign *> (stmt); + enum tree_code subcode = gimple_assign_rhs_code (assign_stmt); switch (get_gimple_rhs_class (subcode)) { case GIMPLE_SINGLE_RHS: { - tree rhs = gimple_assign_rhs1 (stmt); + tree rhs = gimple_assign_rhs1 (assign_stmt); enum tree_code_class kind = TREE_CODE_CLASS (subcode); if (TREE_CODE (rhs) == SSA_NAME) @@ -4489,7 +4503,7 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree)) /* Handle unary operators that can appear in GIMPLE form. Note that we know the single operand must be a constant, so this should almost always return a simplified RHS. */ - tree op0 = (*valueize) (gimple_assign_rhs1 (stmt)); + tree op0 = (*valueize) (gimple_assign_rhs1 (assign_stmt)); return fold_unary_ignore_overflow_loc (loc, subcode, @@ -4499,12 +4513,12 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree)) case GIMPLE_BINARY_RHS: { /* Handle binary operators that can appear in GIMPLE form. */ - tree op0 = (*valueize) (gimple_assign_rhs1 (stmt)); - tree op1 = (*valueize) (gimple_assign_rhs2 (stmt)); + tree op0 = (*valueize) (gimple_assign_rhs1 (assign_stmt)); + tree op1 = (*valueize) (gimple_assign_rhs2 (assign_stmt)); /* Translate &x + CST into an invariant form suitable for further propagation. */ - if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR + if (gimple_assign_rhs_code (assign_stmt) == POINTER_PLUS_EXPR && TREE_CODE (op0) == ADDR_EXPR && TREE_CODE (op1) == INTEGER_CST) { @@ -4523,9 +4537,9 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree)) case GIMPLE_TERNARY_RHS: { /* Handle ternary operators that can appear in GIMPLE form. */ - tree op0 = (*valueize) (gimple_assign_rhs1 (stmt)); - tree op1 = (*valueize) (gimple_assign_rhs2 (stmt)); - tree op2 = (*valueize) (gimple_assign_rhs3 (stmt)); + tree op0 = (*valueize) (gimple_assign_rhs1 (assign_stmt)); + tree op1 = (*valueize) (gimple_assign_rhs2 (assign_stmt)); + tree op2 = (*valueize) (gimple_assign_rhs3 (assign_stmt)); /* Fold embedded expressions in ternary codes. */ if ((subcode == COND_EXPR @@ -5238,14 +5252,14 @@ gimple_val_nonnegative_real_p (tree val) def_stmt = SSA_NAME_DEF_STMT (val); - if (is_gimple_assign (def_stmt)) + if (gassign *def_assign = dyn_cast <gassign *> (def_stmt)) { tree op0, op1; /* See fold-const.c:tree_expr_nonnegative_p for additional cases that could be handled with recursion. */ - switch (gimple_assign_rhs_code (def_stmt)) + switch (gimple_assign_rhs_code (def_assign)) { case ABS_EXPR: /* Always true for floating-point operands. */ @@ -5254,8 +5268,8 @@ gimple_val_nonnegative_real_p (tree val) case MULT_EXPR: /* True if the two operands are identical (since we are restricted to floating-point inputs). */ - op0 = gimple_assign_rhs1 (def_stmt); - op1 = gimple_assign_rhs2 (def_stmt); + op0 = gimple_assign_rhs1 (def_assign); + op1 = gimple_assign_rhs2 (def_assign); if (op0 == op1 || operand_equal_p (op0, op1, 0)) -- 1.7.11.7