summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-operands.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-operands.c')
-rw-r--r--gcc/tree-ssa-operands.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index 02380b66361..f1edfa18e18 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;