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:
parent
3e97fe67e3
commit
fd660b1bee
8 changed files with 92 additions and 7 deletions
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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..
|
||||
|
|
|
@ -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"} } */
|
||||
|
|
|
@ -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"} } */
|
||||
|
|
26
gcc/testsuite/gcc.dg/tree-ssa/20040615-1.c
Normal file
26
gcc/testsuite/gcc.dg/tree-ssa/20040615-1.c
Normal 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" } } */
|
||||
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue