This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Speedup CSE by 5%
- From: Arend Bayer <arend dot bayer at web dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 16 Jan 2005 23:22:28 +0100 (CET)
- Subject: 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,