match.pd: Implement conditional expression patterns.
2014-11-13 Richard Biener <rguenther@suse.de> * match.pd: Implement conditional expression patterns. * tree-ssa-forwprop.c (forward_propagate_into_cond): Remove them here. (combine_cond_exprs): Remove. (pass_forwprop::execute): Do not call combine_cond_exprs. * fold-const.c (fold_ternary_loc): Remove patterns here. (pedantic_omit_one_operand_loc): Remove. From-SVN: r217465
This commit is contained in:
parent
83633539b7
commit
96994de045
4 changed files with 60 additions and 103 deletions
|
@ -1,3 +1,13 @@
|
|||
2014-11-13 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* match.pd: Implement conditional expression patterns.
|
||||
* tree-ssa-forwprop.c (forward_propagate_into_cond): Remove
|
||||
them here.
|
||||
(combine_cond_exprs): Remove.
|
||||
(pass_forwprop::execute): Do not call combine_cond_exprs.
|
||||
* fold-const.c (fold_ternary_loc): Remove patterns here.
|
||||
(pedantic_omit_one_operand_loc): Remove.
|
||||
|
||||
2014-12-13 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR middle-end/61559
|
||||
|
|
|
@ -121,7 +121,6 @@ static enum tree_code compcode_to_comparison (enum comparison_code);
|
|||
static int operand_equal_for_comparison_p (tree, tree, tree);
|
||||
static int twoval_comparison_p (tree, tree *, tree *, int *);
|
||||
static tree eval_subst (location_t, tree, tree, tree, tree, tree);
|
||||
static tree pedantic_omit_one_operand_loc (location_t, tree, tree, tree);
|
||||
static tree distribute_bit_expr (location_t, enum tree_code, tree, tree, tree);
|
||||
static tree make_bit_field_ref (location_t, tree, tree,
|
||||
HOST_WIDE_INT, HOST_WIDE_INT, int);
|
||||
|
@ -3074,27 +3073,6 @@ omit_one_operand_loc (location_t loc, tree type, tree result, tree omitted)
|
|||
return non_lvalue_loc (loc, t);
|
||||
}
|
||||
|
||||
/* Similar, but call pedantic_non_lvalue instead of non_lvalue. */
|
||||
|
||||
static tree
|
||||
pedantic_omit_one_operand_loc (location_t loc, tree type, tree result,
|
||||
tree omitted)
|
||||
{
|
||||
tree t = fold_convert_loc (loc, type, result);
|
||||
|
||||
/* If the resulting operand is an empty statement, just return the omitted
|
||||
statement casted to void. */
|
||||
if (IS_EMPTY_STMT (t) && TREE_SIDE_EFFECTS (omitted))
|
||||
return build1_loc (loc, NOP_EXPR, void_type_node,
|
||||
fold_ignored_result (omitted));
|
||||
|
||||
if (TREE_SIDE_EFFECTS (omitted))
|
||||
return build2_loc (loc, COMPOUND_EXPR, type,
|
||||
fold_ignored_result (omitted), t);
|
||||
|
||||
return pedantic_non_lvalue_loc (loc, t);
|
||||
}
|
||||
|
||||
/* Return a tree for the case when the result of an expression is RESULT
|
||||
converted to TYPE and OMITTED1 and OMITTED2 were previously operands
|
||||
of the expression but are now not needed.
|
||||
|
@ -13553,11 +13531,6 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
|
|||
}
|
||||
else if (TREE_CODE (arg0) == VECTOR_CST)
|
||||
{
|
||||
if (integer_all_onesp (arg0))
|
||||
return pedantic_omit_one_operand_loc (loc, type, arg1, arg2);
|
||||
if (integer_zerop (arg0))
|
||||
return pedantic_omit_one_operand_loc (loc, type, arg2, arg1);
|
||||
|
||||
if ((TREE_CODE (arg1) == VECTOR_CST
|
||||
|| TREE_CODE (arg1) == CONSTRUCTOR)
|
||||
&& (TREE_CODE (arg2) == VECTOR_CST
|
||||
|
@ -13582,9 +13555,6 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
|
|||
}
|
||||
}
|
||||
|
||||
if (operand_equal_p (arg1, op2, 0))
|
||||
return pedantic_omit_one_operand_loc (loc, type, arg1, arg0);
|
||||
|
||||
/* If we have A op B ? A : C, we may be able to convert this to a
|
||||
simpler expression, depending on the operation and the values
|
||||
of B and C. Signed zeros prevent all of these transformations,
|
||||
|
|
48
gcc/match.pd
48
gcc/match.pd
|
@ -590,3 +590,51 @@ along with GCC; see the file COPYING3. If not see
|
|||
(simplify
|
||||
(bswap (bitop:c (bswap @0) @1))
|
||||
(bitop @0 (bswap @1)))))
|
||||
|
||||
|
||||
/* Combine COND_EXPRs and VEC_COND_EXPRs. */
|
||||
|
||||
/* Simplify constant conditions.
|
||||
Only optimize constant conditions when the selected branch
|
||||
has the same type as the COND_EXPR. This avoids optimizing
|
||||
away "c ? x : throw", where the throw has a void type.
|
||||
Note that we cannot throw away the fold-const.c variant nor
|
||||
this one as we depend on doing this transform before possibly
|
||||
A ? B : B -> B triggers and the fold-const.c one can optimize
|
||||
0 ? A : B to B even if A has side-effects. Something
|
||||
genmatch cannot handle. */
|
||||
(simplify
|
||||
(cond INTEGER_CST@0 @1 @2)
|
||||
(if (integer_zerop (@0)
|
||||
&& (!VOID_TYPE_P (TREE_TYPE (@2))
|
||||
|| VOID_TYPE_P (type)))
|
||||
@2)
|
||||
(if (!integer_zerop (@0)
|
||||
&& (!VOID_TYPE_P (TREE_TYPE (@1))
|
||||
|| VOID_TYPE_P (type)))
|
||||
@1))
|
||||
(simplify
|
||||
(vec_cond VECTOR_CST@0 @1 @2)
|
||||
(if (integer_all_onesp (@0))
|
||||
@1)
|
||||
(if (integer_zerop (@0))
|
||||
@2))
|
||||
|
||||
(for cnd (cond vec_cond)
|
||||
/* A ? B : (A ? X : C) -> A ? B : C. */
|
||||
(simplify
|
||||
(cnd @0 (cnd @0 @1 @2) @3)
|
||||
(cnd @0 @1 @3))
|
||||
(simplify
|
||||
(cnd @0 @1 (cnd @0 @2 @3))
|
||||
(cnd @0 @1 @3))
|
||||
|
||||
/* A ? B : B -> B. */
|
||||
(simplify
|
||||
(cnd @0 @1 @1)
|
||||
@1))
|
||||
|
||||
/* !A ? B : C -> A ? C : B. */
|
||||
(simplify
|
||||
(cond (logical_inverted_value truth_valued_p@0) @1 @2)
|
||||
(cond @0 @2 @1))
|
||||
|
|
|
@ -617,7 +617,6 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
|
|||
tree tmp = NULL_TREE;
|
||||
tree cond = gimple_assign_rhs1 (stmt);
|
||||
enum tree_code code = gimple_assign_rhs_code (stmt);
|
||||
bool swap = false;
|
||||
|
||||
/* We can do tree combining on SSA_NAME and comparison expressions. */
|
||||
if (COMPARISON_CLASS_P (cond))
|
||||
|
@ -640,15 +639,6 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
|
|||
TREE_TYPE (cond),
|
||||
gimple_assign_rhs1 (def_stmt),
|
||||
gimple_assign_rhs2 (def_stmt));
|
||||
else if (code == COND_EXPR
|
||||
&& ((def_code == BIT_NOT_EXPR
|
||||
&& TYPE_PRECISION (TREE_TYPE (cond)) == 1)
|
||||
|| (def_code == BIT_XOR_EXPR
|
||||
&& integer_onep (gimple_assign_rhs2 (def_stmt)))))
|
||||
{
|
||||
tmp = gimple_assign_rhs1 (def_stmt);
|
||||
swap = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp
|
||||
|
@ -669,15 +659,7 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
|
|||
else if (integer_zerop (tmp))
|
||||
gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs3 (stmt));
|
||||
else
|
||||
{
|
||||
gimple_assign_set_rhs1 (stmt, unshare_expr (tmp));
|
||||
if (swap)
|
||||
{
|
||||
tree t = gimple_assign_rhs2 (stmt);
|
||||
gimple_assign_set_rhs2 (stmt, gimple_assign_rhs3 (stmt));
|
||||
gimple_assign_set_rhs3 (stmt, t);
|
||||
}
|
||||
}
|
||||
gimple_assign_set_rhs1 (stmt, unshare_expr (tmp));
|
||||
stmt = gsi_stmt (*gsi_p);
|
||||
update_stmt (stmt);
|
||||
|
||||
|
@ -687,58 +669,6 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Propagate from the ssa name definition statements of COND_EXPR
|
||||
values in the rhs of statement STMT into the conditional arms
|
||||
if that simplifies it.
|
||||
Returns true if the stmt was changed. */
|
||||
|
||||
static bool
|
||||
combine_cond_exprs (gimple_stmt_iterator *gsi_p)
|
||||
{
|
||||
gimple stmt = gsi_stmt (*gsi_p);
|
||||
tree cond, val1, val2;
|
||||
bool changed = false;
|
||||
|
||||
cond = gimple_assign_rhs1 (stmt);
|
||||
val1 = gimple_assign_rhs2 (stmt);
|
||||
if (TREE_CODE (val1) == SSA_NAME)
|
||||
{
|
||||
gimple def_stmt = SSA_NAME_DEF_STMT (val1);
|
||||
if (is_gimple_assign (def_stmt)
|
||||
&& gimple_assign_rhs_code (def_stmt) == gimple_assign_rhs_code (stmt)
|
||||
&& operand_equal_p (gimple_assign_rhs1 (def_stmt), cond, 0))
|
||||
{
|
||||
val1 = unshare_expr (gimple_assign_rhs2 (def_stmt));
|
||||
gimple_assign_set_rhs2 (stmt, val1);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
val2 = gimple_assign_rhs3 (stmt);
|
||||
if (TREE_CODE (val2) == SSA_NAME)
|
||||
{
|
||||
gimple def_stmt = SSA_NAME_DEF_STMT (val2);
|
||||
if (is_gimple_assign (def_stmt)
|
||||
&& gimple_assign_rhs_code (def_stmt) == gimple_assign_rhs_code (stmt)
|
||||
&& operand_equal_p (gimple_assign_rhs1 (def_stmt), cond, 0))
|
||||
{
|
||||
val2 = unshare_expr (gimple_assign_rhs3 (def_stmt));
|
||||
gimple_assign_set_rhs3 (stmt, val2);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (operand_equal_p (val1, val2, 0))
|
||||
{
|
||||
gimple_assign_set_rhs_from_tree (gsi_p, val1);
|
||||
stmt = gsi_stmt (*gsi_p);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
update_stmt (stmt);
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
/* We've just substituted an ADDR_EXPR into stmt. Update all the
|
||||
relevant data structures to match. */
|
||||
|
||||
|
@ -2432,8 +2362,7 @@ pass_forwprop::execute (function *fun)
|
|||
|| code == VEC_COND_EXPR)
|
||||
{
|
||||
/* In this case the entire COND_EXPR is in rhs1. */
|
||||
if (forward_propagate_into_cond (&gsi)
|
||||
|| combine_cond_exprs (&gsi))
|
||||
if (forward_propagate_into_cond (&gsi))
|
||||
{
|
||||
changed = true;
|
||||
stmt = gsi_stmt (gsi);
|
||||
|
|
Loading…
Add table
Reference in a new issue