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]

fix pr23303


As explained in http://gcc.gnu.org/ml/gcc/2005-08/msg00580.html; bootstrapped/regtested on i386.

Ok for mainline?

Paolo
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.857
diff -p -c -r1.857 i386.c
*** config/i386/i386.c	2 Sep 2005 00:27:56 -0000	1.857
--- config/i386/i386.c	9 Sep 2005 08:47:27 -0000
*************** ix86_fixup_binary_operands (enum rtx_cod
*** 8394,8412 ****
    /* If the destination is memory, and we do not have matching source
       operands, do things in registers.  */
    matching_memory = 0;
!   if (GET_CODE (dst) == MEM)
      {
        if (rtx_equal_p (dst, src1))
  	matching_memory = 1;
        else if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
  	       && rtx_equal_p (dst, src2))
  	matching_memory = 2;
!       else
! 	dst = gen_reg_rtx (mode);
      }
  
    /* Both source operands cannot be in memory.  */
!   if (GET_CODE (src1) == MEM && GET_CODE (src2) == MEM)
      {
        if (matching_memory != 2)
  	src2 = force_reg (mode, src2);
--- 8394,8414 ----
    /* If the destination is memory, and we do not have matching source
       operands, do things in registers.  */
    matching_memory = 0;
!   if (MEM_P (dst))
      {
        if (rtx_equal_p (dst, src1))
  	matching_memory = 1;
        else if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
  	       && rtx_equal_p (dst, src2))
  	matching_memory = 2;
! 
!       if ((optimize && !optimize_size && !no_new_pseudos && !TARGET_READ_MODIFY)
! 	  || matching_memory == 0)
!         dst = gen_reg_rtx (mode);
      }
  
    /* Both source operands cannot be in memory.  */
!   if (MEM_P (src1) && MEM_P (src2))
      {
        if (matching_memory != 2)
  	src2 = force_reg (mode, src2);
*************** ix86_fixup_binary_operands (enum rtx_cod
*** 8421,8426 ****
--- 8423,8441 ----
        && GET_RTX_CLASS (code) != RTX_COMM_ARITH)
      src1 = force_reg (mode, src1);
  
+   /* If optimizing for speed, and the processor does not like memory operands
+      in arithmetic operations, copy to regs.  This is also done by a peephole
+      but doing it here exposes more optimization opportunities.  */
+   if (optimize && !no_new_pseudos && !optimize_size && !TARGET_READ_MODIFY)
+     {
+       if (MEM_P (dst))
+ 	dst = gen_reg_rtx (mode);
+       if (MEM_P (src1))
+ 	src1 = force_reg (mode, src1);
+       if (MEM_P (src2))
+ 	src2 = force_reg (mode, src2);
+     }
+ 
    src1 = operands[1] = src1;
    src2 = operands[2] = src2;
    return dst;
*************** void
*** 8509,8529 ****
  ix86_expand_unary_operator (enum rtx_code code, enum machine_mode mode,
  			    rtx operands[])
  {
!   int matching_memory;
    rtx src, dst, op, clob;
  
    dst = operands[0];
    src = operands[1];
  
    /* If the destination is memory, and we do not have matching source
!      operands, do things in registers.  */
!   matching_memory = 0;
    if (MEM_P (dst))
      {
!       if (rtx_equal_p (dst, src))
! 	matching_memory = 1;
!       else
  	dst = gen_reg_rtx (mode);
      }
  
    /* When source operand is memory, destination must match.  */
--- 8524,8546 ----
  ix86_expand_unary_operator (enum rtx_code code, enum machine_mode mode,
  			    rtx operands[])
  {
!   bool matching_memory;
    rtx src, dst, op, clob;
  
    dst = operands[0];
    src = operands[1];
  
    /* If the destination is memory, and we do not have matching source
!      operands, or the processor penalizes memory operands in arithmetic
!      operations, do things in registers.  */
!   matching_memory = false;
    if (MEM_P (dst))
      {
!       if ((optimize && !optimize_size && !no_new_pseudos && !TARGET_READ_MODIFY)
!           || !rtx_equal_p (dst, src))
  	dst = gen_reg_rtx (mode);
+       else
+ 	matching_memory = true;
      }
  
    /* When source operand is memory, destination must match.  */
*************** ix86_expand_fp_absneg_operator (enum rtx
*** 8657,8666 ****
    matching_memory = false;
    if (MEM_P (dst))
      {
!       if (rtx_equal_p (dst, src))
! 	matching_memory = true;
        else
! 	dst = gen_reg_rtx (mode);
      }
    if (MEM_P (src) && !matching_memory)
      src = force_reg (mode, src);
--- 8674,8684 ----
    matching_memory = false;
    if (MEM_P (dst))
      {
!       if ((optimize && !optimize_size && !no_new_pseudos && !TARGET_READ_MODIFY)
! 	  || !rtx_equal_p (dst, src))
!         dst = gen_reg_rtx (mode);
        else
!         matching_memory = true;
      }
    if (MEM_P (src) && !matching_memory)
      src = force_reg (mode, src);
*************** ix86_rtx_costs (rtx x, int code, int out
*** 16375,16380 ****
--- 16393,16406 ----
  	*total = 0;
        return false;
  
+     case MEM:
+       /* Penalize memory accesses inside arithmetic operations if the
+ 	 processor is slow at them.  */
+       if (!optimize_size && !TARGET_READ_MODIFY
+ 	  && (GET_RTX_CLASS (outer_code) == RTX_BIN_ARITH
+ 	      || GET_RTX_CLASS (outer_code) == RTX_COMM_ARITH))
+ 	*total++;
+ 
      default:
        return false;
      }
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.814
diff -p -u -r1.814 expr.c
--- expr.c	1 Sep 2005 01:06:45 -0000	1.814
+++ expr.c	9 Sep 2005 08:50:39 -0000
@@ -6614,6 +6614,18 @@ expand_expr_real_1 (tree exp, rtx target
       target = 0;
     }
 
+  /* If we'll do cse, generate all results into pseudo registers
+     since 1) that allows cse to find more things
+     and 2) otherwise cse could produce an insn the machine
+     cannot support.  An exception is a CONSTRUCTOR into a multi-word
+     MEM: that's much more likely to be most efficient into the MEM.
+     Another is a CALL_EXPR which must return in memory.  */
+
+  if (! cse_not_expected && mode != BLKmode && target
+      && (!REG_P (target) || REGNO (target) < FIRST_PSEUDO_REGISTER)
+      && ! (code == CONSTRUCTOR && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
+      && ! (code == CALL_EXPR && aggregate_value_p (exp, exp)))
+    target = 0;
 
   switch (code)
     {

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