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]

Speedup CSE by 5%


This patch integrates approx_reg_cost() and approx_reg_cost_1() into one
function by not using for_each_rtx(): The overhead of the additional
function calls and some additional branches of the for_each_rtx()
construction turn out to be significant performance-wise. I don't think
the resulting code is less clear.

It consistently gives a speedup of a little more than 5% for the CSE
passes. This translates to about 0.3% for compiling a linux kernel, 0.5%
for my own project (GNU Go), and about 1% for lpgparse.i from PR 15678.

This is tested by a bootstrap and make check with no regressions on
i686-pc-linux-gnu with C,C++,f95,objc.

Arend

2005-01-16  Arend Bayer  <arend.bayer@web.de>
	* cse.c (approx_reg_cost_1): Remove by integrating it...
	(approx_reg_cost): ...and hand-inlining for_each_rtx here.


Index: gcc/cse.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cse.c,v
retrieving revision 1.329
diff -u -p -c -r1.329 cse.c
*** gcc/cse.c	5 Jan 2005 23:19:17 -0000	1.329
--- gcc/cse.c	16 Jan 2005 21:40:48 -0000
*************** struct cse_basic_block_data
*** 600,606 ****
  
  static bool fixed_base_plus_p (rtx x);
  static int notreg_cost (rtx, enum rtx_code);
- static int approx_reg_cost_1 (rtx *, void *);
  static int approx_reg_cost (rtx);
  static int preferable (int, int, int, int);
  static void new_basic_block (void);
--- 600,605 ----
*************** dump_class (struct table_elt *classp)
*** 717,764 ****
      }
  }
  
! /* Subroutine of approx_reg_cost; called through for_each_rtx.  */
  
  static int
! approx_reg_cost_1 (rtx *xp, void *data)
  {
!   rtx x = *xp;
!   int *cost_p = data;
  
!   if (x && REG_P (x))
      {
        unsigned int regno = REGNO (x);
  
!       if (! CHEAP_REGNO (regno))
  	{
! 	  if (regno < FIRST_PSEUDO_REGISTER)
! 	    {
! 	      if (SMALL_REGISTER_CLASSES)
! 		return 1;
! 	      *cost_p += 2;
! 	    }
! 	  else
! 	    *cost_p += 1;
  	}
      }
  
!   return 0;
! }
! 
! /* Return an estimate of the cost of the registers used in an rtx.
!    This is mostly the number of different REG expressions in the rtx;
!    however for some exceptions like fixed registers we use a cost of
!    0.  If any other hard register reference occurs, return MAX_COST.  */
! 
! static int
! approx_reg_cost (rtx x)
! {
!   int cost = 0;
! 
!   if (for_each_rtx (&x, approx_reg_cost_1, (void *) &cost))
!     return MAX_COST;
  
!   return cost;
  }
  
  /* Returns a canonical version of X for the address, from the point of view,
--- 716,774 ----
      }
  }
  
! 
! /* Return an estimate of the cost of the registers used in an rtx.
!    This is mostly the number of different REG expressions in the rtx;
!    however for some exceptions like fixed registers we use a cost of
!    0.  If any other hard register reference occurs, return MAX_COST.  */
  
  static int
! approx_reg_cost (rtx x)
  {
!   int total = 0;
!   int i, j;
!   enum rtx_code code;
!   const char *format;
  
!   if (x == 0)
!     return 0;
! 
!   code = GET_CODE (x);
!   if (REG_P (x))
      {
        unsigned int regno = REGNO (x);
  
!       if (CHEAP_REGNO (regno))
! 	return 0;
!       if (regno < FIRST_PSEUDO_REGISTER)
  	{
! 	  if (SMALL_REGISTER_CLASSES)
! 	    return MAX_COST;
! 	  return 2;
  	}
+       else
+ 	return 1;
      }
  
!   format = GET_RTX_FORMAT (code);
!   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
!     if (format[i] == 'e') 
!       {
! 	int this_cost = approx_reg_cost (XEXP (x, i));
! 	if (this_cost == MAX_COST)
! 	  return MAX_COST;
! 	total += this_cost;
!       }
!     else if (format[i] == 'E' || format[i] == 'V')
!       for (j = 0; j < XVECLEN (x, i); j++)
! 	{
! 	  int this_cost = approx_reg_cost (XVECEXP (x, i, j));
! 	  if (this_cost == MAX_COST)
! 	    return MAX_COST;
! 	  total += this_cost;
! 	}
  
!   return total;
  }
  
  /* Returns a canonical version of X for the address, from the point of view,


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