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]

Regclass propagation patch 1



Hi
With our current handling of FP operations using integer regs as we do for i386
or VIS instructions as we do on Ultrasparc, it is important for the compiler to realize
that when register A is used by instructions doable in both FP and integer unit,
but it is used in instruction together with register B, that is calculated in FP
unit, register A must be in FP unit too.

This can be done in regclass, but currently isn't. To get correct preferences for
instructions that can be done in both (I.E 0 cost for the both classes), we must
use constraints like "f#r,r#f", so we hide the fact behind regclass.

This patch modifies regclass to handle properly constraints done in form "f,r",
so in the first pass, both FP and integer registers get's zero and in the second
pass preferrences are propagated trought operations. This avoids many of slowdowns
caused by my fp in integer patch.

Remaining problem is that regclass use only two passes so information is not
propagated in longer chains. I have code to make regclass do full propagation,
but it adds quite large amout of code to keep regclass linear, so I will send
it later after I re-think it.

Problem remains for group of registers that are used together, but there are no
instruction not doable in both units. Then decision is not done and resulting
code might be ugly. I would like to handle it later by modyfing the preffered
class according to the reg_renumber assigned by local and global alloc and
propagating the changes while local/global is working.

The once first register of the group is assigned to the hardreg, other will get
prefferences to the same unit.

Effect can be seen for example:
double n=1;
main()
{
    double a=1,b,c;
    asm("%0 %1":"=f,r"(b):"f,r"(a));
    asm("%0 %1":"=f,r"(c):"f,r"(b));
    asm("%0"::"r"(c));
}

Now you get GENERAL_REGS preferrence for c and b and FLOAT_INT_REGS for a
(because it is too far for propagation).  Originaly the preferences was
GENERAL_REGS for c and FLOAT_REGS for a/b.

The patch also contains necesary changes to i386.md to avoid extra # constraints
and change to dumping code to print preferrences after each pass.

Fri Dec 31 12:38:39 CET 1999  Jan Hubicka  <hubicka@freesoft.cz>
	* regclass.c (regclass): Dump after each pass.
	(record_reg_classes): Fixt preferred_class handling.
	* i386.md (push?f, mov?f, neg?f, abs?f): Remove obsolette '#' parts
	in constraints.
*** regclass.c.nof	Fri Dec 31 10:58:16 1999
--- regclass.c	Fri Dec 31 12:21:40 1999
*************** regclass (f, nregs, dump)
*** 1159,1168 ****
  	  reg_pref[i].prefclass = (int) best;
  	  reg_pref[i].altclass = (int) alt;
  	}
      }
  
-   if (dump)
-     dump_regclass (dump);
  #ifdef FORBIDDEN_INC_DEC_CLASSES
    free (in_inc_dec);
  #endif
--- 1157,1169 ----
  	  reg_pref[i].prefclass = (int) best;
  	  reg_pref[i].altclass = (int) alt;
  	}
+       if (dump)
+ 	{
+ 	  fprintf (dump, "\nPass %i\n",pass);
+ 	  dump_regclass (dump);
+ 	}
      }
  
  #ifdef FORBIDDEN_INC_DEC_CLASSES
    free (in_inc_dec);
  #endif
*************** record_reg_classes (n_alts, n_ops, ops, 
*** 1326,1337 ****
  		  /* If we have assigned a class to this register in our
  		     first pass, add a cost to this alternative corresponding
  		     to what we would add if this register were not in the
! 		     appropriate class.  */
  
! 		  if (reg_pref)
  		    alt_cost
! 		      += (may_move_in_cost[(unsigned char) reg_pref[REGNO (op)].prefclass]
! 			  [(int) classes[i]]);
  
  		  if (REGNO (ops[i]) != REGNO (ops[j])
  		      && ! find_reg_note (insn, REG_DEAD, op))
--- 1327,1354 ----
  		  /* If we have assigned a class to this register in our
  		     first pass, add a cost to this alternative corresponding
  		     to what we would add if this register were not in the
! 		     appropriate class.
  
! 		     In the case preferred class is superset of our class, we
! 		     can't decide whether move will happen or not, since we don't
! 		     know if the register will end up in our class or not.
! 		     In this case be optimistic, the preferred class was probably
! 		     choosen so because insn has another alternative that allows it.
! 		     In case this alternative is no longer cheap, we will add
! 		     the cost while processing it.  */
! 
! 		  if (reg_pref
! 		      && !reg_classes_intersect_p (classes[i],
! 					       reg_pref[REGNO (op)]. prefclass))
  		    alt_cost
! 		      += ((recog_data.operand_type[i] != OP_OUT
! 			  ? (may_move_in_cost[(unsigned char) reg_pref[REGNO (op)].prefclass]
! 			     [(int) classes[i]])
! 			  : 0)
! 			 + (recog_data.operand_type[i] != OP_IN
! 			    ? (may_move_out_cost[(int) classes[i]]
! 			       [(unsigned char) reg_pref[REGNO (op)].prefclass])
! 			    : 0));
  
  		  if (REGNO (ops[i]) != REGNO (ops[j])
  		      && ! find_reg_note (insn, REG_DEAD, op))
*************** record_reg_classes (n_alts, n_ops, ops, 
*** 1553,1564 ****
  		  /* If we have assigned a class to this register in our
  		     first pass, add a cost to this alternative corresponding
  		     to what we would add if this register were not in the
! 		     appropriate class.  */
  
! 		  if (reg_pref)
  		    alt_cost
! 		      += (may_move_in_cost[(unsigned char) reg_pref[REGNO (op)].prefclass]
! 			  [(int) classes[i]]);
  		}
  	    }
  
--- 1570,1597 ----
  		  /* If we have assigned a class to this register in our
  		     first pass, add a cost to this alternative corresponding
  		     to what we would add if this register were not in the
! 		     appropriate class.
  
! 		     In the case preferred class is superset of our class, we
! 		     can't decide whether move will happen or not, since we don't
! 		     know if the register will end up in our class or not.
! 		     In this case be optimistic, the preferred class was probably
! 		     choosen so because insn has another alternative that allows it.
! 		     In case this alternative is no longer cheap, we will add
! 		     the cost while processing it.  */
! 
! 		  if (reg_pref
! 		      && !reg_classes_intersect_p (classes[i],
! 					       reg_pref[REGNO (op)]. prefclass))
  		    alt_cost
! 		      += ((recog_data.operand_type[i] != OP_OUT
! 			  ? (may_move_in_cost[(unsigned char) reg_pref[REGNO (op)].prefclass]
! 			     [(int) classes[i]])
! 			  : 0)
! 			 + (recog_data.operand_type[i] != OP_IN
! 			    ? (may_move_out_cost[(int) classes[i]]
! 			       [(unsigned char) reg_pref[REGNO (op)].prefclass])
! 			    : 0));
  		}
  	    }
  
*** i386.md.nopref	Fri Dec 31 12:11:25 1999
--- i386.md	Fri Dec 31 12:19:09 1999
***************
*** 1696,1702 ****
  
  (define_insn "*pushsf"
    [(set (match_operand:SF 0 "push_operand" "=<,<")
! 	(match_operand:SF 1 "general_operand" "f#r,rFm#f"))]
    ""
    "*
  {
--- 1696,1702 ----
  
  (define_insn "*pushsf"
    [(set (match_operand:SF 0 "push_operand" "=<,<")
! 	(match_operand:SF 1 "general_operand" "f,rFm"))]
    ""
    "*
  {
***************
*** 1742,1749 ****
     (set (mem:SF (reg:SI 7)) (match_dup 1))])
  
  (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
--- 1742,1749 ----
     (set (mem:SF (reg:SI 7)) (match_dup 1))])
  
  (define_insn "*movsf_1"
!   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,f,r,m")
! 	(match_operand:SF 1 "general_operand" "fm,f,G#F,rmF,Fr"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && (reload_in_progress || reload_completed
         || GET_CODE (operands[1]) != CONST_DOUBLE
***************
*** 1830,1836 ****
  
  (define_insn "*pushdf"
    [(set (match_operand:DF 0 "push_operand" "=<,<")
! 	(match_operand:DF 1 "general_operand" "f#r,rFo#f"))]
    ""
    "*
  {
--- 1830,1836 ----
  
  (define_insn "*pushdf"
    [(set (match_operand:DF 0 "push_operand" "=<,<")
! 	(match_operand:DF 1 "general_operand" "f,rFo"))]
    ""
    "*
  {
***************
*** 1923,1930 ****
    [(set_attr "type" "fmov,fmov,fmov,multi,multi")])
  
  (define_insn "*movdf_integer"
!   [(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
--- 1923,1930 ----
    [(set_attr "type" "fmov,fmov,fmov,multi,multi")])
  
  (define_insn "*movdf_integer"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,f,r,o")
! 	(match_operand:DF 1 "general_operand" "fm,f,G#F,roF,Fr"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && !optimize_size
     && (reload_in_progress || reload_completed
***************
*** 2054,2060 ****
  
  (define_insn "*pushxf_integer"
    [(set (match_operand:XF 0 "push_operand" "=<,<")
! 	(match_operand:XF 1 "general_operand" "f#r,rFo#f"))]
    "!optimize_size"
    "*
  {
--- 2054,2060 ----
  
  (define_insn "*pushxf_integer"
    [(set (match_operand:XF 0 "push_operand" "=<,<")
! 	(match_operand:XF 1 "general_operand" "f,rFo"))]
    "!optimize_size"
    "*
  {
***************
*** 2142,2149 ****
    [(set_attr "type" "fmov,fmov,fmov,multi,multi")])
  
  (define_insn "*movxf_integer"
!   [(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
--- 2142,2149 ----
    [(set_attr "type" "fmov,fmov,fmov,multi,multi")])
  
  (define_insn "*movxf_integer"
!   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
! 	(match_operand:XF 1 "general_operand" "fm,f,G#F,roF,Fr"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && !optimize_size
     && (reload_in_progress || reload_completed
***************
*** 5106,5112 ****
  ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
  ;; to itself.
  (define_insn "*negsf2_if"
!   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
  	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
     (clobber (reg:CC 17))]
    "TARGET_80387 && ix86_unary_operator_ok (NEG, SFmode, operands)"
--- 5106,5112 ----
  ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
  ;; to itself.
  (define_insn "*negsf2_if"
!   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
  	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
     (clobber (reg:CC 17))]
    "TARGET_80387 && ix86_unary_operator_ok (NEG, SFmode, operands)"
***************
*** 5161,5167 ****
  ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
  ;; to itself.
  (define_insn "*negdf2_if"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
  	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
     (clobber (reg:CC 17))]
    "TARGET_80387 && ix86_unary_operator_ok (NEG, DFmode, operands)"
--- 5161,5167 ----
  ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
  ;; to itself.
  (define_insn "*negdf2_if"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
  	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
     (clobber (reg:CC 17))]
    "TARGET_80387 && ix86_unary_operator_ok (NEG, DFmode, operands)"
***************
*** 5197,5203 ****
  ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
  ;; to itself.
  (define_insn "*negxf2_if"
!   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
  	(neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
     (clobber (reg:CC 17))]
    "TARGET_80387 && ix86_unary_operator_ok (NEG, XFmode, operands)"
--- 5197,5203 ----
  ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
  ;; to itself.
  (define_insn "*negxf2_if"
!   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,rm")
  	(neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
     (clobber (reg:CC 17))]
    "TARGET_80387 && ix86_unary_operator_ok (NEG, XFmode, operands)"
***************
*** 5289,5295 ****
  ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
  ;; to itself.
  (define_insn "*abssf2_if"
!   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
  	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
     (clobber (reg:CC 17))]
    "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands)"
--- 5289,5295 ----
  ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
  ;; to itself.
  (define_insn "*abssf2_if"
!   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
  	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
     (clobber (reg:CC 17))]
    "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands)"
***************
*** 5344,5350 ****
  ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
  ;; to itself.
  (define_insn "*absdf2_if"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
  	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
     (clobber (reg:CC 17))]
    "TARGET_80387 && ix86_unary_operator_ok (ABS, DFmode, operands)"
--- 5344,5350 ----
  ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
  ;; to itself.
  (define_insn "*absdf2_if"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
  	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
     (clobber (reg:CC 17))]
    "TARGET_80387 && ix86_unary_operator_ok (ABS, DFmode, operands)"
***************
*** 5380,5386 ****
  ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
  ;; to itself.
  (define_insn "*absxf2_if"
!   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
  	(abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
     (clobber (reg:CC 17))]
    "TARGET_80387 && ix86_unary_operator_ok (ABS, XFmode, operands)"
--- 5380,5386 ----
  ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
  ;; to itself.
  (define_insn "*absxf2_if"
!   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,rm")
  	(abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
     (clobber (reg:CC 17))]
    "TARGET_80387 && ix86_unary_operator_ok (ABS, XFmode, operands)"


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