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
This commit is contained in:
Jeff Law 2004-06-15 23:09:41 -06:00 committed by Jeff Law
parent 3e97fe67e3
commit fd660b1bee
8 changed files with 92 additions and 7 deletions

View file

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

View file

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

View file

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

View file

@ -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"} } */

View file

@ -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"} } */

View file

@ -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" } } */

View file

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

View file

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