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]

i386 fp moves changes



Hi
The LEGITIMATE_CONSTANT_P returns 0 for CONST_DOUBLES other than 0 and 1.
This results in suboptimal code when integer instructions are used (where
loads from constant pool are used at the place of immediates).

Making LEGITIMATE_CONSTANT_P return 1 results in bad code as well, because all
moves uses immediates in combine and thus immediates are never combined into
arithmetic oprations.

The best solution I was able to come with is to make the LEGITIMATE_CONSTANT_P
return 1 and let the move patterns accept immediates before reload only for
stores to memory. In other cases constant pool is used and post-reload
splitters converts them back to direct loads.  The combiner works fine now even
for 0 and 1 and only problem I am aware of is that PIC register might be
initialized when it is not necesary in some cases.

This patch also fixes some other glitches in move patterns - the mem<->mem
pushes are alowed by expander (this results in better code when not optimizing),
and PREFERRED_RELOAD_CLASS is updated - it now allows loads of fp constants
to integer registers and don't change ALL_REGS to GENERAL_REGS, since the
integer fp fp moves are emited anyway (and fp register is used only
when no integer registers are available.)

Fri Dec 30 17:00:49 CET 1999  Jan Hubicka  <hubicka@freesoft.cz>
	* i386.c (ix86_expand_move): Allow pushes of memory, offload to memory
	all FP constants for constant->reg moves.
	(ix86_split_to_parts): Try to convert memory address into immediate
	when available in the constant pool.
	* i386.h (PREFERRED_RELOAD_CLASS): Allow CONST_DOUBLE->integer reg
	moves.
	(LEGITIMATE_CONSTANT_P): Return 1.
	* i386.md (pushsf): New splitter to convert constant pool memory
	reference to immediate.
	(mov?f): Likewise; do not allow CONST_DOUBLE for reg moves before
	reload.
*** i386.c.nod	Thu Dec 30 12:07:00 1999
--- i386.c	Thu Dec 30 14:16:31 1999
*************** ix86_expand_move (mode, operands)
*** 3709,3729 ****
      }
    else
      {
!       if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  	operands[1] = force_reg (mode, operands[1]);
  
        if (FLOAT_MODE_P (mode))
  	{
! 	  /* If we are loading a floating point constant that isn't 0 or 1
! 	     into a register, force the value to memory now, since we'll 
! 	     get better code out the back end.  */
  
  	  if (strict)
  	    ;
- 	  else if (GET_CODE (operands[0]) == MEM)
- 	    operands[1] = force_reg (mode, operands[1]);
  	  else if (GET_CODE (operands[1]) == CONST_DOUBLE
! 		   && ! standard_80387_constant_p (operands[1]))
  	    operands[1] = validize_mem (force_const_mem (mode, operands[1]));
  	}
      }
--- 3709,3728 ----
      }
    else
      {
!       if (GET_CODE (operands[0]) == MEM && !push_operand (operands[0], mode)
! 	  && GET_CODE (operands[1]) == MEM)
  	operands[1] = force_reg (mode, operands[1]);
  
        if (FLOAT_MODE_P (mode))
  	{
! 	  /* If we are loading a floating point constant to a register,
! 	     force the value to memory now, since we'll get better code
! 	     out the back end.  */
  
  	  if (strict)
  	    ;
  	  else if (GET_CODE (operands[1]) == CONST_DOUBLE
! 		   && register_operand (operands[0], mode))
  	    operands[1] = validize_mem (force_const_mem (mode, operands[1]));
  	}
      }
*************** ix86_split_to_parts (operand, parts, mod
*** 4779,4784 ****
--- 4778,4790 ----
    if (size < 2 || size > 3)
      abort ();
  
+   /* Optimize constant pool reference to immediates.  This is used by fp moves,
+      that force all constants to memory to allow combining.  */
+ 
+   if (GET_CODE (operand) == MEM && GET_CODE (XEXP (operand, 0)) == SYMBOL_REF
+       && CONSTANT_POOL_ADDRESS_P (XEXP (operand, 0)))
+     operand = get_pool_constant (XEXP (operand, 0));
+ 
    if (GET_CODE (operand) == MEM && !offsettable_memref_p (operand))
      {
        /* The only non-offsetable memories we handle are pushes.  */
*** i386.h.nod	Thu Dec 30 12:04:43 1999
--- i386.h	Thu Dec 30 16:50:08 1999
*************** enum reg_class
*** 1035,1045 ****
  #define PREFERRED_RELOAD_CLASS(X,CLASS)					\
    (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != VOIDmode		\
     ? (standard_80387_constant_p (X)					\
!       ? reg_class_subset_p (CLASS, FLOAT_REGS) ? CLASS : FLOAT_REGS	\
!       : NO_REGS)							\
     : GET_MODE (X) == QImode && ! reg_class_subset_p (CLASS, Q_REGS) ? Q_REGS \
-    : ((CLASS) == ALL_REGS						\
-       && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) ? GENERAL_REGS	\
     : (CLASS))
  
  /* If we are copying between general and FP registers, we need a memory
--- 1035,1045 ----
  #define PREFERRED_RELOAD_CLASS(X,CLASS)					\
    (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != VOIDmode		\
     ? (standard_80387_constant_p (X)					\
!       ? CLASS								\
!       : (reg_class_subset_p (CLASS, FLOAT_REGS) 			\
! 	 ? NO_REGS							\
! 	 : reg_class_subset_p (CLASS, GENERAL_REGS) ? CLASS : GENERAL_REGS)) \
     : GET_MODE (X) == QImode && ! reg_class_subset_p (CLASS, Q_REGS) ? Q_REGS \
     : (CLASS))
  
  /* If we are copying between general and FP registers, we need a memory
*************** do {								\
*** 1556,1563 ****
  /* Nonzero if the constant value X is a legitimate general operand.
     It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
  
! #define LEGITIMATE_CONSTANT_P(X) \
!   (GET_CODE (X) == CONST_DOUBLE ? standard_80387_constant_p (X) : 1)
  
  #ifdef REG_OK_STRICT
  #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)				\
--- 1556,1562 ----
  /* Nonzero if the constant value X is a legitimate general operand.
     It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
  
! #define LEGITIMATE_CONSTANT_P(X) 1
  
  #ifdef REG_OK_STRICT
  #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)				\
*** i386.md.nod	Thu Dec 30 12:32:30 1999
--- i386.md	Thu Dec 30 14:19:40 1999
***************
*** 1721,1726 ****
--- 1721,1738 ----
  }"
    [(set_attr "type" "multi,push")])
  
+ (define_split
+   [(set (match_operand:SF 0 "push_operand" "")
+ 	(match_operand:SF 1 "memory_operand" ""))]
+   "reload_completed
+    && GET_CODE (operands[1]) == MEM
+    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
+    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
+   [(set (match_dup 0)
+ 	(match_dup 1))]
+   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
+ 
+ 
  ;; %%% Kill this when call knows how to work this out.
  (define_split
    [(set (match_operand:SF 0 "push_operand" "")
***************
*** 1732,1738 ****
  (define_insn "*movsf_1"
    [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,m")
  	(match_operand:SF 1 "general_operand" "fm#r,f#r,G,rmF#f,Fr#f"))]
!   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
    "*
  {
    switch (which_alternative)
--- 1744,1753 ----
  (define_insn "*movsf_1"
    [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,m")
  	(match_operand:SF 1 "general_operand" "fm#r,f#r,G,rmF#f,Fr#f"))]
!   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
!    && (reload_in_progress || reload_completed
!        || GET_CODE (operands[1]) != CONST_DOUBLE
!        || memory_operand (operands[0], SFmode))" 
    "*
  {
    switch (which_alternative)
***************
*** 1772,1777 ****
--- 1787,1807 ----
  }"
    [(set_attr "type" "fmov,fmov,fmov,imov,imov")])
  
+ (define_split
+   [(set (match_operand:SF 0 "general_operand" "")
+ 	(match_operand:SF 1 "memory_operand" ""))]
+   "reload_completed
+    && GET_CODE (operands[1]) == MEM
+    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
+    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
+    && (!(FP_REG_P (operands[0]) || 
+ 	 (GET_CODE (operands[0]) == SUBREG
+ 	  && FP_REG_P (SUBREG_REG (operands[0]))))
+        || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
+   [(set (match_dup 0)
+ 	(match_dup 1))]
+   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
+ 
  (define_insn "swapsf"
    [(set (match_operand:SF 0 "register_operand" "+f")
  	(match_operand:SF 1 "register_operand" "+f"))
***************
*** 1849,1855 ****
    [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,f,*r,o")
  	(match_operand:DF 1 "general_operand" "fm,f,G,*roF,F*r"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
!    && optimize_size"
    "*
  {
    switch (which_alternative)
--- 1879,1888 ----
    [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,f,*r,o")
  	(match_operand:DF 1 "general_operand" "fm,f,G,*roF,F*r"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
!    && optimize_size
!    && (reload_in_progress || reload_completed
!        || GET_CODE (operands[1]) != CONST_DOUBLE
!        || memory_operand (operands[0], DFmode))" 
    "*
  {
    switch (which_alternative)
***************
*** 1893,1899 ****
    [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
  	(match_operand:DF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
!    && !optimize_size"
    "*
  {
    switch (which_alternative)
--- 1926,1935 ----
    [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
  	(match_operand:DF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
!    && !optimize_size
!    && (reload_in_progress || reload_completed
!        || GET_CODE (operands[1]) != CONST_DOUBLE
!        || memory_operand (operands[0], DFmode))" 
    "*
  {
    switch (which_alternative)
***************
*** 1948,1953 ****
--- 1984,2001 ----
     (set (match_dup 3) (match_dup 6))]
    "if (ix86_split_long_move (operands)) DONE;")
  
+ (define_split
+   [(set (match_operand:DF 0 "register_operand" "")
+ 	(match_operand:DF 1 "memory_operand" ""))]
+   "reload_completed
+    && GET_CODE (operands[1]) == MEM
+    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
+    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
+    && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
+   [(set (match_dup 0)
+ 	(match_dup 1))]
+   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
+ 
  (define_insn "swapdf"
    [(set (match_operand:DF 0 "register_operand" "+f")
  	(match_operand:DF 1 "register_operand" "+f"))
***************
*** 2051,2057 ****
    [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
  	(match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
!    && optimize_size"
    "*
  {
    switch (which_alternative)
--- 2099,2108 ----
    [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
  	(match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
!    && optimize_size
!    && (reload_in_progress || reload_completed
!        || GET_CODE (operands[1]) != CONST_DOUBLE
!        || memory_operand (operands[0], XFmode))" 
    "*
  {
    switch (which_alternative)
***************
*** 2094,2100 ****
    [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
  	(match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
!    && !optimize_size"
    "*
  {
    switch (which_alternative)
--- 2145,2154 ----
    [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
  	(match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
!    && !optimize_size
!    && (reload_in_progress || reload_completed
!        || GET_CODE (operands[1]) != CONST_DOUBLE
!        || memory_operand (operands[0], XFmode))" 
    "*
  {
    switch (which_alternative)
***************
*** 2149,2154 ****
--- 2203,2220 ----
     (set (match_dup 4) (match_dup 7))]
    "if (ix86_split_long_move (operands)) DONE;")
  
+ (define_split
+   [(set (match_operand:XF 0 "register_operand" "")
+ 	(match_operand:XF 1 "memory_operand" ""))]
+   "reload_completed
+    && GET_CODE (operands[1]) == MEM
+    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
+    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
+    && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
+   [(set (match_dup 0)
+ 	(match_dup 1))]
+   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
+ 
  (define_insn "swapxf"
    [(set (match_operand:XF 0 "register_operand" "+f")
  	(match_operand:XF 1 "register_operand" "+f"))


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