diff options
author | Bernd Schmidt <bernds@codesourcery.com> | 2010-06-25 08:56:24 +0000 |
---|---|---|
committer | Bernd Schmidt <bernds@gcc.gnu.org> | 2010-06-25 08:56:24 +0000 |
commit | 0354c0c70b2a090a3705fffd6a87313233b5516d (patch) | |
tree | 5a50f0008cf354dc460d1db0b3077d133fe49dbb /gcc/tree-ssa-ccp.c | |
parent | 38f78b0c69999b7e2eec2ce58a02d08b24be7f43 (diff) | |
download | gcc-0354c0c70b2a090a3705fffd6a87313233b5516d.zip gcc-0354c0c70b2a090a3705fffd6a87313233b5516d.tar.gz gcc-0354c0c70b2a090a3705fffd6a87313233b5516d.tar.bz2 |
With large parts from Jim Wilson:
PR target/43902
* tree-pretty-print.c (dump_generic_node, op_code_prio): Add
WIDEN_MULT_PLUS_EXPR and WIDEN_MULT_MINUS_EXPR.
* optabs.c (optab_for_tree_code): Likewise.
(expand_widen_pattern_expr): Likewise.
* tree-ssa-math-opts.c (convert_mult_to_widen): New function, broken
out of execute_optimize_widening_mul.
(convert_plusminus_to_widen): New function.
(execute_optimize_widening_mul): Use the two new functions.
* expr.c (expand_expr_real_2): Add support for GIMPLE_TERNARY_RHS.
Remove code to generate widening multiply-accumulate. Add support
for WIDEN_MULT_PLUS_EXPR and WIDEN_MULT_MINUS_EXPR.
* gimple-pretty-print.c (dump_ternary_rhs): New function.
(dump_gimple_assign): Call it when appropriate.
* tree.def (WIDEN_MULT_PLUS_EXPR, WIDEN_MULT_MINUS_EXPR): New codes.
* cfgexpand.c (gimple_assign_rhs_to_tree): Likewise.
(expand_gimple_stmt_1): Likewise.
(expand_debug_expr): Support WIDEN_MULT_PLUS_EXPR and
WIDEN_MULT_MINUS_EXPR.
* tree-ssa-operands.c (get_expr_operands): Likewise.
* tree-inline.c (estimate_operator_cost): Likewise.
* gimple.c (extract_ops_from_tree_1): Renamed from
extract_ops_from_tree. Add new arg for a third operand; fill it.
(gimple_build_assign_stat): Support operations with three operands.
(gimple_build_assign_with_ops_stat): Likewise.
(gimple_assign_set_rhs_from_tree): Likewise.
(gimple_assign_set_rhs_with_ops_1): Renamed from
gimple_assign_set_rhs_with_ops. Add new arg for a third operand.
(get_gimple_rhs_num_ops): Support GIMPLE_TERNARY_RHS.
(get_gimple_rhs_num_ops): Handle WIDEN_MULT_PLUS_EXPR and
WIDEN_MULT_MINUS_EXPR.
* gimple.h (enum gimple_rhs_class): Add GIMPLE_TERNARY_RHS.
(extract_ops_from_tree_1): Adjust declaration.
(gimple_assign_set_rhs_with_ops_1): Likewise.
(gimple_build_assign_with_ops): Pass NULL for last operand.
(gimple_build_assign_with_ops3): New macro.
(gimple_assign_rhs3, gimple_assign_rhs3_ptr, gimple_assign_set_rhs3,
gimple_assign_set_rhs_with_ops, extract_ops_from_tree): New inline
functions.
* tree-cfg.c (verify_gimple_assign_ternary): New static function.
(verify_gimple_assign): Call it.
* doc/gimple.texi (Manipulating operands): Document GIMPLE_TERNARY_RHS.
(Tuple specific accessors, subsection GIMPLE_ASSIGN): Document new
functions for dealing with three-operand statements.
* tree.c (commutative_ternary_tree_code): New function.
* tree.h (commutative_ternary_tree_code): Declare it.
* tree-vrp.c (gimple_assign_nonnegative_warnv_p): Return false for ternary
statements.
(gimple_assign_nonzero_warnv_p): Likewise.
* tree-ssa-sccvn.c (stmt_has_constants): Handle GIMPLE_TERNARY_RHS.
* tree-ssa-ccp.c (get_rhs_assign_op_for_ccp): New static function.
(ccp_fold): Use it. Handle GIMPLE_TERNARY_RHS.
* tree-ssa-dom.c (enum expr_kind): Add EXPR_TERNARY.
(struct hashtable_expr): New member ternary in the union.
(initialize_hash_element): Handle GIMPLE_TERNARY_RHS.
(hashable_expr_equal_p): Fix indentation. Handle EXPR_TERNARY.
(iterative_hash_hashable_expr): Likewise.
(print_expr_hash_elt): Handle EXPR_TERNARY.
* gimple-fold.c (fold_gimple_assign): Handle GIMPLE_TERNARY_RHS.
* tree-ssa-threadedge.c (fold_assignment_stmt): Remove useless break
statements. Handle GIMPLE_TERNARY_RHS.
testsuite/
PR target/43902
* gcc.target/mips/madd-9.c: New test.
From-SVN: r161366
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r-- | gcc/tree-ssa-ccp.c | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 2b6139b..be4509c 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -839,6 +839,23 @@ ccp_visit_phi_node (gimple phi) return SSA_PROP_NOT_INTERESTING; } +/* Get operand number OPNR from the rhs of STMT. Before returning it, + simplify it to a constant if possible. */ + +static tree +get_rhs_assign_op_for_ccp (gimple stmt, int opnr) +{ + tree op = gimple_op (stmt, opnr); + + if (TREE_CODE (op) == SSA_NAME) + { + prop_value_t *val = get_value (op); + if (val->lattice_val == CONSTANT) + op = get_value (op)->value; + } + return op; +} + /* CCP specific front-end to the non-destructive constant folding routines. @@ -961,15 +978,7 @@ ccp_fold (gimple stmt) Note that we know the single operand must be a constant, so this should almost always return a simplified RHS. */ tree lhs = gimple_assign_lhs (stmt); - tree op0 = gimple_assign_rhs1 (stmt); - - /* Simplify the operand down to a constant. */ - if (TREE_CODE (op0) == SSA_NAME) - { - prop_value_t *val = get_value (op0); - if (val->lattice_val == CONSTANT) - op0 = get_value (op0)->value; - } + tree op0 = get_rhs_assign_op_for_ccp (stmt, 1); /* Conversions are useless for CCP purposes if they are value-preserving. Thus the restrictions that @@ -1006,23 +1015,8 @@ ccp_fold (gimple stmt) case GIMPLE_BINARY_RHS: { /* Handle binary operators that can appear in GIMPLE form. */ - tree op0 = gimple_assign_rhs1 (stmt); - tree op1 = gimple_assign_rhs2 (stmt); - - /* Simplify the operands down to constants when appropriate. */ - if (TREE_CODE (op0) == SSA_NAME) - { - prop_value_t *val = get_value (op0); - if (val->lattice_val == CONSTANT) - op0 = val->value; - } - - if (TREE_CODE (op1) == SSA_NAME) - { - prop_value_t *val = get_value (op1); - if (val->lattice_val == CONSTANT) - op1 = val->value; - } + tree op0 = get_rhs_assign_op_for_ccp (stmt, 1); + tree op1 = get_rhs_assign_op_for_ccp (stmt, 2); /* Fold &foo + CST into an invariant reference if possible. */ if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR @@ -1039,6 +1033,17 @@ ccp_fold (gimple stmt) gimple_expr_type (stmt), op0, op1); } + case GIMPLE_TERNARY_RHS: + { + /* Handle binary operators that can appear in GIMPLE form. */ + tree op0 = get_rhs_assign_op_for_ccp (stmt, 1); + tree op1 = get_rhs_assign_op_for_ccp (stmt, 2); + tree op2 = get_rhs_assign_op_for_ccp (stmt, 3); + + return fold_ternary_loc (loc, subcode, + gimple_expr_type (stmt), op0, op1, op2); + } + default: gcc_unreachable (); } |