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]

Patch to improve x86 output_op_from_reg


Currently moves from an i386 integer register to the floating point unit
are performed by pushing the register onto the stack and having the
floating point unit load from that memory location.  This patch attempts
to locate an existing memory location which is equivalent to the register
so that the push and stack adjustment can be avoided.

Notes:

  1) This patch is intended as food for thought.  It doesn't currently
     verify that the memory expression is still valid at insn.  I'm
     open to suggestions on how to better implement this optimization.

  2) Another possible improvement would be to reuse an allocated stack
     slot.  This technique is currently used in other areas of the i386
     port.

  3) The effects of this patch can be seen by compiling:

double
func (int a, int b)
  {
  int c;
  int d;
  double e;

  c = a;
  d = b;
  printf("c = %d  d = %d\n", c, d);
  e = 5.0 * c + d;

  return e;
  }

     with -O -S.

ChangeLog:

Sun Mar 28 21:52:35 EST 1999  John Wehle  (john@feith.com)

	* i386.c (output_op_from_reg): New arguement `insn'.
	Check for existing equivalent memory location.
	Update all callers.
	* i386.md: Likewise.

Enjoy!

-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/config/i386/i386.c.ORIGINAL	Sat Mar 27 23:36:47 1999
--- gcc/config/i386/i386.c	Sun Mar 28 02:37:24 1999
*************** function_arg_partial_nregs (cum, mode, t
*** 862,868 ****
     as a pointer to the top of the 386 stack.  So a call from floatsidf2
     would look like this:
  
!       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  
     where %z0 corresponds to the caller's operands[1], and is used to
     emit the proper size suffix.
--- 862,868 ----
     as a pointer to the top of the 386 stack.  So a call from floatsidf2
     would look like this:
  
!       output_op_from_reg (insn, operands[1], AS1 (fild%z0,%1));
  
     where %z0 corresponds to the caller's operands[1], and is used to
     emit the proper size suffix.
*************** function_arg_partial_nregs (cum, mode, t
*** 871,884 ****
     values directly. */
  
  void
! output_op_from_reg (src, template)
       rtx src;
       char *template;
  {
    rtx xops[4];
    int size = GET_MODE_SIZE (GET_MODE (src));
  
    xops[0] = src;
    xops[1] = AT_SP (Pmode);
    xops[2] = GEN_INT (size);
    xops[3] = stack_pointer_rtx;
--- 871,909 ----
     values directly. */
  
  void
! output_op_from_reg (insn, src, template)
!      rtx insn;
       rtx src;
       char *template;
  {
+   rtx p;
    rtx xops[4];
    int size = GET_MODE_SIZE (GET_MODE (src));
  
    xops[0] = src;
+ 
+   /* See if there is already an equivalent memory location.  */
+   for (p = PREV_INSN (insn); p; p = PREV_INSN (p))
+     {
+     if (GET_CODE (p) == CODE_LABEL)
+       break;
+     if (GET_RTX_CLASS (GET_CODE (p)) != 'i')
+       continue;
+     if (GET_CODE (p) == CALL_INSN && call_used_regs [REGNO (src)])
+       break;
+     if (reg_set_p (src, PATTERN (p)))
+       {
+ 	rtx set = single_set (p);
+ 	if ( ! set
+ 	    || GET_CODE (SET_SRC (set)) != MEM
+ 	    || MEM_VOLATILE_P (SET_SRC (set)))
+ 	  break;
+ 	xops[1] = SET_SRC (set);
+ 	output_asm_insn (template, xops);
+ 	return;
+       }
+     }
+ 
    xops[1] = AT_SP (Pmode);
    xops[2] = GEN_INT (size);
    xops[3] = stack_pointer_rtx;
*************** output_387_binary_op (insn, operands)
*** 4228,4240 ****
  
        if (NON_STACK_REG_P (operands[1]))
  	{
! 	  output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
  	  return "";
  	}
  
        else if (NON_STACK_REG_P (operands[2]))
  	{
! 	  output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
  	  return "";
  	}
  
--- 4253,4265 ----
  
        if (NON_STACK_REG_P (operands[1]))
  	{
! 	  output_op_from_reg (insn, operands[1], strcat (buf, AS1 (%z0,%1)));
  	  return "";
  	}
  
        else if (NON_STACK_REG_P (operands[2]))
  	{
! 	  output_op_from_reg (insn, operands[2], strcat (buf, AS1 (%z0,%1)));
  	  return "";
  	}
  
*************** output_387_binary_op (insn, operands)
*** 4261,4273 ****
  
        if (NON_STACK_REG_P (operands[1]))
  	{
! 	  output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
  	  return "";
  	}
  
        else if (NON_STACK_REG_P (operands[2]))
  	{
! 	  output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
  	  return "";
  	}
  
--- 4286,4298 ----
  
        if (NON_STACK_REG_P (operands[1]))
  	{
! 	  output_op_from_reg (insn, operands[1], strcat (buf, AS1 (r%z0,%1)));
  	  return "";
  	}
  
        else if (NON_STACK_REG_P (operands[2]))
  	{
! 	  output_op_from_reg (insn, operands[2], strcat (buf, AS1 (%z0,%1)));
  	  return "";
  	}
  
*************** output_float_compare (insn, operands)
*** 4446,4452 ****
  	strcat (buf, "p");
  
        if (NON_STACK_REG_P (operands[1]))
! 	output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
        else if (cc_status.flags & CC_FCOMI)
  	{
  	  output_asm_insn (strcat (buf, AS2 (%z1,%y1,%0)), operands);
--- 4471,4477 ----
  	strcat (buf, "p");
  
        if (NON_STACK_REG_P (operands[1]))
! 	output_op_from_reg (insn, operands[1], strcat (buf, AS1 (%z0,%1)));
        else if (cc_status.flags & CC_FCOMI)
  	{
  	  output_asm_insn (strcat (buf, AS2 (%z1,%y1,%0)), operands);
*** gcc/config/i386/i386.md.ORIGINAL	Sun Mar 28 00:22:17 1999
--- gcc/config/i386/i386.md	Sun Mar 28 00:24:17 1999
***************
*** 1422,1428 ****
  
    if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
        RET;
      }
  
--- 1422,1428 ----
  
    if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (insn, operands[1], AS1 (fld%z0,%y1));
        RET;
      }
  
***************
*** 1560,1566 ****
  
    if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
        RET;
      }
  
--- 1560,1566 ----
  
    if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (insn, operands[1], AS1 (fld%z0,%y1));
        RET;
      }
  
***************
*** 1697,1703 ****
  
    if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
        RET;
      }
  
--- 1697,1703 ----
  
    if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (insn, operands[1], AS1 (fld%z0,%y1));
        RET;
      }
  
***************
*** 2290,2296 ****
  
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
        RET;
      }
  
--- 2290,2296 ----
  
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (insn, operands[1], AS1 (fld%z0,%y1));
        RET;
      }
  
***************
*** 2325,2331 ****
  
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
        RET;
      }
  
--- 2325,2331 ----
  
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (insn, operands[1], AS1 (fld%z0,%y1));
        RET;
      }
  
***************
*** 2360,2366 ****
  
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
        RET;
      }
  
--- 2360,2366 ----
  
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (insn, operands[1], AS1 (fld%z0,%y1));
        RET;
      }
  
***************
*** 2772,2778 ****
  {
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
        RET;
      }
    else if (GET_CODE (operands[1]) == MEM)
--- 2772,2778 ----
  {
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (insn, operands[1], AS1 (fild%z0,%1));
        RET;
      }
    else if (GET_CODE (operands[1]) == MEM)
***************
*** 2789,2795 ****
  {
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
        RET;
      }
    else if (GET_CODE (operands[1]) == MEM)
--- 2789,2795 ----
  {
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (insn, operands[1], AS1 (fild%z0,%1));
        RET;
      }
    else if (GET_CODE (operands[1]) == MEM)
***************
*** 2806,2812 ****
  {
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
        RET;
      }
    else if (GET_CODE (operands[1]) == MEM)
--- 2806,2812 ----
  {
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (insn, operands[1], AS1 (fild%z0,%1));
        RET;
      }
    else if (GET_CODE (operands[1]) == MEM)
***************
*** 2823,2829 ****
  {
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
        RET;
      }
    else if (GET_CODE (operands[1]) == MEM)
--- 2823,2829 ----
  {
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (insn, operands[1], AS1 (fild%z0,%1));
        RET;
      }
    else if (GET_CODE (operands[1]) == MEM)
***************
*** 2840,2846 ****
  {
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
        RET;
      }
    else if (GET_CODE (operands[1]) == MEM)
--- 2840,2846 ----
  {
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (insn, operands[1], AS1 (fild%z0,%1));
        RET;
      }
    else if (GET_CODE (operands[1]) == MEM)
***************
*** 2857,2863 ****
  {
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
        RET;
      }
    else if (GET_CODE (operands[1]) == MEM)
--- 2857,2863 ----
  {
    if (NON_STACK_REG_P (operands[1]))
      {
!       output_op_from_reg (insn, operands[1], AS1 (fild%z0,%1));
        RET;
      }
    else if (GET_CODE (operands[1]) == MEM)
-------------------------------------------------------------------------
|   Feith Systems  |   Voice: 1-215-646-8000  |  Email: john@feith.com  |
|    John Wehle    |     Fax: 1-215-540-5495  |                         |
-------------------------------------------------------------------------



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