Commit 0e0ed594 by Jeff Law

tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Remove reassociation code.


	* tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Remove
	reassociation code.
	* passes.c (init_optimization_passes): Run reassociation again
	after loop optimizations.

	* tree-ssa-dom.c (thread_across_edge): Canonicalize condition
	if necessary.
	(optimize_stmt): Ditto.
	(canonicalize_comparison): New function.
	* tree-ssa-operands.c (swap_tree_operands): Make external.
	(get_expr_operands): Stop auto-canonicalization.
	* tree-ssa-reassoc.c: Rewrite.
	(init_optimization_passes): 
	* tree-flow.h (swap_tree_operands): Prototype.
	* Makefile.in (tree-ssa-reassoc.o): Update dependencies.

	* gcc.dg/tree-ssa/ssa-pre-2.c: Update due to reassociation changes.
	* gcc.dg/tree-ssa/reassoc-1.c: Likewise.
	* gcc.dg/tree-ssa/reassoc-2.c: Likewise.
	* gcc.dg/tree-ssa/reassoc-3.c: Likewise.
	* gcc.dg/tree-ssa/reassoc-4.c: Likewise.
	* gcc.dg/tree-ssa/reassoc-5.c: New.
	* gcc.dg/tree-ssa/reassoc-6.c: New.
	* gcc.dg/tree-ssa/reassoc-7.c: New.
	* gcc.dg/tree-ssa/reassoc-8.c: New.
	* gcc.dg/tree-ssa/reassoc-9.c: New.
	* gcc.dg/tree-ssa/reassoc-10.c: New.
	* gcc.dg/tree-ssa/reassoc-11.c: New.

From-SVN: r108425
parent e525ba8e
2005-12-12 Jeff Law <law@redhat.com>
* tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Remove
reassociation code.
* passes.c (init_optimization_passes): Run reassociation again
after loop optimizations.
2005-12-12 Daniel Berlin <dberlin@dberlin.org>
* tree-ssa-dom.c (thread_across_edge): Canonicalize condition
if necessary.
(optimize_stmt): Ditto.
(canonicalize_comparison): New function.
* tree-ssa-operands.c (swap_tree_operands): Make external.
(get_expr_operands): Stop auto-canonicalization.
* tree-ssa-reassoc.c: Rewrite.
(init_optimization_passes):
* tree-flow.h (swap_tree_operands): Prototype.
* Makefile.in (tree-ssa-reassoc.o): Update dependencies.
2005-12-12 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> 2005-12-12 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* pa.c (pa_output_function_epilogue): Set cfun->machine->in_nsubspa to * pa.c (pa_output_function_epilogue): Set cfun->machine->in_nsubspa to
......
...@@ -1975,7 +1975,8 @@ tree-ssa-alias.o : tree-ssa-alias.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ ...@@ -1975,7 +1975,8 @@ tree-ssa-alias.o : tree-ssa-alias.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \ tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) errors.h $(TIMEVAR_H) \ $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) errors.h $(TIMEVAR_H) \
$(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) tree-iterator.h\ $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) tree-iterator.h\
$(BASIC_BLOCK_H) $(HASHTAB_H) $(TREE_GIMPLE_H) tree-inline.h $(BASIC_BLOCK_H) $(TREE_GIMPLE_H) tree-inline.h vec.h \
alloc-pool.h
tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h $(DIAGNOSTIC_H) \ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h $(DIAGNOSTIC_H) \
$(FLAGS_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) toplev.h \ $(FLAGS_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) toplev.h \
......
...@@ -538,6 +538,7 @@ init_optimization_passes (void) ...@@ -538,6 +538,7 @@ init_optimization_passes (void)
propagate away the degenerate PHI nodes. */ propagate away the degenerate PHI nodes. */
NEXT_PASS (pass_phi_only_copy_prop); NEXT_PASS (pass_phi_only_copy_prop);
NEXT_PASS (pass_reassoc);
NEXT_PASS (pass_dce); NEXT_PASS (pass_dce);
NEXT_PASS (pass_dse); NEXT_PASS (pass_dse);
NEXT_PASS (pass_may_alias); NEXT_PASS (pass_may_alias);
...@@ -553,10 +554,10 @@ init_optimization_passes (void) ...@@ -553,10 +554,10 @@ init_optimization_passes (void)
NEXT_PASS (pass_may_alias); NEXT_PASS (pass_may_alias);
NEXT_PASS (pass_cse_reciprocals); NEXT_PASS (pass_cse_reciprocals);
NEXT_PASS (pass_split_crit_edges); NEXT_PASS (pass_split_crit_edges);
NEXT_PASS (pass_reassoc);
NEXT_PASS (pass_pre); NEXT_PASS (pass_pre);
NEXT_PASS (pass_sink_code); NEXT_PASS (pass_sink_code);
NEXT_PASS (pass_tree_loop); NEXT_PASS (pass_tree_loop);
NEXT_PASS (pass_reassoc);
NEXT_PASS (pass_dominator); NEXT_PASS (pass_dominator);
/* The only copy propagation opportunities left after DOM /* The only copy propagation opportunities left after DOM
......
2005-12-12 Daniel Berlin <dberlin@dberlin.org>
* gcc.dg/tree-ssa/ssa-pre-2.c: Update due to reassociation changes.
* gcc.dg/tree-ssa/reassoc-1.c: Likewise.
* gcc.dg/tree-ssa/reassoc-2.c: Likewise.
* gcc.dg/tree-ssa/reassoc-3.c: Likewise.
* gcc.dg/tree-ssa/reassoc-4.c: Likewise.
* gcc.dg/tree-ssa/reassoc-5.c: New.
* gcc.dg/tree-ssa/reassoc-6.c: New.
* gcc.dg/tree-ssa/reassoc-7.c: New.
* gcc.dg/tree-ssa/reassoc-8.c: New.
* gcc.dg/tree-ssa/reassoc-9.c: New.
* gcc.dg/tree-ssa/reassoc-10.c: New.
* gcc.dg/tree-ssa/reassoc-11.c: New.
2005-12-12 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> 2005-12-12 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR testsuite/25167 PR testsuite/25167
...@@ -14,5 +14,5 @@ int main(void) ...@@ -14,5 +14,5 @@ int main(void)
printf ("%d %d\n", e, f); printf ("%d %d\n", e, f);
} }
/* { dg-final { scan-tree-dump-times "a \\\+ b" 1 "optimized"} } */ /* { dg-final { scan-tree-dump-times "b \\\+ a" 1 "optimized"} } */
/* { dg-final { cleanup-tree-dump "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
int main(int a, int b, int c, int d)
{
/* Should become just a & b & c & d */
int e = (a & b) & (c & d);
int f = (c & a) & (b & d);
return e & f;
}
/* { dg-final { scan-tree-dump-times "\\\& " 3 "optimized"} } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-reassoc1" } */
int main(int a, int b, int c, int d)
{
/* All the xor's cancel each other out, leaving 0 */
int e = (a ^ b) ^ (c ^ d);
int f = (c ^ a) ^ (b ^ d);
return e ^ f;
}
/* { dg-final { scan-tree-dump-times "= 0" 1 "reassoc1"} } */
/* { dg-final { cleanup-tree-dump "reassoc1" } } */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized -fdump-tree-reassoc-details" } */ /* { dg-options "-O2 -fdump-tree-optimized" } */
extern int a0, a1, a2, a3, a4; int f (int a0,int a1,int a2,int a3,int a4)
int f ()
{ {
int b0, b1, b2, b3, b4; int b0, b1, b2, b3, b4,e;
/* this can be optimized to four additions... */ /* this can be optimized to four additions... */
b4 = a4 + a3 + a2 + a1 + a0; b4 = a4 + a3 + a2 + a1 + a0;
b3 = a3 + a2 + a1 + a0; b3 = a3 + a2 + a1 + a0;
b2 = a2 + a1 + a0; b2 = a2 + a1 + a0;
b1 = a1 + a0; b1 = a1 + a0;
/* This is actually 0 */ /* This is actually 0 */
return b4 - b3 + b2 - b1 - a4 - a2; e = b4 - b3 + b2 - b1 - a4 - a2;
} return e;
/* { dg-final { scan-tree-dump-times "Reassociating by rank" 3 "reassoc" } } */ }
/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" { xfail *-*-* } } } */
/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-final { cleanup-tree-dump "reassoc" } } */
/* { dg-do compile } */ int main(int a, int b, int c, int d)
/* { dg-options "-O2 -fdump-tree-optimized -ffast-math" } */
float a, b, c, d;
extern int printf (const char *, ...);
int main(void)
{ {
float e; int e = (a & ~b) & (~c & d);
float f; int f = (~c & a) & (b & ~d);
/* We should be able to transform these into the same expression, and only have two additions. */ return (e & f);
e = a + b;
e = e + c;
f = c + a;
f = f + b;
printf ("%f %f\n", e, f);
} }
/* { dg-final { scan-tree-dump-times "\\\+" 2 "optimized"} } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */ /* { dg-options "-O2 -fdump-tree-optimized -ffast-math" } */
float a, b, c, d; float a, b, c, d;
extern int printf (const char *, ...); extern int printf (const char *, ...);
int main(void) int main(void)
...@@ -14,5 +14,5 @@ int main(void) ...@@ -14,5 +14,5 @@ int main(void)
printf ("%f %f\n", e, f); printf ("%f %f\n", e, f);
} }
/* { dg-final { scan-tree-dump-times "\\\+" 4 "optimized"} } */ /* { dg-final { scan-tree-dump-times "\\\+" 2 "optimized"} } */
/* { dg-final { cleanup-tree-dump "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
extern int printf (const char *, ...);
int main(int argc, int b)
{
/* We should be able to get rid of the a - i. */
int i;
for (i = 0; i < 50; i++)
{
int a = b + i;
int c = a - i;
int d = argc + b;
printf ("%d %d\n", c,d);
}
}
/* { dg-final { scan-tree-dump-times "a - i" 0 "optimized"} } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-reassoc1" } */
int main(int a, int b, int c, int d)
{
/* Should be transformed into a + c + 8 */
int e = a + 3;
int f = c + 5;
int g = e + f;
return g;
}
/* { dg-final { scan-tree-dump-times "\\\+ 8" 1 "reassoc1"} } */
/* { dg-final { cleanup-tree-dump "reassoc1" } } */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-reassoc1" } */
int main(int a, int b, int c, int d, int e, int f, int g, int h)
{
/* Should be transformed into a + c + d + e + g + 15 */
int i = (a + 9) + (c + d);
int j = (e + 4) + (2 + g);
e = i + j;
return e;
}
/* { dg-final { scan-tree-dump-times "\\\+ 15" 1 "reassoc1"} } */
/* { dg-final { cleanup-tree-dump "reassoc1" } } */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-reassoc1" } */
int main(int a, int b, int c, int d, int e, int f, int g, int h)
{
/* e & ~e -> 0 */
int i = (a & 9) & (c & d);
int j = (~e & d) & (~c & e);
e = i & j;
return e;
}
/* { dg-final { scan-tree-dump-times "= 0" 1 "reassoc1"} } */
/* { dg-final { cleanup-tree-dump "reassoc1" } } */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-reassoc1" } */
int main(int a, int b, int c, int d, int e, int f, int g, int h)
{
/* Should be transformed into e = 20 */
int i = (a + 9) + (c + 8);
int j = (-c + 1) + (-a + 2);
e = i + j;
return e;
}
/* { dg-final { scan-tree-dump-times "= 20" 1 "reassoc1"} } */
/* { dg-final { cleanup-tree-dump "reassoc1" } } */
...@@ -16,6 +16,7 @@ int motion_test1(int data, int data_0, int data_3, int v) ...@@ -16,6 +16,7 @@ int motion_test1(int data, int data_0, int data_3, int v)
return v * t * u; return v * t * u;
} }
/* We should eliminate one computation of data_0 + data_3 along the /* We should eliminate one computation of data_0 + data_3 along the
main path, causing one reload. */ main path, and one computation of v * i along the main path, causing
/* { dg-final { scan-tree-dump-times "Eliminated: 1" 1 "pre"} } */ two eliminations. */
/* { dg-final { scan-tree-dump-times "Eliminated: 2" 1 "pre"} } */
/* { dg-final { cleanup-tree-dump "pre" } } */ /* { dg-final { cleanup-tree-dump "pre" } } */
...@@ -873,4 +873,6 @@ void delete_alias_heapvars (void); ...@@ -873,4 +873,6 @@ void delete_alias_heapvars (void);
#include "tree-flow-inline.h" #include "tree-flow-inline.h"
void swap_tree_operands (tree, tree *, tree *);
#endif /* _TREE_FLOW_H */ #endif /* _TREE_FLOW_H */
...@@ -588,6 +588,52 @@ struct tree_opt_pass pass_dominator = ...@@ -588,6 +588,52 @@ struct tree_opt_pass pass_dominator =
}; };
/* Given a stmt CONDSTMT containing a COND_EXPR, canonicalize the
COND_EXPR into a canonical form. */
static void
canonicalize_comparison (tree condstmt)
{
tree cond = COND_EXPR_COND (condstmt);
tree op0;
tree op1;
enum tree_code code = TREE_CODE (cond);
if (!COMPARISON_CLASS_P (cond))
return;
op0 = TREE_OPERAND (cond, 0);
op1 = TREE_OPERAND (cond, 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 (cond, swap_tree_comparison (code));
swap_tree_operands (condstmt,
&TREE_OPERAND (cond, 0),
&TREE_OPERAND (cond, 1));
/* If one operand was in the operand cache, but the other is
not, because it is a constant, this is a case that the
internal updating code of swap_tree_operands can't handle
properly. */
if (TREE_CODE_CLASS (TREE_CODE (op0))
!= TREE_CODE_CLASS (TREE_CODE (op1)))
update_stmt (condstmt);
}
}
}
/* We are exiting E->src, see if E->dest ends with a conditional /* We are exiting E->src, see if E->dest ends with a conditional
jump which has a known value when reached via E. jump which has a known value when reached via E.
...@@ -799,7 +845,10 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e) ...@@ -799,7 +845,10 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
/* Now temporarily cprop the operands and try to find the resulting /* Now temporarily cprop the operands and try to find the resulting
expression in the hash tables. */ expression in the hash tables. */
if (TREE_CODE (stmt) == COND_EXPR) if (TREE_CODE (stmt) == COND_EXPR)
cond = COND_EXPR_COND (stmt); {
canonicalize_comparison (stmt);
cond = COND_EXPR_COND (stmt);
}
else if (TREE_CODE (stmt) == GOTO_EXPR) else if (TREE_CODE (stmt) == GOTO_EXPR)
cond = GOTO_DESTINATION (stmt); cond = GOTO_DESTINATION (stmt);
else else
...@@ -1788,97 +1837,6 @@ simplify_rhs_and_lookup_avail_expr (tree stmt, int insert) ...@@ -1788,97 +1837,6 @@ simplify_rhs_and_lookup_avail_expr (tree stmt, int insert)
} }
} }
/* If we have z = (x OP C1), see if we earlier had x = y OP C2.
If OP is associative, create and fold (y OP C2) OP C1 which
should result in (y OP C3), use that as the RHS for the
assignment. Add minus to this, as we handle it specially below. */
if ((associative_tree_code (rhs_code) || rhs_code == MINUS_EXPR)
&& TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
&& num_imm_uses (TREE_OPERAND (rhs, 0)) == 1
&& is_gimple_min_invariant (TREE_OPERAND (rhs, 1)))
{
tree rhs_def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));
/* If the statement defines an induction variable, do not propagate
its value, so that we do not create overlapping life ranges. */
if (simple_iv_increment_p (rhs_def_stmt))
goto dont_fold_assoc;
/* See if the RHS_DEF_STMT has the same form as our statement. */
if (TREE_CODE (rhs_def_stmt) == MODIFY_EXPR)
{
tree rhs_def_rhs = TREE_OPERAND (rhs_def_stmt, 1);
enum tree_code rhs_def_code = TREE_CODE (rhs_def_rhs);
if ((rhs_code == rhs_def_code && unsafe_associative_fp_binop (rhs))
|| (rhs_code == PLUS_EXPR && rhs_def_code == MINUS_EXPR)
|| (rhs_code == MINUS_EXPR && rhs_def_code == PLUS_EXPR))
{
tree def_stmt_op0 = TREE_OPERAND (rhs_def_rhs, 0);
tree def_stmt_op1 = TREE_OPERAND (rhs_def_rhs, 1);
if (TREE_CODE (def_stmt_op0) == SSA_NAME
&& ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def_stmt_op0)
&& is_gimple_min_invariant (def_stmt_op1))
{
tree outer_const = TREE_OPERAND (rhs, 1);
tree type = TREE_TYPE (TREE_OPERAND (stmt, 0));
tree t;
/* If we care about correct floating point results, then
don't fold x + c1 - c2. Note that we need to take both
the codes and the signs to figure this out. */
if (FLOAT_TYPE_P (type)
&& !flag_unsafe_math_optimizations
&& (rhs_def_code == PLUS_EXPR
|| rhs_def_code == MINUS_EXPR))
{
bool neg = false;
neg ^= (rhs_code == MINUS_EXPR);
neg ^= (rhs_def_code == MINUS_EXPR);
neg ^= real_isneg (TREE_REAL_CST_PTR (outer_const));
neg ^= real_isneg (TREE_REAL_CST_PTR (def_stmt_op1));
if (neg)
goto dont_fold_assoc;
}
/* Ho hum. So fold will only operate on the outermost
thingy that we give it, so we have to build the new
expression in two pieces. This requires that we handle
combinations of plus and minus. */
if (rhs_def_code != rhs_code)
{
if (rhs_def_code == MINUS_EXPR)
t = build2 (MINUS_EXPR, type, outer_const, def_stmt_op1);
else
t = build2 (MINUS_EXPR, type, def_stmt_op1, outer_const);
rhs_code = PLUS_EXPR;
}
else if (rhs_def_code == MINUS_EXPR)
t = build2 (PLUS_EXPR, type, def_stmt_op1, outer_const);
else
t = build2 (rhs_def_code, type, def_stmt_op1, outer_const);
t = local_fold (t);
t = build2 (rhs_code, type, def_stmt_op0, t);
t = local_fold (t);
/* If the result is a suitable looking gimple expression,
then use it instead of the original for STMT. */
if (TREE_CODE (t) == SSA_NAME
|| (UNARY_CLASS_P (t)
&& TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
|| ((BINARY_CLASS_P (t) || COMPARISON_CLASS_P (t))
&& TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
&& is_gimple_val (TREE_OPERAND (t, 1))))
result = update_rhs_and_lookup_avail_expr (stmt, t, insert);
}
}
}
dont_fold_assoc:;
}
/* Optimize *"foo" into 'f'. This is done here rather than /* Optimize *"foo" into 'f'. This is done here rather than
in fold to avoid problems with stuff like &*"foo". */ in fold to avoid problems with stuff like &*"foo". */
if (TREE_CODE (rhs) == INDIRECT_REF || TREE_CODE (rhs) == ARRAY_REF) if (TREE_CODE (rhs) == INDIRECT_REF || TREE_CODE (rhs) == ARRAY_REF)
...@@ -2918,7 +2876,10 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, ...@@ -2918,7 +2876,10 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
bool may_have_exposed_new_symbols = false; bool may_have_exposed_new_symbols = false;
old_stmt = stmt = bsi_stmt (si); old_stmt = stmt = bsi_stmt (si);
if (TREE_CODE (stmt) == COND_EXPR)
canonicalize_comparison (stmt);
update_stmt_if_modified (stmt); update_stmt_if_modified (stmt);
ann = stmt_ann (stmt); ann = stmt_ann (stmt);
opt_stats.num_stmts++; opt_stats.num_stmts++;
......
...@@ -1047,7 +1047,6 @@ swap_tree_operands (tree stmt, tree *exp0, tree *exp1) ...@@ -1047,7 +1047,6 @@ swap_tree_operands (tree stmt, tree *exp0, tree *exp1)
*exp1 = op0; *exp1 = op0;
} }
/* Recursively scan the expression pointed to by EXPR_P in statement referred /* Recursively scan the expression pointed to by EXPR_P in statement referred
to by INFO. FLAGS is one of the OPF_* constants modifying how to interpret to by INFO. FLAGS is one of the OPF_* constants modifying how to interpret
the operands found. */ the operands found. */
...@@ -1260,39 +1259,6 @@ get_expr_operands (tree stmt, tree *expr_p, int flags) ...@@ -1260,39 +1259,6 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
case ASSERT_EXPR: case ASSERT_EXPR:
do_binary: do_binary:
{ {
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));
swap_tree_operands (stmt,
&TREE_OPERAND (expr, 0),
&TREE_OPERAND (expr, 1));
}
/* For a commutative operator we can just swap the operands. */
else if (commutative_tree_code (code))
{
swap_tree_operands (stmt,
&TREE_OPERAND (expr, 0),
&TREE_OPERAND (expr, 1));
}
}
get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags); get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags); get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
return; return;
......
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