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