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]

[PING][PATCH][REVISED] Fix PR middle-end/PR28690, modify swap_commutative_operands_p


On Tue, Jun 19, 2007 at 05:38:14PM +0200, Paolo Bonzini wrote:
> 2) This has nothing to do with this patch which -- in my opinion -- is 
> now ready to be committed (as soon as the regression period finishes).

Now that we seem to have resolved the x86_64 performance regressions,
I'd like to ask for another review of this patch.

I had to refresh the patch (attached below) since the last time I posted it
due to the dataflow merge.  I bootstrapped and regtested it on powerpc64-linux
and everything still looks good.  Is this patch ok for mainline once the
freeze is over?

Peter

2007-06-20  Peter Bergner  <bergner@vnet.ibm.com>

	PR middle-end/PR28690
	* optabs.c (expand_binop): (emit_cmp_and_jump_insns): Allow EQ compares.
	* rtlanal.c (commutative_operand_precedence): Prefer both REG_POINTER
	and MEM_POINTER operands over REG and MEM operands.
	(swap_commutative_operands_p): Change return value to bool.  In case
	of a tie, sort on REGNO.
	* rtl.h: Update the corresponding prototype.
	* tree-ssa-address.c (gen_addr_rtx): Use simplify_gen_binary
	instead of gen_rtx_PLUS.

Index: optabs.c
===================================================================
--- optabs.c	(revision 125863)
+++ optabs.c	(working copy)
@@ -4027,9 +4027,11 @@ emit_cmp_and_jump_insns (rtx x, rtx y, e
   /* Swap operands and condition to ensure canonical RTL.  */
   if (swap_commutative_operands_p (x, y))
     {
-      /* If we're not emitting a branch, this means some caller
-         is out of sync.  */
-      gcc_assert (label);
+      /* If we're not emitting a branch, callers are required to pass
+	 operands in an order conforming to canonical RTL.  We relax this
+	 for commutative comparsions so callers using EQ don't need to do
+	 swapping by hand.  */
+      gcc_assert (label || (comparison == swap_condition (comparison)));
 
       op0 = y, op1 = x;
       comparison = swap_condition (comparison);
Index: rtlanal.c
===================================================================
--- rtlanal.c	(revision 125863)
+++ rtlanal.c	(working copy)
@@ -2877,9 +2877,9 @@ commutative_operand_precedence (rtx op)
   
   /* Constants always come the second operand.  Prefer "nice" constants.  */
   if (code == CONST_INT)
-    return -7;
+    return -10;
   if (code == CONST_DOUBLE)
-    return -6;
+    return -9;
   op = avoid_constant_pool_reference (op);
   code = GET_CODE (op);
 
@@ -2887,22 +2887,24 @@ commutative_operand_precedence (rtx op)
     {
     case RTX_CONST_OBJ:
       if (code == CONST_INT)
-        return -5;
+        return -8;
       if (code == CONST_DOUBLE)
-        return -4;
-      return -3;
+        return -7;
+      return -6;
 
     case RTX_EXTRA:
       /* SUBREGs of objects should come second.  */
       if (code == SUBREG && OBJECT_P (SUBREG_REG (op)))
-        return -2;
-
+        return -5;
       return 0;
 
     case RTX_OBJ:
       /* Complex expressions should be the first, so decrease priority
          of objects.  */
-      return -1;
+      if (REG_P (op))
+	return (REG_POINTER (op)) ? -1 : -3;
+      else
+	return (MEM_P (op) && MEM_POINTER (op)) ? -2 : -4;
 
     case RTX_COMM_ARITH:
       /* Prefer operands that are themselves commutative to be first.
@@ -2929,11 +2931,19 @@ commutative_operand_precedence (rtx op)
 /* Return 1 iff it is necessary to swap operands of commutative operation
    in order to canonicalize expression.  */
 
-int
+bool
 swap_commutative_operands_p (rtx x, rtx y)
 {
-  return (commutative_operand_precedence (x)
-	  < commutative_operand_precedence (y));
+  int result = (commutative_operand_precedence (x)
+		- commutative_operand_precedence (y));
+  if (result)
+    return result < 0;
+
+  /* Group together equal REGs to do more simplification.  */
+  if (REG_P (x) && REG_P (y))
+    return REGNO (x) > REGNO (y);
+
+  return false;
 }
 
 /* Return 1 if X is an autoincrement side effect and the register is
Index: tree-ssa-address.c
===================================================================
--- tree-ssa-address.c	(revision 125863)
+++ tree-ssa-address.c	(working copy)
@@ -125,7 +125,7 @@ gen_addr_rtx (rtx symbol, rtx base, rtx 
   if (base)
     {
       if (*addr)
-	*addr = gen_rtx_PLUS (Pmode, *addr, base);
+	*addr = simplify_gen_binary (PLUS, Pmode, base, *addr);
       else
 	*addr = base;
     }
Index: rtl.h
===================================================================
--- rtl.h	(revision 125863)
+++ rtl.h	(working copy)
@@ -1674,7 +1674,7 @@ extern int reg_referenced_p (rtx, rtx);
 extern int reg_used_between_p (rtx, rtx, rtx);
 extern int reg_set_between_p (rtx, rtx, rtx);
 extern int commutative_operand_precedence (rtx);
-extern int swap_commutative_operands_p (rtx, rtx);
+extern bool swap_commutative_operands_p (rtx, rtx);
 extern int modified_between_p (rtx, rtx, rtx);
 extern int no_labels_between_p (rtx, rtx);
 extern int modified_in_p (rtx, rtx);


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