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]

fix alpha gc bootstrap problem


No idea why this is happening now, and apparently only to me, but
the fact is that data gets put into reg_known_value and a call to
ggc_collect happens before end_alias_analysis.  The call to collect
happens during CSE, and is protected by a ggc_push_context, but it
still doesn't seem terribly safe.

Bootstrapped on alphaev6-linux.


r~


        * alias.c (alias_invariant, alias_invariant_size): Mark GTY.
        (reg_known_value, reg_known_value_size): Likewise; make static.
        (reg_known_equiv_p): Make static.
        (clear_reg_alias_info): Update for new indexing.
        (get_reg_known_value, set_reg_known_value): New.
        (get_reg_known_equiv_p, set_reg_known_equiv_p): New.
        (canon_rtx): Use them. 
        (init_alias_analysis): Likewise.  Allocate reg_known_value with gc.
        Don't play queer offsetting games with reg_known_value and
        reg_known_equiv_p.
        (end_alias_analysis): Free reg_known_value with gc.
        * rtl.h (get_reg_known_value, get_reg_known_equiv_p): Declare.
        * sched-deps.c (reg_known_equiv_p, reg_known_value): Remove.
        (deps_may_trap_p, sched_analyze_1, sched_analyze_2): Use the new
        functions instead.

Index: alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/alias.c,v
retrieving revision 1.222
diff -c -p -d -r1.222 alias.c
*** alias.c	23 Mar 2004 20:43:38 -0000	1.222
--- alias.c	25 Mar 2004 00:52:39 -0000
*************** static GTY (()) rtx static_reg_base_valu
*** 181,197 ****
  
     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
!    init_alias_analysis, and does not change until end_alias_analysis
!    is called.  */
! rtx *reg_known_value;
  
  /* Indicates number of valid entries in reg_known_value.  */
! static unsigned int reg_known_value_size;
  
  /* Vector recording for each reg_known_value whether it is due to a
     REG_EQUIV note.  Future passes (viz., reload) may replace the
--- 181,196 ----
  
     Because this array contains only pseudo registers it has no effect
     after reload.  */
! static GTY((length("alias_invariant_size"))) rtx *alias_invariant;
! unsigned GTY(()) int alias_invariant_size;
  
  /* Vector indexed by N giving the initial (unchanging) value known for
!    pseudo-register N.  This array is initialized in init_alias_analysis,
!    and does not change until end_alias_analysis is called.  */
! static GTY((length("reg_known_value_size"))) rtx *reg_known_value;
  
  /* Indicates number of valid entries in reg_known_value.  */
! static GTY(()) unsigned int reg_known_value_size;
  
  /* Vector recording for each reg_known_value whether it is due to a
     REG_EQUIV note.  Future passes (viz., reload) may replace the
*************** static unsigned int reg_known_value_size
*** 205,211 ****
     REG_EQUIV notes.  One could argue that the REG_EQUIV notes are
     wrong, but solving the problem in the scheduler will likely give
     better code, so we do it here.  */
! char *reg_known_equiv_p;
  
  /* True when scanning insns from the start of the rtl to the
     NOTE_INSN_FUNCTION_BEG note.  */
--- 204,210 ----
     REG_EQUIV notes.  One could argue that the REG_EQUIV notes are
     wrong, but solving the problem in the scheduler will likely give
     better code, so we do it here.  */
! static bool *reg_known_equiv_p;
  
  /* True when scanning insns from the start of the rtl to the
     NOTE_INSN_FUNCTION_BEG note.  */
*************** clear_reg_alias_info (rtx reg)
*** 1075,1084 ****
  {
    unsigned int regno = REGNO (reg);
  
!   if (regno < reg_known_value_size && regno >= FIRST_PSEUDO_REGISTER)
!     reg_known_value[regno] = reg;
  }
  
  /* Returns a canonical version of X, from the point of view alias
     analysis.  (For example, if X is a MEM whose address is a register,
     and the register has a known value (say a SYMBOL_REF), then a MEM
--- 1074,1143 ----
  {
    unsigned int regno = REGNO (reg);
  
!   if (regno >= FIRST_PSEUDO_REGISTER)
!     {
!       regno -= FIRST_PSEUDO_REGISTER;
!       if (regno < reg_known_value_size)
! 	{
! 	  reg_known_value[regno] = reg;
! 	  reg_known_equiv_p[regno] = false;
! 	}
!     }
  }
  
+ /* If a value is known for REGNO, return it.  */
+ 
+ rtx 
+ get_reg_known_value (unsigned int regno)
+ {
+   if (regno >= FIRST_PSEUDO_REGISTER)
+     {
+       regno -= FIRST_PSEUDO_REGISTER;
+       if (regno < reg_known_value_size)
+ 	return reg_known_value[regno];
+     }
+   return NULL;
+ }
+ 
+ /* Set it.  */
+ 
+ static void
+ set_reg_known_value (unsigned int regno, rtx val)
+ {
+   if (regno >= FIRST_PSEUDO_REGISTER)
+     {
+       regno -= FIRST_PSEUDO_REGISTER;
+       if (regno < reg_known_value_size)
+ 	reg_known_value[regno] = val;
+     }
+ }
+ 
+ /* Similarly for reg_known_equiv_p.  */
+ 
+ bool
+ get_reg_known_equiv_p (unsigned int regno)
+ {
+   if (regno >= FIRST_PSEUDO_REGISTER)
+     {
+       regno -= FIRST_PSEUDO_REGISTER;
+       if (regno < reg_known_value_size)
+ 	return reg_known_equiv_p[regno];
+     }
+   return false;
+ }
+ 
+ static void
+ set_reg_known_equiv_p (unsigned int regno, bool val)
+ {
+   if (regno >= FIRST_PSEUDO_REGISTER)
+     {
+       regno -= FIRST_PSEUDO_REGISTER;
+       if (regno < reg_known_value_size)
+ 	reg_known_equiv_p[regno] = val;
+     }
+ }
+ 
+ 
  /* Returns a canonical version of X, from the point of view alias
     analysis.  (For example, if X is a MEM whose address is a register,
     and the register has a known value (say a SYMBOL_REF), then a MEM
*************** rtx
*** 1088,1098 ****
  canon_rtx (rtx x)
  {
    /* Recursively look for equivalences.  */
!   if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER
!       && REGNO (x) < reg_known_value_size)
!     return reg_known_value[REGNO (x)] == x
!       ? x : canon_rtx (reg_known_value[REGNO (x)]);
!   else if (GET_CODE (x) == PLUS)
      {
        rtx x0 = canon_rtx (XEXP (x, 0));
        rtx x1 = canon_rtx (XEXP (x, 1));
--- 1147,1162 ----
  canon_rtx (rtx x)
  {
    /* Recursively look for equivalences.  */
!   if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
!     {
!       rtx t = get_reg_known_value (REGNO (x));
!       if (t == x)
! 	return x;
!       if (t)
! 	return canon_rtx (t);
!     }
! 
!   if (GET_CODE (x) == PLUS)
      {
        rtx x0 = canon_rtx (XEXP (x, 0));
        rtx x1 = canon_rtx (XEXP (x, 1));
*************** init_alias_analysis (void)
*** 2736,2749 ****
  
    timevar_push (TV_ALIAS_ANALYSIS);
  
!   reg_known_value_size = maxreg;
! 
!   reg_known_value
!     = (rtx *) xcalloc ((maxreg - FIRST_PSEUDO_REGISTER), sizeof (rtx))
!     - FIRST_PSEUDO_REGISTER;
!   reg_known_equiv_p
!     = (char*) xcalloc ((maxreg - FIRST_PSEUDO_REGISTER), sizeof (char))
!     - FIRST_PSEUDO_REGISTER;
  
    /* Overallocate reg_base_value to allow some growth during loop
       optimization.  Loop unrolling can create a large number of
--- 2800,2808 ----
  
    timevar_push (TV_ALIAS_ANALYSIS);
  
!   reg_known_value_size = maxreg - FIRST_PSEUDO_REGISTER;
!   reg_known_value = ggc_calloc (reg_known_value_size, sizeof (rtx));
!   reg_known_equiv_p = xcalloc (reg_known_value_size, sizeof (bool));
  
    /* Overallocate reg_base_value to allow some growth during loop
       optimization.  Loop unrolling can create a large number of
*************** init_alias_analysis (void)
*** 2861,2866 ****
--- 2920,2926 ----
  		{
  		  unsigned int regno = REGNO (SET_DEST (set));
  		  rtx src = SET_SRC (set);
+ 		  rtx t;
  
  		  if (REG_NOTES (insn) != 0
  		      && (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
*************** init_alias_analysis (void)
*** 2868,2896 ****
  			  || (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
  		      && GET_CODE (XEXP (note, 0)) != EXPR_LIST
  		      && ! rtx_varies_p (XEXP (note, 0), 1)
! 		      && ! reg_overlap_mentioned_p (SET_DEST (set), XEXP (note, 0)))
  		    {
! 		      reg_known_value[regno] = XEXP (note, 0);
! 		      reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV;
  		    }
  		  else if (REG_N_SETS (regno) == 1
  			   && GET_CODE (src) == PLUS
  			   && GET_CODE (XEXP (src, 0)) == REG
! 			   && REGNO (XEXP (src, 0)) >= FIRST_PSEUDO_REGISTER
! 			   && (reg_known_value[REGNO (XEXP (src, 0))])
  			   && GET_CODE (XEXP (src, 1)) == CONST_INT)
  		    {
! 		      rtx op0 = XEXP (src, 0);
! 		      op0 = reg_known_value[REGNO (op0)];
! 		      reg_known_value[regno]
! 			= plus_constant (op0, INTVAL (XEXP (src, 1)));
! 		      reg_known_equiv_p[regno] = 0;
  		    }
  		  else if (REG_N_SETS (regno) == 1
  			   && ! rtx_varies_p (src, 1))
  		    {
! 		      reg_known_value[regno] = src;
! 		      reg_known_equiv_p[regno] = 0;
  		    }
  		}
  	    }
--- 2928,2955 ----
  			  || (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
  		      && GET_CODE (XEXP (note, 0)) != EXPR_LIST
  		      && ! rtx_varies_p (XEXP (note, 0), 1)
! 		      && ! reg_overlap_mentioned_p (SET_DEST (set),
! 						    XEXP (note, 0)))
  		    {
! 		      set_reg_known_value (regno, XEXP (note, 0));
! 		      set_reg_known_equiv_p (regno,
! 			REG_NOTE_KIND (note) == REG_EQUIV);
  		    }
  		  else if (REG_N_SETS (regno) == 1
  			   && GET_CODE (src) == PLUS
  			   && GET_CODE (XEXP (src, 0)) == REG
! 			   && (t = get_reg_known_value (REGNO (XEXP (src, 0))))
  			   && GET_CODE (XEXP (src, 1)) == CONST_INT)
  		    {
! 		      t = plus_constant (t, INTVAL (XEXP (src, 1)));
! 		      set_reg_known_value (regno, t);
! 		      set_reg_known_equiv_p (regno, 0);
  		    }
  		  else if (REG_N_SETS (regno) == 1
  			   && ! rtx_varies_p (src, 1))
  		    {
! 		      set_reg_known_value (regno, src);
! 		      set_reg_known_equiv_p (regno, 0);
  		    }
  		}
  	    }
*************** init_alias_analysis (void)
*** 2917,2925 ****
    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];
  
    /* Simplify the reg_base_value array so that no register refers to
       another register, except to special registers indirectly through
--- 2976,2984 ----
    while (changed && ++pass < MAX_ALIAS_LOOP_PASSES);
  
    /* Fill in the remaining entries.  */
!   for (i = 0; i < (int)reg_known_value_size; i++)
      if (reg_known_value[i] == 0)
!       reg_known_value[i] = regno_reg_rtx[i + FIRST_PSEUDO_REGISTER];
  
    /* Simplify the reg_base_value array so that no register refers to
       another register, except to special registers indirectly through
*************** void
*** 2965,2974 ****
  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)
      {
--- 3024,3033 ----
  end_alias_analysis (void)
  {
    old_reg_base_value = reg_base_value;
!   ggc_free (reg_known_value);
    reg_known_value = 0;
    reg_known_value_size = 0;
!   free (reg_known_equiv_p);
    reg_known_equiv_p = 0;
    if (alias_invariant)
      {
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.466
diff -c -p -d -r1.466 rtl.h
*** rtl.h	20 Mar 2004 23:08:57 -0000	1.466
--- rtl.h	25 Mar 2004 00:52:40 -0000
*************** extern rtx addr_side_effect_eval (rtx, i
*** 2423,2428 ****
--- 2423,2430 ----
  extern bool memory_modified_in_insn_p (rtx, rtx);
  extern rtx find_base_term (rtx);
  extern rtx gen_hard_reg_clobber (enum machine_mode, unsigned int);
+ extern rtx get_reg_known_value (unsigned int);
+ extern bool get_reg_known_equiv_p (unsigned int);
  
  /* In sibcall.c */
  typedef enum {
Index: sched-deps.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sched-deps.c,v
retrieving revision 1.71
diff -c -p -d -r1.71 sched-deps.c
*** sched-deps.c	4 Mar 2004 19:03:02 -0000	1.71
--- sched-deps.c	25 Mar 2004 00:52:40 -0000
*************** Software Foundation, 59 Temple Place - S
*** 44,51 ****
  #include "cselib.h"
  #include "df.h"
  
- extern char *reg_known_equiv_p;
- extern rtx *reg_known_value;
  
  static regset_head reg_pending_sets_head;
  static regset_head reg_pending_clobbers_head;
--- 44,49 ----
*************** deps_may_trap_p (rtx mem)
*** 113,122 ****
  {
    rtx addr = XEXP (mem, 0);
  
!   if (REG_P (addr)
!       && REGNO (addr) >= FIRST_PSEUDO_REGISTER
!       && reg_known_value[REGNO (addr)])
!     addr = reg_known_value[REGNO (addr)];
    return rtx_addr_can_trap_p (addr);
  }
  
--- 111,122 ----
  {
    rtx addr = XEXP (mem, 0);
  
!   if (REG_P (addr) && REGNO (addr) >= FIRST_PSEUDO_REGISTER)
!     {
!       rtx t = get_reg_known_value (REGNO (addr));
!       if (t)
! 	addr = t;
!     }
    return rtx_addr_can_trap_p (addr);
  }
  
*************** sched_analyze_1 (struct deps *deps, rtx 
*** 523,532 ****
  	  /* Pseudos that are REG_EQUIV to something may be replaced
  	     by that during reloading.  We need only add dependencies for
  	     the address in the REG_EQUIV note.  */
! 	  if (!reload_completed
! 	      && reg_known_equiv_p[regno]
! 	      && GET_CODE (reg_known_value[regno]) == MEM)
! 	    sched_analyze_2 (deps, XEXP (reg_known_value[regno], 0), insn);
  
  	  /* Don't let it cross a call after scheduling if it doesn't
  	     already cross one.  */
--- 523,534 ----
  	  /* Pseudos that are REG_EQUIV to something may be replaced
  	     by that during reloading.  We need only add dependencies for
  	     the address in the REG_EQUIV note.  */
! 	  if (!reload_completed && get_reg_known_equiv_p (regno))
! 	    {
! 	      rtx t = get_reg_known_value (regno);
! 	      if (GET_CODE (t) == MEM)
! 	        sched_analyze_2 (deps, XEXP (t, 0), insn);
! 	    }
  
  	  /* Don't let it cross a call after scheduling if it doesn't
  	     already cross one.  */
*************** sched_analyze_2 (struct deps *deps, rtx 
*** 659,668 ****
  	    /* Pseudos that are REG_EQUIV to something may be replaced
  	       by that during reloading.  We need only add dependencies for
  	       the address in the REG_EQUIV note.  */
! 	    if (!reload_completed
! 		&& reg_known_equiv_p[regno]
! 		&& GET_CODE (reg_known_value[regno]) == MEM)
! 	      sched_analyze_2 (deps, XEXP (reg_known_value[regno], 0), insn);
  
  	    /* If the register does not already cross any calls, then add this
  	       insn to the sched_before_next_call list so that it will still
--- 661,672 ----
  	    /* Pseudos that are REG_EQUIV to something may be replaced
  	       by that during reloading.  We need only add dependencies for
  	       the address in the REG_EQUIV note.  */
! 	    if (!reload_completed && get_reg_known_equiv_p (regno))
! 	      {
! 		rtx t = get_reg_known_value (regno);
! 		if (GET_CODE (t) == MEM)
! 		  sched_analyze_2 (deps, XEXP (t, 0), insn);
! 	      }
  
  	    /* If the register does not already cross any calls, then add this
  	       insn to the sched_before_next_call list so that it will still


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