regclass compilation time

Jan Hubicka jh@suse.cz
Sun Feb 11 08:33:00 GMT 2001


Hi
Following patch:

2001-01-01  Alexandre Oliva  <aoliva@redhat.com>

	* tm.texi (REGISTER_MOVE_COST): Add a mode argument.
	* reload.c (REGISTER_MOVE_COST): Likewise.  Adjust all callers.
	* reload1.c (REGISTER_MOVE_COST): Likewise.
	* regclass.c (REGISTER_MOVE_COST): Likewise.
	(move_cost, may_move_in_cost, may_move_out_cost): Add mode
	dimension.  Adjust all users.
	(init_reg_sets_1): Iterate on all modes.
	* config/1750a/1750a.h (REGISTER_MOVE_COST): Adjust.
	* config/a29k/a29k.h (REGISTER_MOVE_COST): Adjust.
	* config/alpha/alpha.h (REGISTER_MOVE_COST): Adjust.
	* config/arc/arc.h (REGISTER_MOVE_COST): Adjust.
	* config/arm/arm.h (REGISTER_MOVE_COST): Adjust.
	* config/avr/avr.h (REGISTER_MOVE_COST): Adjust.
	* config/c4x/c4x.h (REGISTER_MOVE_COST): Adjust.
	* config/d30v/d30v.h (REGISTER_MOVE_COST): Adjust.
	* config/dsp16xx/dsp16xx.h (REGISTER_MOVE_COST): Adjust.
	* config/h8300/h8300.h (REGISTER_MOVE_COST): Adjust.
	* config/i386/i386.h (REGISTER_MOVE_COST): Adjust.
	* config/ia64/ia64.h (REGISTER_MOVE_COST): Adjust.
	* config/m32r/m32r.h (REGISTER_MOVE_COST): Adjust.
	* config/m68hc11/m68hc11.h (REGISTER_MOVE_COST): Adjust.
	* config/m68k/m68k.h (REGISTER_MOVE_COST): Adjust.
	* config/mcore/mcore.h (REGISTER_MOVE_COST): Adjust.
	* config/mips/mips.h (REGISTER_MOVE_COST): Adjust.
	* config/mn10200/mn10200.h (REGISTER_MOVE_COST): Adjust.
	* config/mn10300/mn10300.h (REGISTER_MOVE_COST): Adjust.
	* config/ns32k/ns32k.h (REGISTER_MOVE_COST): Adjust.
	* config/pa/pa.h (REGISTER_MOVE_COST): Adjust.
	* config/pdp11/pdp11.h (REGISTER_MOVE_COST): Adjust.
	* config/pj/pj.h (REGISTER_MOVE_COST): Adjust.
	* config/romp/romp.h (REGISTER_MOVE_COST): Adjust.
	* config/rs6000/rs6000.h (REGISTER_MOVE_COST): Adjust.
	* config/sh/sh.h (REGISTER_MOVE_COST): Adjust.
	* config/sparc/sparc.h (REGISTER_MOVE_COST): Adjust.

has introduced performance problems on i386.  We have many classes and many
modes and the init_reg_sets_1 is doing loop with complexity

N_MODES * N_REG_CLASSES^4

This makes gcc to initialize over 0.7 seconds on my athlon box compares to 0.02
of gcc 2.95. This slows down compilation of many small files considerably and
I've hit badly this limit in my SSE code where I added next 4 register classes
increasing inicialization time to over 4 seconds.

This patch optimizes the initialization loop in two ways - first it works out
what classes contains some register of given mode and avoids the internal loop
in cases it is just nonsense and it cuts the complexity to N_MODES *
N_REG_CLASSES^3 by re-using of actually computed valies.

The startup time is now about 0.06 seconds.  I would also like to reduce the
arrays by allocating just for modes that do support some register, but I would
like to handle this by separate patch.

Honza

Sun Feb 11 17:31:53 CET 2001  Jan Hubicka  <jh@suse.cz>

	* regclass.c (init_reg_sets_1): Optimize calculation of move_cost arrays.

*** regclass.c.old	Fri Jan 12 04:30:14 2001
--- regclass.c	Fri Jan 12 05:58:26 2001
*************** init_reg_sets_1 ()
*** 288,293 ****
--- 288,295 ----
  {
    register unsigned int i, j;
    register unsigned int /* enum machine_mode */ m;
+   char contains_reg_of_mode [LIM_REG_CLASSES] [MAX_MACHINE_MODE];
+   char allocatable_regs_of_mode [MAX_MACHINE_MODE];
  
    /* This macro allows the fixed or call-used registers
       and the register classes to depend on target flags.  */
*************** init_reg_sets_1 ()
*** 423,466 ****
        if (CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (i)))
  	SET_HARD_REG_BIT (losing_caller_save_reg_set, i);
      }
  
    /* Initialize the move cost table.  Find every subset of each class
       and take the maximum cost of moving any subset to any other.  */
  
    for (m = 0; m < MAX_MACHINE_MODE; m++)
!     for (i = 0; i < N_REG_CLASSES; i++)
!       for (j = 0; j < N_REG_CLASSES; j++)
! 	{
! 	  int cost = i == j ? 2 : REGISTER_MOVE_COST (m, i, j);
! 	  enum reg_class *p1, *p2;
! 
! 	  for (p2 = &reg_class_subclasses[j][0]; *p2 != LIM_REG_CLASSES; p2++)
! 	    if (*p2 != i)
! 	      cost = MAX (cost, REGISTER_MOVE_COST (m, i, *p2));
! 
! 	  for (p1 = &reg_class_subclasses[i][0]; *p1 != LIM_REG_CLASSES; p1++)
  	    {
! 	      if (*p1 != j)
! 		cost = MAX (cost, REGISTER_MOVE_COST (m, *p1, j));
  
! 	      for (p2 = &reg_class_subclasses[j][0];
! 		   *p2 != LIM_REG_CLASSES; p2++)
! 		if (*p1 != *p2)
! 		  cost = MAX (cost, REGISTER_MOVE_COST (m, *p1, *p2));
  	    }
- 
- 	  move_cost[m][i][j] = cost;
- 
- 	  if (reg_class_subset_p (i, j))
- 	    may_move_in_cost[m][i][j] = 0;
- 	  else
- 	    may_move_in_cost[m][i][j] = cost;
- 
- 	  if (reg_class_subset_p (j, i))
- 	    may_move_out_cost[m][i][j] = 0;
- 	  else
- 	    may_move_out_cost[m][i][j] = cost;
- 	}
  
  #ifdef CLASS_CANNOT_CHANGE_MODE
    {
--- 425,495 ----
        if (CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (i)))
  	SET_HARD_REG_BIT (losing_caller_save_reg_set, i);
      }
+   memset (contains_reg_of_mode, 0, sizeof (contains_reg_of_mode));
+   memset (allocatable_regs_of_mode, 0, sizeof (allocatable_regs_of_mode));
+   for (m = 0; m < MAX_MACHINE_MODE; m++)
+     for (i = 0; i < N_REG_CLASSES; i++)
+       for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
+ 	if (!fixed_regs [j] && TEST_HARD_REG_BIT (reg_class_contents[i], j)
+ 	    && HARD_REGNO_MODE_OK (j, m))
+ 	   {
+ 	     contains_reg_of_mode [i][m] = 1;
+ 	     allocatable_regs_of_mode [m] = 1;
+ 	     break;
+ 	   }
  
    /* Initialize the move cost table.  Find every subset of each class
       and take the maximum cost of moving any subset to any other.  */
  
    for (m = 0; m < MAX_MACHINE_MODE; m++)
!     if (allocatable_regs_of_mode [m])
!       for (i = 0; i < N_REG_CLASSES; i++)
! 	if (contains_reg_of_mode [i][m])
! 	  for (j = 0; j < N_REG_CLASSES; j++)
  	    {
! 	      int cost;
! 	      enum reg_class *p1, *p2;
  
! 	      if (!contains_reg_of_mode [j][m])
! 		{
! 		  move_cost[m][i][j] = 65536;
! 		  may_move_in_cost[m][i][j] = 65536;
! 		  may_move_out_cost[m][i][j] = 65536;
! 		}
! 	      else
! 		{
! 		  cost = i == j ? 2 : REGISTER_MOVE_COST (m, i, j);
! 
! 		  for (p2 = &reg_class_subclasses[j][0]; *p2 != LIM_REG_CLASSES;
! 		       p2++)
! 		    if (*p2 != i && contains_reg_of_mode [*p1][m])
! 		      cost = MAX (cost, move_cost [m][i][*p2]);
! 
! 		  for (p1 = &reg_class_subclasses[i][0]; *p1 != LIM_REG_CLASSES;
! 		       p1++)
! 		    if (*p1 != j && contains_reg_of_mode [*p1][m])
! 		      cost = MAX (cost, move_cost [m][*p1][j]);
! 
! 		  move_cost[m][i][j] = cost;
! 
! 		  if (reg_class_subset_p (i, j))
! 		    may_move_in_cost[m][i][j] = 0;
! 		  else
! 		    may_move_in_cost[m][i][j] = cost;
! 
! 		  if (reg_class_subset_p (j, i))
! 		    may_move_out_cost[m][i][j] = 0;
! 		  else
! 		    may_move_out_cost[m][i][j] = cost;
! 		}
! 	    }
! 	else
! 	  for (j = 0; j < N_REG_CLASSES; j++)
! 	    {
! 	      move_cost[m][i][j] = 65536;
! 	      may_move_in_cost[m][i][j] = 65536;
! 	      may_move_out_cost[m][i][j] = 65536;
  	    }
  
  #ifdef CLASS_CANNOT_CHANGE_MODE
    {



More information about the Gcc-patches mailing list