This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Improve VFP code generation
- From: Paul Brook <paul at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 29 Mar 2006 20:15:40 +0100
- Subject: Improve VFP code generation
Under some circumstances, particularly when accessing arrays, gcc generates
poor code for VFP memory accesses. It will typically generate:
ldrd r6, [r3, r5]
fmdrr d7, r6, r7
when it would be much better to use
add r6, r3, r5
fldd d7, [r6]
This uses fewer registers, and transfers less data over the coprocessor
interface.
The solution is to disparage core registers in the floating point move
patterns. This is sufficient to make the register allocator pick the second
code sequence above.
The definition of REGISTER_MOVE_COST already says the latter sequence is
cheaper. I'm guessing once we allocate the registers it's too late for this
to make any difference.
Tested with cross to arm-none-eabi.
Applied to mainline and branches/csl/arm-4_1.
Paul
Mainline:
2006-03-29 Paul Brook <paul@codesourcery.com>
* config/arm/vfp.md (movsf_vfp): Disparage w<->r alternatives.
(movdf_vfp): Ditto.
csl-arm:
2006-03-29 Paul Brook <paul@codesourcery.com>
* gcc/config/arm/vfp.md (movsf_vfp): Disparage w<->r alternatives.
(thumb2_movsf_vfp, movdf_vfp, thumb2_movdf_vfp): Ditto.
Index: gcc/config/arm/vfp.md
===================================================================
--- gcc/config/arm/vfp.md (revision 112251)
+++ gcc/config/arm/vfp.md (working copy)
@@ -232,10 +232,12 @@ (define_insn "*thumb2_movdi_vfp"
;; SFmode moves
+;; Disparage the w<->r cases because reloading an invalid address is
+;; preferable to loading the value via integer registers.
(define_insn "*movsf_vfp"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=w,r,w ,Uv,r ,m,w,r")
- (match_operand:SF 1 "general_operand" " r,w,UvE,w, mE,r,w,r"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=w,?r,w ,Uv,r ,m,w,r")
+ (match_operand:SF 1 "general_operand" " ?r,w,UvE,w, mE,r,w,r"))]
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
&& ( s_register_operand (operands[0], SFmode)
|| s_register_operand (operands[1], SFmode))"
@@ -255,8 +257,8 @@ (define_insn "*movsf_vfp"
)
(define_insn "*thumb2_movsf_vfp"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=w,r,w ,Uv,r ,m,w,r")
- (match_operand:SF 1 "general_operand" " r,w,UvE,w, mE,r,w,r"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=w,?r,w ,Uv,r ,m,w,r")
+ (match_operand:SF 1 "general_operand" " ?r,w,UvE,w, mE,r,w,r"))]
"TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP
&& ( s_register_operand (operands[0], SFmode)
|| s_register_operand (operands[1], SFmode))"
@@ -279,8 +281,8 @@ (define_insn "*thumb2_movsf_vfp"
;; DFmode moves
(define_insn "*movdf_vfp"
- [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,r,r, m,w ,Uv,w,r")
- (match_operand:DF 1 "soft_df_operand" " r,w,mF,r,UvF,w, w,r"))]
+ [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,r, m,w ,Uv,w,r")
+ (match_operand:DF 1 "soft_df_operand" " ?r,w,mF,r,UvF,w, w,r"))]
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
&& ( register_operand (operands[0], DFmode)
|| register_operand (operands[1], DFmode))"
@@ -314,8 +316,8 @@ (define_insn "*movdf_vfp"
)
(define_insn "*thumb2_movdf_vfp"
- [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,r,r, m,w ,Uv,w,r")
- (match_operand:DF 1 "soft_df_operand" " r,w,mF,r,UvF,w, w,r"))]
+ [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,r, m,w ,Uv,w,r")
+ (match_operand:DF 1 "soft_df_operand" " ?r,w,mF,r,UvF,w, w,r"))]
"TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
"*
{
Index: gcc/config/arm/vfp.md
===================================================================
--- gcc/config/arm/vfp.md (revision 112500)
+++ gcc/config/arm/vfp.md (working copy)
@@ -181,10 +181,12 @@ (define_insn "*arm_movdi_vfp"
;; SFmode moves
+;; Disparage the w<->r cases because reloading an invalid address is
+;; preferable to loading the value via integer registers.
(define_insn "*movsf_vfp"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=w,r,w ,Uv,r ,m,w,r")
- (match_operand:SF 1 "general_operand" " r,w,UvE,w, mE,r,w,r"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=w,?r,w ,Uv,r ,m,w,r")
+ (match_operand:SF 1 "general_operand" " ?r,w,UvE,w, mE,r,w,r"))]
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
&& ( s_register_operand (operands[0], SFmode)
|| s_register_operand (operands[1], SFmode))"
@@ -207,8 +209,8 @@ (define_insn "*movsf_vfp"
;; DFmode moves
(define_insn "*movdf_vfp"
- [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,r,r, m,w ,Uv,w,r")
- (match_operand:DF 1 "soft_df_operand" " r,w,mF,r,UvF,w, w,r"))]
+ [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,r, m,w ,Uv,w,r")
+ (match_operand:DF 1 "soft_df_operand" " ?r,w,mF,r,UvF,w, w,r"))]
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
&& ( register_operand (operands[0], DFmode)
|| register_operand (operands[1], DFmode))"