This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix non-canonical RTL produced by expand, take 2


This patch makes expand output canonical RTL for binary commutative operations. The original patch, at http://gcc.gnu.org/ml/gcc-patches/2005-09/msg00941.html, did not put a REG first if the operands are both in the rtx class RTX_OBJECT and none is equal to the target. This detail alone caused a regression in gap on powerpc.

If the operands have the same precedence, this patch instead matches exactly what expand is doing now. If the operands have different precedence, CSE will always fix it (but it won't with fwprop -- this patch fixes a regression on crafty caused by the fwprop patch).

Bootstrapped/regtested i686-pc-linux-gnu, tested on powerpc-apple-darwin8.2.0 that the gap assembly code is the same with or without the patch.

Ok for mainline?

Paolo
Index: optabs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.297
diff -u -r1.297 optabs.c
--- optabs.c	29 Sep 2005 21:49:35 -0000	1.297
+++ optabs.c	10 Oct 2005 11:11:07 -0000
@@ -998,6 +998,30 @@
   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 or a pseudo 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 it is better if the
+     first operand is TARGET, or if both TARGET and OP0 are pseudos.  */
+  if (target == 0 || REG_P (target))
+    return (REG_P (op1) && !REG_P (op0)) || target == op1;
+  else
+    return 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.
 
@@ -1073,12 +1097,7 @@
     {
       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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]