ARM: Improve mixed integer/VFP code

Daniel Jacobowitz drow@false.org
Mon Jun 29 17:47:00 GMT 2009


We discovered in a GCC 4.3-based compiler that if a register was
mostly needed in integer registers, the cost of memory and VFP were
exactly the same.  So if there was also an integer-to-float
conversion, which requires the value in a VFP register, VFP would win
out over memory in regclass.

The costs have been this way since VFP support was first checked in.
In fact, this isn't accurate.  Especially if you assume a cache hit on
the spill location (likely, especially in loops), memory is cheaper.
The exact amounts depend on your processor, but I've changed it
unconditionally as there are other reasons to discourage this use
of the FPU.

In GCC 4.4 and trunk, the problem is masked by the better register
allocator.  Since the reasoning still holds, I've chosen to apply
the cost change to trunk also.  I suspect a more complicated test
case will show the same improvement.

I tested this on arm-none-eabi, and Paul Brook approved it off-list.
I've checked it in.

-- 
Daniel Jacobowitz
CodeSourcery

2009-06-24  Daniel Jacobowitz  <dan@codesourcery.com>

	* config/arm/arm.h (REGISTER_MOVE_COST): Increase VFP register
	move cost.

Index: gcc/config/arm/arm.h
===================================================================
--- gcc/config/arm/arm.h	(revision 148907)
+++ gcc/config/arm/arm.h	(working copy)
@@ -1433,13 +1433,17 @@ do {									      \
 /* If defined, gives a class of registers that cannot be used as the
    operand of a SUBREG that changes the mode of the object illegally.  */
 
-/* Moves between FPA_REGS and GENERAL_REGS are two memory insns.  */
+/* Moves between FPA_REGS and GENERAL_REGS are two memory insns.
+   Moves between VFP_REGS and GENERAL_REGS are a single insn, but
+   it is typically more expensive than a single memory access.  We set
+   the cost to less than two memory accesses so that floating
+   point to integer conversion does not go through memory.  */
 #define REGISTER_MOVE_COST(MODE, FROM, TO)		\
   (TARGET_32BIT ?						\
    ((FROM) == FPA_REGS && (TO) != FPA_REGS ? 20 :	\
     (FROM) != FPA_REGS && (TO) == FPA_REGS ? 20 :	\
-    IS_VFP_CLASS (FROM) && !IS_VFP_CLASS (TO) ? 10 :	\
-    !IS_VFP_CLASS (FROM) && IS_VFP_CLASS (TO) ? 10 :	\
+    IS_VFP_CLASS (FROM) && !IS_VFP_CLASS (TO) ? 15 :	\
+    !IS_VFP_CLASS (FROM) && IS_VFP_CLASS (TO) ? 15 :	\
     (FROM) == IWMMXT_REGS && (TO) != IWMMXT_REGS ? 4 :  \
     (FROM) != IWMMXT_REGS && (TO) == IWMMXT_REGS ? 4 :  \
     (FROM) == IWMMXT_GR_REGS || (TO) == IWMMXT_GR_REGS ? 20 :  \



More information about the Gcc-patches mailing list