diff options
Diffstat (limited to 'gcc/tree-ssa-dom.c')
-rw-r--r-- | gcc/tree-ssa-dom.c | 118 |
1 files changed, 84 insertions, 34 deletions
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 25eb306369d..68338206a8a 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -51,6 +51,7 @@ enum expr_kind EXPR_SINGLE, EXPR_UNARY, EXPR_BINARY, + EXPR_TERNARY, EXPR_CALL }; @@ -61,7 +62,8 @@ struct hashable_expr union { struct { tree rhs; } single; struct { enum tree_code op; tree opnd; } unary; - struct { enum tree_code op; tree opnd0; tree opnd1; } binary; + struct { enum tree_code op; tree opnd0, opnd1; } binary; + struct { enum tree_code op; tree opnd0, opnd1, opnd2; } ternary; struct { tree fn; bool pure; size_t nargs; tree *args; } call; } ops; }; @@ -211,22 +213,30 @@ initialize_hash_element (gimple stmt, tree lhs, switch (get_gimple_rhs_class (subcode)) { case GIMPLE_SINGLE_RHS: - expr->kind = EXPR_SINGLE; - expr->ops.single.rhs = gimple_assign_rhs1 (stmt); - break; + expr->kind = EXPR_SINGLE; + expr->ops.single.rhs = gimple_assign_rhs1 (stmt); + break; case GIMPLE_UNARY_RHS: - expr->kind = EXPR_UNARY; + expr->kind = EXPR_UNARY; expr->type = TREE_TYPE (gimple_assign_lhs (stmt)); - expr->ops.unary.op = subcode; - expr->ops.unary.opnd = gimple_assign_rhs1 (stmt); - break; + expr->ops.unary.op = subcode; + expr->ops.unary.opnd = gimple_assign_rhs1 (stmt); + break; case GIMPLE_BINARY_RHS: - expr->kind = EXPR_BINARY; + expr->kind = EXPR_BINARY; expr->type = TREE_TYPE (gimple_assign_lhs (stmt)); - expr->ops.binary.op = subcode; - expr->ops.binary.opnd0 = gimple_assign_rhs1 (stmt); - expr->ops.binary.opnd1 = gimple_assign_rhs2 (stmt); - break; + expr->ops.binary.op = subcode; + expr->ops.binary.opnd0 = gimple_assign_rhs1 (stmt); + expr->ops.binary.opnd1 = gimple_assign_rhs2 (stmt); + break; + case GIMPLE_TERNARY_RHS: + expr->kind = EXPR_TERNARY; + expr->type = TREE_TYPE (gimple_assign_lhs (stmt)); + expr->ops.ternary.op = subcode; + expr->ops.ternary.opnd0 = gimple_assign_rhs1 (stmt); + expr->ops.ternary.opnd1 = gimple_assign_rhs2 (stmt); + expr->ops.ternary.opnd2 = gimple_assign_rhs3 (stmt); + break; default: gcc_unreachable (); } @@ -371,23 +381,40 @@ hashable_expr_equal_p (const struct hashable_expr *expr0, expr1->ops.unary.opnd, 0); case EXPR_BINARY: - { - if (expr0->ops.binary.op != expr1->ops.binary.op) - return false; - - if (operand_equal_p (expr0->ops.binary.opnd0, - expr1->ops.binary.opnd0, 0) - && operand_equal_p (expr0->ops.binary.opnd1, - expr1->ops.binary.opnd1, 0)) - return true; - - /* For commutative ops, allow the other order. */ - return (commutative_tree_code (expr0->ops.binary.op) - && operand_equal_p (expr0->ops.binary.opnd0, - expr1->ops.binary.opnd1, 0) - && operand_equal_p (expr0->ops.binary.opnd1, - expr1->ops.binary.opnd0, 0)); - } + if (expr0->ops.binary.op != expr1->ops.binary.op) + return false; + + if (operand_equal_p (expr0->ops.binary.opnd0, + expr1->ops.binary.opnd0, 0) + && operand_equal_p (expr0->ops.binary.opnd1, + expr1->ops.binary.opnd1, 0)) + return true; + + /* For commutative ops, allow the other order. */ + return (commutative_tree_code (expr0->ops.binary.op) + && operand_equal_p (expr0->ops.binary.opnd0, + expr1->ops.binary.opnd1, 0) + && operand_equal_p (expr0->ops.binary.opnd1, + expr1->ops.binary.opnd0, 0)); + + case EXPR_TERNARY: + if (expr0->ops.ternary.op != expr1->ops.ternary.op + || !operand_equal_p (expr0->ops.ternary.opnd2, + expr1->ops.ternary.opnd2, 0)) + return false; + + if (operand_equal_p (expr0->ops.ternary.opnd0, + expr1->ops.ternary.opnd0, 0) + && operand_equal_p (expr0->ops.ternary.opnd1, + expr1->ops.ternary.opnd1, 0)) + return true; + + /* For commutative ops, allow the other order. */ + return (commutative_ternary_tree_code (expr0->ops.ternary.op) + && operand_equal_p (expr0->ops.ternary.opnd0, + expr1->ops.ternary.opnd1, 0) + && operand_equal_p (expr0->ops.ternary.opnd1, + expr1->ops.ternary.opnd0, 0)); case EXPR_CALL: { @@ -450,8 +477,8 @@ iterative_hash_hashable_expr (const struct hashable_expr *expr, hashval_t val) case EXPR_BINARY: val = iterative_hash_object (expr->ops.binary.op, val); if (commutative_tree_code (expr->ops.binary.op)) - val = iterative_hash_exprs_commutative (expr->ops.binary.opnd0, - expr->ops.binary.opnd1, val); + val = iterative_hash_exprs_commutative (expr->ops.binary.opnd0, + expr->ops.binary.opnd1, val); else { val = iterative_hash_expr (expr->ops.binary.opnd0, val); @@ -459,6 +486,19 @@ iterative_hash_hashable_expr (const struct hashable_expr *expr, hashval_t val) } break; + case EXPR_TERNARY: + val = iterative_hash_object (expr->ops.ternary.op, val); + if (commutative_ternary_tree_code (expr->ops.ternary.op)) + val = iterative_hash_exprs_commutative (expr->ops.ternary.opnd0, + expr->ops.ternary.opnd1, val); + else + { + val = iterative_hash_expr (expr->ops.ternary.opnd0, val); + val = iterative_hash_expr (expr->ops.ternary.opnd1, val); + } + val = iterative_hash_expr (expr->ops.ternary.opnd2, val); + break; + case EXPR_CALL: { size_t i; @@ -511,6 +551,16 @@ print_expr_hash_elt (FILE * stream, const struct expr_hash_elt *element) print_generic_expr (stream, element->expr.ops.binary.opnd1, 0); break; + case EXPR_TERNARY: + fprintf (stream, " %s <", tree_code_name[element->expr.ops.ternary.op]); + print_generic_expr (stream, element->expr.ops.ternary.opnd0, 0); + fputs (", ", stream); + print_generic_expr (stream, element->expr.ops.ternary.opnd1, 0); + fputs (", ", stream); + print_generic_expr (stream, element->expr.ops.ternary.opnd2, 0); + fputs (">", stream); + break; + case EXPR_CALL: { size_t i; @@ -1585,7 +1635,7 @@ record_edge_info (basic_block bb) edge_info = allocate_edge_info (false_edge); record_conditions (edge_info, inverted, cond); - if (code == NE_EXPR) + if (TREE_CODE (inverted) == EQ_EXPR) { edge_info->lhs = op1; edge_info->rhs = op0; @@ -1612,7 +1662,7 @@ record_edge_info (basic_block bb) edge_info = allocate_edge_info (false_edge); record_conditions (edge_info, inverted, cond); - if (TREE_CODE (cond) == NE_EXPR) + if (TREE_CODE (inverted) == EQ_EXPR) { edge_info->lhs = op0; edge_info->rhs = op1; |