aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2004-06-15 23:09:41 -0600
committerJeff Law <law@gcc.gnu.org>2004-06-15 23:09:41 -0600
commitfd660b1bee7af09cd69d1125cf35e6aa5826234c (patch)
tree2d5c137139fce6357a14c09e7a739e3529131431
parent3e97fe67e31070b78a333dba397ab4ddde2e7311 (diff)
downloadgcc-fd660b1bee7af09cd69d1125cf35e6aa5826234c.zip
gcc-fd660b1bee7af09cd69d1125cf35e6aa5826234c.tar.gz
gcc-fd660b1bee7af09cd69d1125cf35e6aa5826234c.tar.bz2
fold-const.c (swap_tree_comparison): No longer static.
* fold-const.c (swap_tree_comparison): No longer static. (tree_swap_operands_p): Similarly. Return true if both operands are SSA_NAMEs and the first operand has a higher version number than the second operand. * tree.h (swap_tree_comparison): Prototype. (tree_swap_operands_p): Prototype. * tree-ssa-operands.c (get_expr_operands): For commutative operators and relational comparisons, canonicalize the order of the operands. * gcc.dg/tree-ssa/20040615-1.c: New test. * gcc.dg/tree-ssa/20030824-1.c: Update expected output to be less sensitive to operand ordering. * gcc.dg/tree-ssa/20030824-2.c: Likewise. From-SVN: r83224
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/fold-const.c16
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030824-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030824-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040615-1.c26
-rw-r--r--gcc/tree-ssa-operands.c31
-rw-r--r--gcc/tree.h3
8 files changed, 92 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cdea3c0..027ff23 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2004-06-15 Jeff Law <law@redhat.com>
+
+ * fold-const.c (swap_tree_comparison): No longer static.
+ (tree_swap_operands_p): Similarly. Return true if both operands
+ are SSA_NAMEs and the first operand has a higher version number than
+ the second operand.
+ * tree.h (swap_tree_comparison): Prototype.
+ (tree_swap_operands_p): Prototype.
+ * tree-ssa-operands.c (get_expr_operands): For commutative
+ operators and relational comparisons, canonicalize the
+ order of the operands.
+
2004-06-15 Richard Henderson <rth@redhat.com>
* c-common.c (lang_gimplify_stmt): Remove next_p argument.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 72974d6..91f4054 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -92,7 +92,6 @@ static hashval_t size_htab_hash (const void *);
static int size_htab_eq (const void *, const void *);
static tree fold_convert_const (enum tree_code, tree, tree);
static enum tree_code invert_tree_comparison (enum tree_code, bool);
-static enum tree_code swap_tree_comparison (enum tree_code);
static enum comparison_code comparison_to_compcode (enum tree_code);
static enum tree_code compcode_to_comparison (enum comparison_code);
static tree combine_comparisons (enum tree_code, enum tree_code,
@@ -132,8 +131,6 @@ static tree fold_mathfn_compare (enum built_in_function, enum tree_code,
static tree fold_inf_compare (enum tree_code, tree, tree, tree);
static tree fold_div_compare (enum tree_code, tree, tree, tree);
static bool reorder_operands_p (tree, tree);
-static bool tree_swap_operands_p (tree, tree, bool);
-
static tree fold_negate_const (tree, tree);
static tree fold_not_const (tree, tree);
static tree fold_relational_const (enum tree_code, tree, tree, tree);
@@ -2119,7 +2116,7 @@ invert_tree_comparison (enum tree_code code, bool honor_nans)
/* Similar, but return the comparison that results if the operands are
swapped. This is safe for floating-point. */
-static enum tree_code
+enum tree_code
swap_tree_comparison (enum tree_code code)
{
switch (code)
@@ -5527,7 +5524,7 @@ reorder_operands_p (tree arg0, tree arg1)
isn't. If REORDER is true, only recommend swapping if we can
evaluate the operands in reverse order. */
-static bool
+bool
tree_swap_operands_p (tree arg0, tree arg1, bool reorder)
{
STRIP_SIGN_NOPS (arg0);
@@ -5574,6 +5571,15 @@ tree_swap_operands_p (tree arg0, tree arg1, bool reorder)
if (DECL_P (arg0))
return 1;
+ /* It is preferable to swap two SSA_NAME to ensure a canonical form
+ for commutative and comparison operators. Ensuring a canonical
+ form allows the optimizers to find additional redundancies without
+ having to explicitly check for both orderings. */
+ if (TREE_CODE (arg0) == SSA_NAME
+ && TREE_CODE (arg1) == SSA_NAME
+ && SSA_NAME_VERSION (arg0) > SSA_NAME_VERSION (arg1))
+ return 1;
+
return 0;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 50ac366..7cb9953 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2004-06-15 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/20040615-1.c: New test.
+ * gcc.dg/tree-ssa/20030824-1.c: Update expected output to
+ be less sensitive to operand ordering.
+ * gcc.dg/tree-ssa/20030824-2.c: Likewise.
+
2004-06-16 Danny Smith <dannysmith@users.sourceforge.net>
* g++.dg/abi/bitfield3.C: Add comment..
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030824-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030824-1.c
index 328d33d..5490537 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/20030824-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030824-1.c
@@ -19,4 +19,4 @@ int foo (int x, int y)
}
/* The addition should be optimized into 'y+x'. */
-/* { dg-final { scan-tree-dump-times "y \\+ x" 1 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "\[xy\] \\+ \[xy]" 1 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030824-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030824-2.c
index 5ed66d0..6e59dd8 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/20030824-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030824-2.c
@@ -19,4 +19,4 @@ int foo (int x, int y)
}
/* This function should be optimized into 'return y+x'. */
-/* { dg-final { scan-tree-dump-times "return y \\+ x" 1 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "return \[xy\] \\+ \[xy\]" 1 "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040615-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040615-1.c
new file mode 100644
index 0000000..40d6676
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040615-1.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-dom1 -fdump-tree-dom2" } */
+
+void bar1 (void);
+void bar2 (void);
+
+void
+foo (unsigned int a, unsigned int b)
+{
+ if (a >= b)
+ bar1 ();
+ else if (b <= a)
+ bar2 ();
+}
+
+
+/* We do not canonicalize the second conditional immediately after going
+ into SSA form, thus the first dominator pass is unable to remove
+ the useless conditional. Thus the xfailed test.
+
+ However, the second conditional is canonicalized before the second
+ dominator optimizer pass and we do want to verify the call to
+ bar2 was eliminated. */
+/* { dg-final { scan-tree-dump-times "bar2" 0 "dom1" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "bar2" 0 "dom2" } } */
+
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index 02380b6..f1edfa18 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -1235,6 +1235,37 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops)
|| code == TRUTH_XOR_EXPR
|| code == COMPOUND_EXPR)
{
+ tree op0 = TREE_OPERAND (expr, 0);
+ tree op1 = TREE_OPERAND (expr, 1);
+
+ /* If it would be profitable to swap the operands, then do so to
+ canonicalize the statement, enabling better optimization.
+
+ By placing canonicalization of such expressions here we
+ transparently keep statements in canonical form, even
+ when the statement is modified. */
+ if (tree_swap_operands_p (op0, op1, false))
+ {
+ /* For relationals we need to swap the operands and change
+ the code. */
+ if (code == LT_EXPR
+ || code == GT_EXPR
+ || code == LE_EXPR
+ || code == GE_EXPR)
+ {
+ TREE_SET_CODE (expr, swap_tree_comparison (code));
+ TREE_OPERAND (expr, 0) = op1;
+ TREE_OPERAND (expr, 1) = op0;
+ }
+
+ /* For a commutative operator we can just swap the operands. */
+ if (commutative_tree_code (code))
+ {
+ TREE_OPERAND (expr, 0) = op1;
+ TREE_OPERAND (expr, 1) = op0;
+ }
+ }
+
get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags, prev_vops);
get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags, prev_vops);
return;
diff --git a/gcc/tree.h b/gcc/tree.h
index 6180895..a1db1f0 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -3332,6 +3332,9 @@ extern tree build_fold_addr_expr (tree);
extern tree build_fold_addr_expr_with_type (tree, tree);
extern tree build_fold_indirect_ref (tree);
+extern bool tree_swap_operands_p (tree, tree, bool);
+extern enum tree_code swap_tree_comparison (enum tree_code);
+
/* In builtins.c */
extern tree fold_builtin (tree);
extern enum built_in_function builtin_mathfn_code (tree);