This is the mail archive of the 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]

ARM: Improve mixed integer/VFP code

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

2009-06-24  Daniel Jacobowitz  <>

	* 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.  */
   (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 :  \

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