From 966073719a045032562f6bbfd595456b85b28e24 Mon Sep 17 00:00:00 2001
From: bonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Thu, 15 Sep 2005 21:51:13 +0000
Subject: [PATCH] 2005-09-15  Paolo Bonzini  <bonzini@gnu.org>

	* optabs.c (expand_binop): Use swap_commutative_operands_with_target
	to order operands.
	(swap_commutative_operands_with_target): New.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@104324 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog |  6 ++++++
 gcc/optabs.c  | 35 ++++++++++++++++++++++++-----------
 2 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index baa35eb1cc47..12e478a4d51b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-09-15  Paolo Bonzini  <bonzini@gnu.org>
+
+	* optabs.c (expand_binop): Use swap_commutative_operands_with_target
+	to order operands.
+	(swap_commutative_operands_with_target): New.
+
 2005-09-15  Daniel Berlin  <dberlin@dberlin.org>
 
 	* tree-data-ref.c (analyze_array_indexes): Add estimate_only
diff --git a/gcc/optabs.c b/gcc/optabs.c
index f2df3de54ea1..bcb11b5432f3 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -998,6 +998,28 @@ expand_simple_binop (enum machine_mode mode, enum rtx_code code, rtx op0,
   return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
 }
 
+
+/* Return whether OP0 and OP1 should be swapped when expanding a commutative
+   binop.  Order them according to commutative_operand_precedence and, if
+   possible, try to put TARGET first.  */
+static bool
+swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
+{
+  int op0_prec = commutative_operand_precedence (op0);
+  int op1_prec = commutative_operand_precedence (op1);
+
+  if (op0_prec < op1_prec)
+    return true;
+
+  if (op0_prec > op1_prec)
+    return false;
+
+  /* With equal precedence, both orders are ok, but try to put the
+     target first.  */
+  return target && rtx_equal_p (op1, target);
+}
+
+
 /* Generate code to perform an operation specified by BINOPTAB
    on operands OP0 and OP1, with result having machine-mode MODE.
 
@@ -1060,10 +1082,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
   /* Record where to delete back to if we backtrack.  */
   last = get_last_insn ();
 
-  /* If operation is commutative,
-     try to make the first operand a register.
-     Even better, try to make it the same as the target.
-     Also try to make the last operand a constant.  */
+  /* If operation is commutative, canonicalize the order of the operands.  */
   if (GET_RTX_CLASS (binoptab->code) == RTX_COMM_ARITH
       || binoptab == smul_widen_optab
       || binoptab == umul_widen_optab
@@ -1071,13 +1090,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
       || binoptab == umul_highpart_optab)
     {
       commutative_op = 1;
-
-      if (((target == 0 || REG_P (target))
-	   ? ((REG_P (op1)
-	       && !REG_P (op0))
-	      || target == op1)
-	   : rtx_equal_p (op1, target))
-	  || GET_CODE (op0) == CONST_INT)
+      if (swap_commutative_operands_with_target (target, op0, op1))
 	{
 	  temp = op1;
 	  op1 = op0;
-- 
GitLab