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:
Richard Biener 2014-11-13 08:53:23 +00:00 committed by Richard Biener
parent 83633539b7
commit 96994de045
4 changed files with 60 additions and 103 deletions

View file

@ -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

View file

@ -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,

View file

@ -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))

View file

@ -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);