Commit 96994de0 by Richard Biener Committed by Richard Biener

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
parent 83633539
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> 2014-12-13 Richard Biener <rguenther@suse.de>
PR middle-end/61559 PR middle-end/61559
...@@ -121,7 +121,6 @@ static enum tree_code compcode_to_comparison (enum comparison_code); ...@@ -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 operand_equal_for_comparison_p (tree, tree, tree);
static int twoval_comparison_p (tree, tree *, tree *, int *); static int twoval_comparison_p (tree, tree *, tree *, int *);
static tree eval_subst (location_t, tree, tree, tree, tree, tree); 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 distribute_bit_expr (location_t, enum tree_code, tree, tree, tree);
static tree make_bit_field_ref (location_t, tree, tree, static tree make_bit_field_ref (location_t, tree, tree,
HOST_WIDE_INT, HOST_WIDE_INT, int); HOST_WIDE_INT, HOST_WIDE_INT, int);
...@@ -3074,27 +3073,6 @@ omit_one_operand_loc (location_t loc, tree type, tree result, tree omitted) ...@@ -3074,27 +3073,6 @@ omit_one_operand_loc (location_t loc, tree type, tree result, tree omitted)
return non_lvalue_loc (loc, t); 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 /* Return a tree for the case when the result of an expression is RESULT
converted to TYPE and OMITTED1 and OMITTED2 were previously operands converted to TYPE and OMITTED1 and OMITTED2 were previously operands
of the expression but are now not needed. of the expression but are now not needed.
...@@ -13553,11 +13531,6 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, ...@@ -13553,11 +13531,6 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
} }
else if (TREE_CODE (arg0) == VECTOR_CST) 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 if ((TREE_CODE (arg1) == VECTOR_CST
|| TREE_CODE (arg1) == CONSTRUCTOR) || TREE_CODE (arg1) == CONSTRUCTOR)
&& (TREE_CODE (arg2) == VECTOR_CST && (TREE_CODE (arg2) == VECTOR_CST
...@@ -13582,9 +13555,6 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, ...@@ -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 /* 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 simpler expression, depending on the operation and the values
of B and C. Signed zeros prevent all of these transformations, of B and C. Signed zeros prevent all of these transformations,
......
...@@ -590,3 +590,51 @@ along with GCC; see the file COPYING3. If not see ...@@ -590,3 +590,51 @@ along with GCC; see the file COPYING3. If not see
(simplify (simplify
(bswap (bitop:c (bswap @0) @1)) (bswap (bitop:c (bswap @0) @1))
(bitop @0 (bswap @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) ...@@ -617,7 +617,6 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
tree tmp = NULL_TREE; tree tmp = NULL_TREE;
tree cond = gimple_assign_rhs1 (stmt); tree cond = gimple_assign_rhs1 (stmt);
enum tree_code code = gimple_assign_rhs_code (stmt); enum tree_code code = gimple_assign_rhs_code (stmt);
bool swap = false;
/* We can do tree combining on SSA_NAME and comparison expressions. */ /* We can do tree combining on SSA_NAME and comparison expressions. */
if (COMPARISON_CLASS_P (cond)) if (COMPARISON_CLASS_P (cond))
...@@ -640,15 +639,6 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p) ...@@ -640,15 +639,6 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
TREE_TYPE (cond), TREE_TYPE (cond),
gimple_assign_rhs1 (def_stmt), gimple_assign_rhs1 (def_stmt),
gimple_assign_rhs2 (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 if (tmp
...@@ -669,15 +659,7 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p) ...@@ -669,15 +659,7 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
else if (integer_zerop (tmp)) else if (integer_zerop (tmp))
gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs3 (stmt)); gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs3 (stmt));
else else
{ gimple_assign_set_rhs1 (stmt, unshare_expr (tmp));
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);
}
}
stmt = gsi_stmt (*gsi_p); stmt = gsi_stmt (*gsi_p);
update_stmt (stmt); update_stmt (stmt);
...@@ -687,58 +669,6 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p) ...@@ -687,58 +669,6 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
return 0; 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 /* We've just substituted an ADDR_EXPR into stmt. Update all the
relevant data structures to match. */ relevant data structures to match. */
...@@ -2432,8 +2362,7 @@ pass_forwprop::execute (function *fun) ...@@ -2432,8 +2362,7 @@ pass_forwprop::execute (function *fun)
|| code == VEC_COND_EXPR) || code == VEC_COND_EXPR)
{ {
/* In this case the entire COND_EXPR is in rhs1. */ /* In this case the entire COND_EXPR is in rhs1. */
if (forward_propagate_into_cond (&gsi) if (forward_propagate_into_cond (&gsi))
|| combine_cond_exprs (&gsi))
{ {
changed = true; changed = true;
stmt = gsi_stmt (gsi); stmt = gsi_stmt (gsi);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment