diff options
author | matz <matz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-04-13 12:39:53 +0000 |
---|---|---|
committer | matz <matz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-04-13 12:39:53 +0000 |
commit | c07e5b8b23ee24d8beedae3817de0543490f40e5 (patch) | |
tree | 05699a395708e0a401d3e3d5b87f880893f20ac8 | |
parent | e212f99af8c85906522c1fe1140a7a1a4bc06d19 (diff) | |
download | gcc-c07e5b8b23ee24d8beedae3817de0543490f40e5.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158265 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/negate.c | 20 | ||||
-rw-r--r-- | gcc/tree-ssa-reassoc.c | 106 |
4 files changed, 102 insertions, 35 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6ba3eca7a99..dfeebd89739 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d6787752043..2c370c07143 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +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 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/negate.c b/gcc/testsuite/gcc.dg/tree-ssa/negate.c new file mode 100644 index 00000000000..c51f323e710 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/negate.c @@ -0,0 +1,20 @@ +/* { 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" } } */ diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index cf05de5be71..9a623bb3d59 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -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)) |