Commit 143597ff by Michael Matz Committed by Michael Matz

tree-ssa-reassoc.c (repropagate_negates): Merge negates also into MINUS_EXPRs.

	* tree-ssa-reassoc.c (repropagate_negates): Merge negates also
	into MINUS_EXPRs.
	(can_reassociate_p): New function.
	(break_up_subtract_bb, reassociate_bb): Use it.

testsuite/
	* gcc.dg/tree-ssa/negate.c: New testcase.

From-SVN: r158265
parent 54c5ec4f
2010-04-13 Michael Matz <matz@suse.de>
* tree-ssa-reassoc.c (repropagate_negates): Merge negates also
into MINUS_EXPRs.
(can_reassociate_p): New function.
(break_up_subtract_bb, reassociate_bb): Use it.
2010-04-13 Richard Guenther <rguenther@suse.de>
PR bootstrap/43737
......
2010-04-13 Michael Matz <matz@suse.de>
* gcc.dg/tree-ssa/negate.c: New testcase.
2010-04-13 Richard Guenther <rguenther@suse.de>
PR testsuite/43735
......
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-reassoc1" } */
int f (int a, int b)
{
int x = -a;
int y = b - x;
return y;
}
int g (int a, int b)
{
int x = -a;
int y = x - b;
return y;
}
/* There should be two additions now. */
/* { dg-final { scan-tree-dump-times "\\+" 2 "reassoc1"} } */
/* { dg-final { cleanup-tree-dump "reassoc1" } } */
......@@ -1707,14 +1707,15 @@ repropagate_negates (void)
{
gimple user = get_single_immediate_use (negate);
if (!user || !is_gimple_assign (user))
continue;
/* The negate operand can be either operand of a PLUS_EXPR
(it can be the LHS if the RHS is a constant for example).
Force the negate operand to the RHS of the PLUS_EXPR, then
transform the PLUS_EXPR into a MINUS_EXPR. */
if (user
&& is_gimple_assign (user)
&& gimple_assign_rhs_code (user) == PLUS_EXPR)
if (gimple_assign_rhs_code (user) == PLUS_EXPR)
{
/* If the negated operand appears on the LHS of the
PLUS_EXPR, exchange the operands of the PLUS_EXPR
......@@ -1737,9 +1738,63 @@ repropagate_negates (void)
update_stmt (user);
}
}
else if (gimple_assign_rhs_code (user) == MINUS_EXPR)
{
if (gimple_assign_rhs1 (user) == negate)
{
/* We have
x = -a
y = x - b
which we transform into
x = a + b
y = -x .
This pushes down the negate which we possibly can merge
into some other operation, hence insert it into the
plus_negates vector. */
gimple feed = SSA_NAME_DEF_STMT (negate);
tree a = gimple_assign_rhs1 (feed);
tree rhs2 = gimple_assign_rhs2 (user);
gimple_stmt_iterator gsi = gsi_for_stmt (feed), gsi2;
gimple_replace_lhs (feed, negate);
gimple_assign_set_rhs_with_ops (&gsi, PLUS_EXPR, a, rhs2);
update_stmt (gsi_stmt (gsi));
gsi2 = gsi_for_stmt (user);
gimple_assign_set_rhs_with_ops (&gsi2, NEGATE_EXPR, negate, NULL);
update_stmt (gsi_stmt (gsi2));
gsi_move_before (&gsi, &gsi2);
VEC_safe_push (tree, heap, plus_negates,
gimple_assign_lhs (gsi_stmt (gsi2)));
}
else
{
/* Transform "x = -a; y = b - x" into "y = b + a", getting
rid of one operation. */
gimple feed = SSA_NAME_DEF_STMT (negate);
tree a = gimple_assign_rhs1 (feed);
tree rhs1 = gimple_assign_rhs1 (user);
gimple_stmt_iterator gsi = gsi_for_stmt (user);
gimple_assign_set_rhs_with_ops (&gsi, PLUS_EXPR, rhs1, a);
update_stmt (gsi_stmt (gsi));
}
}
}
}
/* Returns true if OP is of a type for which we can do reassociation.
That is for integral or non-saturating fixed-point types, and for
floating point type when associative-math is enabled. */
static bool
can_reassociate_p (tree op)
{
tree type = TREE_TYPE (op);
if (INTEGRAL_TYPE_P (type)
|| NON_SAT_FIXED_POINT_TYPE_P (type)
|| (flag_associative_math && SCALAR_FLOAT_TYPE_P (type)))
return true;
return false;
}
/* Break up subtract operations in block BB.
We do this top down because we don't know whether the subtract is
......@@ -1768,27 +1823,15 @@ break_up_subtract_bb (basic_block bb)
gimple stmt = gsi_stmt (gsi);
gimple_set_visited (stmt, false);
if (!is_gimple_assign (stmt)
|| !can_reassociate_p (gimple_assign_lhs (stmt)))
continue;
/* Look for simple gimple subtract operations. */
if (is_gimple_assign (stmt)
&& gimple_assign_rhs_code (stmt) == MINUS_EXPR)
if (gimple_assign_rhs_code (stmt) == MINUS_EXPR)
{
tree lhs = gimple_assign_lhs (stmt);
tree rhs1 = gimple_assign_rhs1 (stmt);
tree rhs2 = gimple_assign_rhs2 (stmt);
/* If associative-math we can do reassociation for
non-integral types. Or, we can do reassociation for
non-saturating fixed-point types. */
if ((!INTEGRAL_TYPE_P (TREE_TYPE (lhs))
|| !INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
|| !INTEGRAL_TYPE_P (TREE_TYPE (rhs2)))
&& (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs))
|| !SCALAR_FLOAT_TYPE_P (TREE_TYPE(rhs1))
|| !SCALAR_FLOAT_TYPE_P (TREE_TYPE(rhs2))
|| !flag_associative_math)
&& (!NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE (lhs))
|| !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(rhs1))
|| !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(rhs2))))
if (!can_reassociate_p (gimple_assign_rhs1 (stmt))
|| !can_reassociate_p (gimple_assign_rhs2 (stmt)))
continue;
/* Check for a subtract used only in an addition. If this
......@@ -1798,6 +1841,9 @@ break_up_subtract_bb (basic_block bb)
if (should_break_up_subtract (stmt))
break_up_subtract (stmt, &gsi);
}
else if (gimple_assign_rhs_code (stmt) == NEGATE_EXPR
&& can_reassociate_p (gimple_assign_rhs1 (stmt)))
VEC_safe_push (tree, heap, plus_negates, gimple_assign_lhs (stmt));
}
for (son = first_dom_son (CDI_DOMINATORS, bb);
son;
......@@ -1858,19 +1904,9 @@ reassociate_bb (basic_block bb)
rhs1 = gimple_assign_rhs1 (stmt);
rhs2 = gimple_assign_rhs2 (stmt);
/* If associative-math we can do reassociation for
non-integral types. Or, we can do reassociation for
non-saturating fixed-point types. */
if ((!INTEGRAL_TYPE_P (TREE_TYPE (lhs))
|| !INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
|| !INTEGRAL_TYPE_P (TREE_TYPE (rhs2)))
&& (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs))
|| !SCALAR_FLOAT_TYPE_P (TREE_TYPE(rhs1))
|| !SCALAR_FLOAT_TYPE_P (TREE_TYPE(rhs2))
|| !flag_associative_math)
&& (!NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE (lhs))
|| !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(rhs1))
|| !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(rhs2))))
if (!can_reassociate_p (lhs)
|| !can_reassociate_p (rhs1)
|| !can_reassociate_p (rhs2))
continue;
if (associative_tree_code (rhs_code))
......
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