Patch to improve x86 output_op_from_reg
John Wehle
john@feith.com
Sun Mar 28 20:08:00 GMT 1999
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 | |
-------------------------------------------------------------------------
More information about the Gcc-patches
mailing list