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]

Re: Trim down memory usage in alias.c


> On Tue, Jan 20, 2004 at 09:39:21PM +0100, Jan Hubicka wrote:
> > + static unsigned int old_reg_base_value_size;
> [...]
> > !       reg_base_value_size = old_reg_base_value_size;
> > !       if (reg_base_value_size > maxreg * 2)
> > ! 	reg_base_value_size = maxreg * 2;
> [...]
> > +   old_reg_base_value_size = reg_base_value_size;
> 
> Better than this, which crops the known size of the old array,
> would be to use ggc_get_size when looking to reuse the old array.

Hi,
here is updated patch, it uses the varray and scales other arrays down.
It has passed bootstrap now, gc,gcac bootstrap is scheduled overnight.
OK assuming it passes?

The savings are slightly higher (about 750Kb of varray overhead now)

Honza

	* alias.c (reg_base_value): Turn into varray.
	(reg_base_value_size): Kill.
	(old_reg_base_value): New deletable varray.
	(alias_invariant_size): New variable.
	(REG_BASE_VALUE): Update to use varray.
	(find_base_value): Likewise.
	(record_set): Likewise.
	(record_base_value): Likewise.
	(memrefs_conflict_p): Likewise.
	(record_set): Likewise
	(record_base_value): Likewise.
	(memrefs_conflict_p): Use alias_invariant_size.
	(init_alias_analysis): Use varray; set alias_invariant_size;
	rescale other arrays to be sized by maxreg.
	(end_alias_analysis): Save reg_base_value; clear alias_invariant_size.
Index: alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/alias.c,v
retrieving revision 1.210
diff -c -3 -p -r1.210 alias.c
*** alias.c	17 Jan 2004 09:31:29 -0000	1.210
--- alias.c	20 Jan 2004 23:14:53 -0000
*************** static void memory_modified_1 (rtx, rtx,
*** 157,173 ****
     current function performs nonlocal memory memory references for the
     purposes of marking the function as a constant function.  */
  
! static GTY((length ("reg_base_value_size"))) rtx *reg_base_value;
  static rtx *new_reg_base_value;
! static unsigned int reg_base_value_size; /* size of reg_base_value array */
  
  /* Static hunks of RTL used by the aliasing code; these are initialized
     once per function to avoid unnecessary RTL allocations.  */
  static GTY (()) rtx static_reg_base_value[FIRST_PSEUDO_REGISTER];
  
  #define REG_BASE_VALUE(X) \
!   (REGNO (X) < reg_base_value_size \
!    ? reg_base_value[REGNO (X)] : 0)
  
  /* Vector of known invariant relationships between registers.  Set in
     loop unrolling.  Indexed by register number, if nonzero the value
--- 157,177 ----
     current function performs nonlocal memory memory references for the
     purposes of marking the function as a constant function.  */
  
! static GTY(()) varray_type reg_base_value;
  static rtx *new_reg_base_value;
! 
! /* We preserve the copy of old array around to avoid amount of garbage
!    produced.  About 8% of garbage produced were attributed to this
!    array.  */
! static GTY((deletable (""))) varray_type old_reg_base_value;
  
  /* Static hunks of RTL used by the aliasing code; these are initialized
     once per function to avoid unnecessary RTL allocations.  */
  static GTY (()) rtx static_reg_base_value[FIRST_PSEUDO_REGISTER];
  
  #define REG_BASE_VALUE(X) \
!   (reg_base_value && REGNO (X) < VARRAY_SIZE (reg_base_value) \
!    ? VARRAY_RTX (reg_base_value, REGNO (X)) : 0)
  
  /* Vector of known invariant relationships between registers.  Set in
     loop unrolling.  Indexed by register number, if nonzero the value
*************** static GTY (()) rtx static_reg_base_valu
*** 178,183 ****
--- 182,188 ----
     Because this array contains only pseudo registers it has no effect
     after reload.  */
  static rtx *alias_invariant;
+ unsigned int alias_invariant_size;
  
  /* Vector indexed by N giving the initial (unchanging) value known for
     pseudo-register N.  This array is initialized in
*************** find_base_value (rtx src)
*** 778,784 ****
  	 The test above is not sufficient because the scheduler may move
  	 a copy out of an arg reg past the NOTE_INSN_FUNCTION_BEGIN.  */
        if ((regno >= FIRST_PSEUDO_REGISTER || fixed_regs[regno])
! 	  && regno < reg_base_value_size)
  	{
  	  /* If we're inside init_alias_analysis, use new_reg_base_value
  	     to reduce the number of relaxation iterations.  */
--- 783,789 ----
  	 The test above is not sufficient because the scheduler may move
  	 a copy out of an arg reg past the NOTE_INSN_FUNCTION_BEGIN.  */
        if ((regno >= FIRST_PSEUDO_REGISTER || fixed_regs[regno])
! 	  && regno < VARRAY_SIZE (reg_base_value))
  	{
  	  /* If we're inside init_alias_analysis, use new_reg_base_value
  	     to reduce the number of relaxation iterations.  */
*************** find_base_value (rtx src)
*** 786,793 ****
  	      && REG_N_SETS (regno) == 1)
  	    return new_reg_base_value[regno];
  
! 	  if (reg_base_value[regno])
! 	    return reg_base_value[regno];
  	}
  
        return 0;
--- 791,798 ----
  	      && REG_N_SETS (regno) == 1)
  	    return new_reg_base_value[regno];
  
! 	  if (VARRAY_RTX (reg_base_value, regno))
! 	    return VARRAY_RTX (reg_base_value, regno);
  	}
  
        return 0;
*************** record_set (rtx dest, rtx set, void *dat
*** 931,937 ****
  
    regno = REGNO (dest);
  
!   if (regno >= reg_base_value_size)
      abort ();
  
    /* If this spans multiple hard registers, then we must indicate that every
--- 936,942 ----
  
    regno = REGNO (dest);
  
!   if (regno >= VARRAY_SIZE (reg_base_value))
      abort ();
  
    /* If this spans multiple hard registers, then we must indicate that every
*************** record_set (rtx dest, rtx set, void *dat
*** 1030,1050 ****
  void
  record_base_value (unsigned int regno, rtx val, int invariant)
  {
!   if (regno >= reg_base_value_size)
!     return;
! 
!   if (invariant && alias_invariant)
      alias_invariant[regno] = val;
  
    if (GET_CODE (val) == REG)
      {
!       if (REGNO (val) < reg_base_value_size)
! 	reg_base_value[regno] = reg_base_value[REGNO (val)];
! 
        return;
      }
! 
!   reg_base_value[regno] = find_base_value (val);
  }
  
  /* Clear alias info for a register.  This is used if an RTL transformation
--- 1035,1054 ----
  void
  record_base_value (unsigned int regno, rtx val, int invariant)
  {
!   if (invariant && alias_invariant && regno < alias_invariant_size)
      alias_invariant[regno] = val;
  
+   if (regno >= VARRAY_SIZE (reg_base_value))
+     VARRAY_GROW (reg_base_value, max_reg_num ());
+ 
    if (GET_CODE (val) == REG)
      {
!       VARRAY_RTX (reg_base_value, regno)
! 	 = REG_BASE_VALUE (val);
        return;
      }
!   VARRAY_RTX (reg_base_value, regno)
!      = find_base_value (val);
  }
  
  /* Clear alias info for a register.  This is used if an RTL transformation
*************** memrefs_conflict_p (int xsize, rtx x, in
*** 1682,1689 ****
  	    unsigned int r_x = REGNO (x), r_y = REGNO (y);
  	    rtx i_x, i_y;	/* invariant relationships of X and Y */
  
! 	    i_x = r_x >= reg_base_value_size ? 0 : alias_invariant[r_x];
! 	    i_y = r_y >= reg_base_value_size ? 0 : alias_invariant[r_y];
  
  	    if (i_x == 0 && i_y == 0)
  	      break;
--- 1686,1693 ----
  	    unsigned int r_x = REGNO (x), r_y = REGNO (y);
  	    rtx i_x, i_y;	/* invariant relationships of X and Y */
  
! 	    i_x = r_x >= alias_invariant_size ? 0 : alias_invariant[r_x];
! 	    i_y = r_y >= alias_invariant_size ? 0 : alias_invariant[r_y];
  
  	    if (i_x == 0 && i_y == 0)
  	      break;
*************** memory_modified_in_insn_p (rtx mem, rtx 
*** 2710,2716 ****
  void
  init_alias_analysis (void)
  {
!   int maxreg = max_reg_num ();
    int changed, pass;
    int i;
    unsigned int ui;
--- 2714,2720 ----
  void
  init_alias_analysis (void)
  {
!   unsigned int maxreg = max_reg_num ();
    int changed, pass;
    int i;
    unsigned int ui;
*************** init_alias_analysis (void)
*** 2730,2746 ****
    /* Overallocate reg_base_value to allow some growth during loop
       optimization.  Loop unrolling can create a large number of
       registers.  */
!   reg_base_value_size = maxreg * 2;
!   reg_base_value = ggc_alloc_cleared (reg_base_value_size * sizeof (rtx));
  
!   new_reg_base_value = xmalloc (reg_base_value_size * sizeof (rtx));
!   reg_seen = xmalloc (reg_base_value_size);
    if (! reload_completed && flag_old_unroll_loops)
      {
        /* ??? Why are we realloc'ing if we're just going to zero it?  */
        alias_invariant = xrealloc (alias_invariant,
! 				  reg_base_value_size * sizeof (rtx));
!       memset (alias_invariant, 0, reg_base_value_size * sizeof (rtx));
      }
  
    /* The basic idea is that each pass through this loop will use the
--- 2734,2764 ----
    /* Overallocate reg_base_value to allow some growth during loop
       optimization.  Loop unrolling can create a large number of
       registers.  */
!   if (old_reg_base_value)
!     {
!       reg_base_value = old_reg_base_value;
!       /* If varray gets large zeroing cost may get important.  */
!       if (VARRAY_SIZE (reg_base_value) > 256
!           && VARRAY_SIZE (reg_base_value) > 4 * maxreg)
! 	VARRAY_GROW (reg_base_value, maxreg);
!       VARRAY_CLEAR (reg_base_value);
!       if (VARRAY_SIZE (reg_base_value) < maxreg)
! 	VARRAY_GROW (reg_base_value, maxreg);
!     }
!   else
!     {
!       VARRAY_RTX_INIT (reg_base_value, maxreg, "reg_base_value");
!     }
  
!   new_reg_base_value = xmalloc (maxreg * sizeof (rtx));
!   reg_seen = xmalloc (maxreg);
    if (! reload_completed && flag_old_unroll_loops)
      {
        /* ??? Why are we realloc'ing if we're just going to zero it?  */
        alias_invariant = xrealloc (alias_invariant,
! 				  maxreg * sizeof (rtx));
!       memset (alias_invariant, 0, maxreg * sizeof (rtx));
!       alias_invariant_size = maxreg;
      }
  
    /* The basic idea is that each pass through this loop will use the
*************** init_alias_analysis (void)
*** 2777,2786 ****
        copying_arguments = true;
  
        /* Wipe the potential alias information clean for this pass.  */
!       memset (new_reg_base_value, 0, reg_base_value_size * sizeof (rtx));
  
        /* Wipe the reg_seen array clean.  */
!       memset (reg_seen, 0, reg_base_value_size);
  
        /* Mark all hard registers which may contain an address.
  	 The stack, frame and argument pointers may contain an address.
--- 2795,2804 ----
        copying_arguments = true;
  
        /* Wipe the potential alias information clean for this pass.  */
!       memset (new_reg_base_value, 0, maxreg * sizeof (rtx));
  
        /* Wipe the reg_seen array clean.  */
!       memset (reg_seen, 0, maxreg);
  
        /* Mark all hard registers which may contain an address.
  	 The stack, frame and argument pointers may contain an address.
*************** init_alias_analysis (void)
*** 2868,2880 ****
  	}
  
        /* Now propagate values from new_reg_base_value to reg_base_value.  */
!       for (ui = 0; ui < reg_base_value_size; ui++)
  	{
  	  if (new_reg_base_value[ui]
! 	      && new_reg_base_value[ui] != reg_base_value[ui]
! 	      && ! rtx_equal_p (new_reg_base_value[ui], reg_base_value[ui]))
  	    {
! 	      reg_base_value[ui] = new_reg_base_value[ui];
  	      changed = 1;
  	    }
  	}
--- 2886,2901 ----
  	}
  
        /* Now propagate values from new_reg_base_value to reg_base_value.  */
!       if (maxreg != (unsigned int) max_reg_num())
! 	abort ();
!       for (ui = 0; ui < maxreg; ui++)
  	{
  	  if (new_reg_base_value[ui]
! 	      && new_reg_base_value[ui] != VARRAY_RTX (reg_base_value, ui)
! 	      && ! rtx_equal_p (new_reg_base_value[ui],
! 				VARRAY_RTX (reg_base_value, ui)))
  	    {
! 	      VARRAY_RTX (reg_base_value, ui) = new_reg_base_value[ui];
  	      changed = 1;
  	    }
  	}
*************** init_alias_analysis (void)
*** 2882,2888 ****
    while (changed && ++pass < MAX_ALIAS_LOOP_PASSES);
  
    /* Fill in the remaining entries.  */
!   for (i = FIRST_PSEUDO_REGISTER; i < maxreg; i++)
      if (reg_known_value[i] == 0)
        reg_known_value[i] = regno_reg_rtx[i];
  
--- 2903,2909 ----
    while (changed && ++pass < MAX_ALIAS_LOOP_PASSES);
  
    /* Fill in the remaining entries.  */
!   for (i = FIRST_PSEUDO_REGISTER; i < (int)maxreg; i++)
      if (reg_known_value[i] == 0)
        reg_known_value[i] = regno_reg_rtx[i];
  
*************** init_alias_analysis (void)
*** 2901,2916 ****
      {
        changed = 0;
        pass++;
!       for (ui = 0; ui < reg_base_value_size; ui++)
  	{
! 	  rtx base = reg_base_value[ui];
  	  if (base && GET_CODE (base) == REG)
  	    {
  	      unsigned int base_regno = REGNO (base);
  	      if (base_regno == ui)		/* register set from itself */
! 		reg_base_value[ui] = 0;
  	      else
! 		reg_base_value[ui] = reg_base_value[base_regno];
  	      changed = 1;
  	    }
  	}
--- 2922,2938 ----
      {
        changed = 0;
        pass++;
!       for (ui = 0; ui < maxreg; ui++)
  	{
! 	  rtx base = VARRAY_RTX (reg_base_value, ui);
  	  if (base && GET_CODE (base) == REG)
  	    {
  	      unsigned int base_regno = REGNO (base);
  	      if (base_regno == ui)		/* register set from itself */
! 		VARRAY_RTX (reg_base_value, ui) = 0;
  	      else
! 		VARRAY_RTX (reg_base_value, ui)
! 		  = VARRAY_RTX (reg_base_value, base_regno);
  	      changed = 1;
  	    }
  	}
*************** init_alias_analysis (void)
*** 2928,2944 ****
  void
  end_alias_analysis (void)
  {
    free (reg_known_value + FIRST_PSEUDO_REGISTER);
    reg_known_value = 0;
    reg_known_value_size = 0;
    free (reg_known_equiv_p + FIRST_PSEUDO_REGISTER);
    reg_known_equiv_p = 0;
-   reg_base_value = 0;
-   reg_base_value_size = 0;
    if (alias_invariant)
      {
        free (alias_invariant);
        alias_invariant = 0;
      }
  }
  
--- 2950,2966 ----
  void
  end_alias_analysis (void)
  {
+   old_reg_base_value = reg_base_value;
    free (reg_known_value + FIRST_PSEUDO_REGISTER);
    reg_known_value = 0;
    reg_known_value_size = 0;
    free (reg_known_equiv_p + FIRST_PSEUDO_REGISTER);
    reg_known_equiv_p = 0;
    if (alias_invariant)
      {
        free (alias_invariant);
        alias_invariant = 0;
+       alias_invariant_size = 0;
      }
  }
  


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