PATCH for global.c
Mark Mitchell
mark@markmitchell.com
Fri Dec 11 10:37:00 GMT 1998
Here's a patch for a bug which took me quite some time to track down.
I've got a very large function (> 10^6 instructions, about a quarter
of a million REGs). In global_conflicts, we have:
block_start_allocnos = (short *) alloca (max_allocno * sizeof (short));
...
EXECUTE_IF_SET_IN_REG_SET (old, FIRST_PSEUDO_REGISTER, i,
{
register int a = reg_allocno[i];
if (a >= 0)
{
SET_ALLOCNO_LIVE (a);
block_start_allocnos[ax++] = a;
}
else if ((a = reg_renumber[i]) >= 0)
mark_reg_live_nc
(a, PSEUDO_REGNO_MODE (i));
});
Notice that reg_allocno values (ints) are being stored in
block_start_allocnos (shorts). I guess this was an attempt to save
memory, but not very much and only for the duration of
record_conflicts. You can guess what happenned: reg_allocno[i] was
about 33,000 in one case, which looks like a negative short, which
caused a lot of chaso when the value was used later:
record_conflicts (allocno_vec, len)
register short *allocno_vec;
...
{
allocno = allocno_vec[len];
...
IOR_HARD_REG_SET (hard_reg_conflicts[allocno], hard_regs_live);
}
Here's the obvious patch. Jeff, OK? And, let's not assume that
*anything* fits in a short; it's quite easy to get 65,000 of just
about anything. Getting 2^32 of them is much, much harder. :-)
--
Mark Mitchell mark@markmitchell.com
Mark Mitchell Consulting http://www.markmitchell.com
Fri Dec 11 10:32:38 1998 Mark Mitchell <mark@markmitchell.com>
* global.c (record_conflicts): Don't use an array of shorts to
store an array of ints.
(global_conflicts): Likewise.
Index: global.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/global.c,v
retrieving revision 1.20
diff -c -p -r1.20 global.c
*** global.c 1998/10/14 09:02:38 1.20
--- global.c 1998/12/11 18:26:41
*************** static void expand_preferences PROTO((vo
*** 261,267 ****
static void prune_preferences PROTO((void));
static void find_reg PROTO((int, HARD_REG_SET, int, int, int));
static void record_one_conflict PROTO((int));
! static void record_conflicts PROTO((short *, int));
static void mark_reg_store PROTO((rtx, rtx));
static void mark_reg_clobber PROTO((rtx, rtx));
static void mark_reg_conflicts PROTO((rtx));
--- 261,267 ----
static void prune_preferences PROTO((void));
static void find_reg PROTO((int, HARD_REG_SET, int, int, int));
static void record_one_conflict PROTO((int));
! static void record_conflicts PROTO((int *, int));
static void mark_reg_store PROTO((rtx, rtx));
static void mark_reg_clobber PROTO((rtx, rtx));
static void mark_reg_conflicts PROTO((rtx));
*************** global_conflicts ()
*** 623,634 ****
{
register int b, i;
register rtx insn;
! short *block_start_allocnos;
/* Make a vector that mark_reg_{store,clobber} will store in. */
regs_set = (rtx *) alloca (max_parallel * sizeof (rtx) * 2);
! block_start_allocnos = (short *) alloca (max_allocno * sizeof (short));
for (b = 0; b < n_basic_blocks; b++)
{
--- 623,634 ----
{
register int b, i;
register rtx insn;
! int *block_start_allocnos;
/* Make a vector that mark_reg_{store,clobber} will store in. */
regs_set = (rtx *) alloca (max_parallel * sizeof (rtx) * 2);
! block_start_allocnos = (int *) alloca (max_allocno * sizeof (int));
for (b = 0; b < n_basic_blocks; b++)
{
*************** record_one_conflict (regno)
*** 1291,1297 ****
static void
record_conflicts (allocno_vec, len)
! register short *allocno_vec;
register int len;
{
register int allocno;
--- 1291,1297 ----
static void
record_conflicts (allocno_vec, len)
! register int *allocno_vec;
register int len;
{
register int allocno;
More information about the Gcc-patches
mailing list