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]
Other format: [Raw text]

PowerPC register and memory cost update


	This patch fixes the register and memory cost calculations to be
more accurate, fixing a Java bootstrap failure caused by stupid register
allocation choices.

	The memory cost change affects performance -- both positive effect
and negative effect, depending on the testcase.  This could demonstrate
that the cost model requires more precision or that some other heuristic
in the compiler is wrong.  It needs more study.

David


        * config/rs6000/rs6000.c (rs6000_register_move_cost): New function.
        (rs6000_memory_move_cost): New function.
        * config/rs6000/rs6000-protos.h: Declare them.
        * config/rs6000/rs6000.h: Use them.

Index: rs6000-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000-protos.h,v
retrieving revision 1.46
diff -c -p -r1.46 rs6000-protos.h
*** rs6000-protos.h	22 Oct 2002 23:05:19 -0000	1.46
--- rs6000-protos.h	23 Oct 2002 15:08:41 -0000
*************** extern void rs6000_emit_epilogue PARAMS 
*** 188,193 ****
--- 188,197 ----
  extern void debug_stack_info PARAMS ((rs6000_stack_t *));
  extern const char *output_isel PARAMS ((rtx *));
  extern int vrsave_operation PARAMS ((rtx, enum machine_mode));
+ extern int rs6000_register_move_cost PARAMS ((enum machine_mode,
+ 					      enum reg_class, enum reg_class));
+ extern int rs6000_memory_move_cost PARAMS ((enum machine_mode,
+ 					    enum reg_class, int));
  
  /* Declare functions in rs6000-c.c */
  
Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.395
diff -c -p -r1.395 rs6000.c
*** rs6000.c	23 Oct 2002 05:22:41 -0000	1.395
--- rs6000.c	23 Oct 2002 15:08:42 -0000
*************** rs6000_binds_local_p (decl)
*** 13236,13238 ****
--- 13236,13296 ----
  {
    return default_binds_local_p_1 (decl, flag_pic || rs6000_flag_pic);
  }
+ 
+ /* A C expression returning the cost of moving data from a register of class
+    CLASS1 to one of CLASS2.  */
+ 
+ int
+ rs6000_register_move_cost (mode, from, to)
+      enum machine_mode mode;
+      enum reg_class from, to;
+ {
+   /*  Moves from/to GENERAL_REGS.  */
+   if (reg_classes_intersect_p (to, GENERAL_REGS)
+       || reg_classes_intersect_p (from, GENERAL_REGS))
+     {
+       if (! reg_classes_intersect_p (to, GENERAL_REGS))
+ 	from = to;
+ 
+       if (from == FLOAT_REGS || from == ALTIVEC_REGS)
+ 	return (rs6000_memory_move_cost (mode, from, 0)
+ 		+ rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
+ 
+ /* It's more expensive to move CR_REGS than CR0_REGS because of the shift...*/
+       else if (from == CR_REGS)
+ 	return 4;
+ 
+       else
+ /* A move will cost one instruction per GPR moved.  */
+ 	return 2 * HARD_REGNO_NREGS (0, mode);
+     }
+ 
+ /* Moving between two similar registers is just one instruction.  */
+   else if (reg_classes_intersect_p (to, from))
+     return mode == TFmode ? 4 : 2;
+ 
+ /* Everything else has to go through GENERAL_REGS.  */
+   else
+     return (rs6000_register_move_cost (mode, GENERAL_REGS, to) 
+ 	    + rs6000_register_move_cost (mode, from, GENERAL_REGS));
+ }
+ 
+ /* A C expressions returning the cost of moving data of MODE from a register to
+    or from memory.  */
+ 
+ int
+ rs6000_memory_move_cost (mode, class, in)
+   enum machine_mode mode;
+   enum reg_class class;
+   int in ATTRIBUTE_UNUSED;
+ {
+   if (reg_classes_intersect_p (class, GENERAL_REGS))
+     return 4 * HARD_REGNO_NREGS (0, mode);
+   else if (reg_classes_intersect_p (class, FLOAT_REGS))
+     return 4 * HARD_REGNO_NREGS (32, mode);
+   else if (reg_classes_intersect_p (class, ALTIVEC_REGS))
+     return 4 * HARD_REGNO_NREGS (FIRST_ALTIVEC_REGNO, mode);
+   else
+     return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
+ }
+ 
Index: rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.232
diff -c -p -r1.232 rs6000.h
*** rs6000.h	18 Oct 2002 00:30:23 -0000	1.232
--- rs6000.h	23 Oct 2002 15:08:42 -0000
*************** extern int rs6000_default_long_calls;
*** 926,960 ****
     : 1)
  
  /* A C expression returning the cost of moving data from a register of class
!    CLASS1 to one of CLASS2.
  
!    On the RS/6000, copying between floating-point and fixed-point
!    registers is expensive.  */
! 
! #define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2)		\
!    ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2	\
!    : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10	\
!    : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10	\
!    : (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20	\
!    : (CLASS1) != ALTIVEC_REGS && (CLASS2) == ALTIVEC_REGS ? 20	\
!    : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS		\
!        || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS		\
!        || (CLASS1) == LINK_OR_CTR_REGS)				\
!       && ((CLASS2) == SPECIAL_REGS || (CLASS2) == MQ_REGS	\
! 	  || (CLASS2) == LINK_REGS || (CLASS2) == CTR_REGS	\
! 	  || (CLASS2) == LINK_OR_CTR_REGS)) ? 10		\
!    : 2)
  
  /* A C expressions returning the cost of moving data of MODE from a register to
!    or from memory.
! 
!    On the RS/6000, bump this up a bit.  */
  
! #define MEMORY_MOVE_COST(MODE, CLASS, IN)	\
!   ((GET_MODE_CLASS (MODE) == MODE_FLOAT		\
!     && (rs6000_cpu == PROCESSOR_RIOS1 || rs6000_cpu == PROCESSOR_PPC601) \
!     ? 3 : 2) \
!    + 4)
  
  /* Specify the cost of a branch insn; roughly the number of extra insns that
     should be added to avoid a branch.
--- 926,939 ----
     : 1)
  
  /* A C expression returning the cost of moving data from a register of class
!    CLASS1 to one of CLASS2.  */
  
! #define REGISTER_MOVE_COST rs6000_register_move_cost
  
  /* A C expressions returning the cost of moving data of MODE from a register to
!    or from memory.  */
  
! #define MEMORY_MOVE_COST rs6000_memory_move_cost
  
  /* Specify the cost of a branch insn; roughly the number of extra insns that
     should be added to avoid a branch.


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