public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Move reg_equiv* arrays into a single VEC structure
@ 2011-03-30 14:26 Jeff Law
  2011-03-30 15:02 ` Richard Guenther
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Jeff Law @ 2011-03-30 14:26 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1189 bytes --]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

As originally discussed here:

http://gcc.gnu.org/ml/gcc-patches/2010-05/msg00987.html

Changes since the original submission:

Per Richi's suggestion I changed the patch to use a GC'd VEC.  I defined
accessor macros so that a ton of reformatting isn't needed and finally I
made the appropriate tweaks to the few backends that peeked at the
reg_equiv arrays.

Given the changes and the length of time since the original submission,
I think it's probably best to get a fresh approval rather than rely on
the prior approval.

Bootstrapped and regression tested on x86_64-unknown-linux-gnu.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJNkzznAAoJEBRtltQi2kC7VgYH/0yTkwWkDRyalReMk3whdIXO
8qw5H6c9Gz+Yj+EnnPySKsFIvJKMBTQHIpdCzjTCVWD/Z7LSJwERzzlNCPrQu2au
dpOoUYCTAwgSW0Us9B+2Bcf2DABinYLV+hgKAKFEVi98CheZe3hZZ14lm5mlYDec
INYKyfqYHmyahT8fa6ABY2kp0X2xhQhJ0VAGPI34kytJpgLpIdtRwq6PsdsPM0PJ
frLAY5xIEmJqBB30RaPqnD07u06xZHi+S9gfAJa4LJTUqVALNusYdZzZajKMtF3i
BCXK4UFk+J2MlM9xZkVWqQiryLc6arVT2bMQcvz7tXTMZkY6ZdZ7sKFBgKea6vM=
=iMqQ
-----END PGP SIGNATURE-----

[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 94214 bytes --]

	* reload.h (reg_equiv_constant): Move into new structure reg_equivs,
	define accessor macro.
	(reg_equiv_invariant, reg_equiv_memory_loc): Likewise.
	(reg_equiv_address, reg_equiv_mem, reg_equiv_alt_mem_list): Likewise.
	(reg_equiv_init): Likewise.
	(reg_equivs_size): New variable.
	(reg_equiv_init_size): Remove.
	(allocate_initial_values): Move prototype to here from....
	* integrate.h (allocate_initial_values): Remove prototype.
	* integrate.c: Include reload.h.
	(allocate_initial_values): Corresponding changes.
	* ira.c (find_reg_equiv_invariant_cost): Corresponding changes.
	(fix_reg_equiv_init, no_equiv): Corresponding changes.
	(update_equiv_regs): Corresponding changes.
	(ira): Corresponding changes.
	* reload.c (push_reg_equiv_alt_mem): Corresponding changes.
	(push_secondary_reload): Corresponding changes.
	(push_reload, find_reloads, find_reloads_toplev): Corresponding changes.
	(make_memloc, find_reloads_address): Corresponding changes.
	(subst_reg_equivs, subst_indexed_address): Corresponding changes.
	(find_reloads_address_1): Corresponding changes.
	(find_reloads_subreg_address, subst_reloads): Corresponding changes.
	(refers_to_regno_for_reload_p): Corresponding changes.
	(reg_overlap_mentioned_for_reload_p): Corresponding changes.
	(refers_to_mem_for_reload_p, find_equiv_reg): Corresponding changes.
	* reload1.c: Include ggc.h.
	(grow_reg_equivs): New function.
	(replace_pseudos_in, reload): Corresponding changes.
	(calculate_needs_all_insns, alter_regs): Corresponding changes.
	(eliminate_regs_1, elimination_effects): Corresponding changes.
	(emit_input_reload_insns, emit_output_reload_insns): Likewise.
	(delete_output_reload): Likewise.
	* caller-save.c (mark_referenced_regs): Corresponding changes.
	* alpha/alpha.c (resolve_reload_operand): Corresponding changes.
	* frv/predicates.md (frv_load_operand): Corresponding changes.
	* microblaze/microblaze.c (double_memory_operand): Corresponding
	changes.
	* avr/avr.h (LEGITIMIZE_RELOAD_ADDRESS): Corresponding changes.
	* xtensa/xtensa.c (fixup_subreg_mem): Corresponding changes.
	* mn10300/mn10300.c (mn10300_secondary_reload): Corresponding
	changes.
	* m68k/m68k.c (emit_move_sequence): Corresponding changes.
	* arm/arm.c (arm_reload_in_hi, arm_reload_out_hi): Corresponding
	changes.
	* pa/pa.c (emit_move_sequence): Corresponding changes.
	* vax/vax.c (nonindexed_address_p): Corresponding changes.


Index: reload.c
===================================================================
*** reload.c	(revision 171659)
--- reload.c	(working copy)
*************** push_reg_equiv_alt_mem (int regno, rtx m
*** 300,312 ****
  {
    rtx it;
  
!   for (it = reg_equiv_alt_mem_list [regno]; it; it = XEXP (it, 1))
      if (rtx_equal_p (XEXP (it, 0), mem))
        return;
  
!   reg_equiv_alt_mem_list [regno]
      = alloc_EXPR_LIST (REG_EQUIV, mem,
! 		       reg_equiv_alt_mem_list [regno]);
  }
  \f
  /* Determine if any secondary reloads are needed for loading (if IN_P is
--- 300,312 ----
  {
    rtx it;
  
!   for (it = reg_equiv_alt_mem_list (regno); it; it = XEXP (it, 1))
      if (rtx_equal_p (XEXP (it, 0), mem))
        return;
  
!   reg_equiv_alt_mem_list (regno)
      = alloc_EXPR_LIST (REG_EQUIV, mem,
! 		       reg_equiv_alt_mem_list (regno));
  }
  \f
  /* Determine if any secondary reloads are needed for loading (if IN_P is
*************** push_secondary_reload (int in_p, rtx x, 
*** 362,369 ****
       might be sensitive to the form of the MEM.  */
  
    if (REG_P (x) && REGNO (x) >= FIRST_PSEUDO_REGISTER
!       && reg_equiv_mem[REGNO (x)] != 0)
!     x = reg_equiv_mem[REGNO (x)];
  
    sri.icode = CODE_FOR_nothing;
    sri.prev_sri = prev_sri;
--- 362,369 ----
       might be sensitive to the form of the MEM.  */
  
    if (REG_P (x) && REGNO (x) >= FIRST_PSEUDO_REGISTER
!       && reg_equiv_mem (REGNO (x)))
!     x = reg_equiv_mem (REGNO (x));
  
    sri.icode = CODE_FOR_nothing;
    sri.prev_sri = prev_sri;
*************** push_reload (rtx in, rtx out, rtx *inloc
*** 949,955 ****
  
        gcc_assert (regno < FIRST_PSEUDO_REGISTER
  		  || reg_renumber[regno] >= 0
! 		  || reg_equiv_constant[regno] == NULL_RTX);
      }
  
    /* reg_equiv_constant only contains constants which are obviously
--- 949,955 ----
  
        gcc_assert (regno < FIRST_PSEUDO_REGISTER
  		  || reg_renumber[regno] >= 0
! 		  || reg_equiv_constant (regno) == NULL_RTX);
      }
  
    /* reg_equiv_constant only contains constants which are obviously
*************** push_reload (rtx in, rtx out, rtx *inloc
*** 962,968 ****
  
        gcc_assert (regno < FIRST_PSEUDO_REGISTER
  		  || reg_renumber[regno] >= 0
! 		  || reg_equiv_constant[regno] == NULL_RTX);
      }
  
    /* If we have a read-write operand with an address side-effect,
--- 962,968 ----
  
        gcc_assert (regno < FIRST_PSEUDO_REGISTER
  		  || reg_renumber[regno] >= 0
! 		  || reg_equiv_constant (regno) == NULL_RTX);
      }
  
    /* If we have a read-write operand with an address side-effect,
*************** find_reloads (rtx insn, int replace, int
*** 2855,2864 ****
  	      && REG_P (reg)
  	      && (GET_MODE_SIZE (GET_MODE (reg))
  		  >= GET_MODE_SIZE (GET_MODE (op)))
! 	      && reg_equiv_constant[REGNO (reg)] == 0)
  	    set_unique_reg_note (emit_insn_before (gen_rtx_USE (VOIDmode, reg),
  						   insn),
! 				 REG_EQUAL, reg_equiv_memory_loc[REGNO (reg)]);
  
  	  substed_operand[i] = recog_data.operand[i] = op;
  	}
--- 2855,2864 ----
  	      && REG_P (reg)
  	      && (GET_MODE_SIZE (GET_MODE (reg))
  		  >= GET_MODE_SIZE (GET_MODE (op)))
! 	      && reg_equiv_constant (REGNO (reg)) == 0)
  	    set_unique_reg_note (emit_insn_before (gen_rtx_USE (VOIDmode, reg),
  						   insn),
! 				 REG_EQUAL, reg_equiv_memory_loc (REGNO (reg)));
  
  	  substed_operand[i] = recog_data.operand[i] = op;
  	}
*************** find_reloads (rtx insn, int replace, int
*** 2879,2885 ****
  	     that we don't try to replace it in the insn in which it
  	     is being set.  */
  	  int regno = REGNO (recog_data.operand[i]);
! 	  if (reg_equiv_constant[regno] != 0
  	      && (set == 0 || &SET_DEST (set) != recog_data.operand_loc[i]))
  	    {
  	      /* Record the existing mode so that the check if constants are
--- 2879,2885 ----
  	     that we don't try to replace it in the insn in which it
  	     is being set.  */
  	  int regno = REGNO (recog_data.operand[i]);
! 	  if (reg_equiv_constant (regno) != 0
  	      && (set == 0 || &SET_DEST (set) != recog_data.operand_loc[i]))
  	    {
  	      /* Record the existing mode so that the check if constants are
*************** find_reloads (rtx insn, int replace, int
*** 2889,2898 ****
  		operand_mode[i] = GET_MODE (recog_data.operand[i]);
  
  	      substed_operand[i] = recog_data.operand[i]
! 		= reg_equiv_constant[regno];
  	    }
! 	  if (reg_equiv_memory_loc[regno] != 0
! 	      && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
  	    /* We need not give a valid is_set_dest argument since the case
  	       of a constant equivalence was checked above.  */
  	    substed_operand[i] = recog_data.operand[i]
--- 2889,2898 ----
  		operand_mode[i] = GET_MODE (recog_data.operand[i]);
  
  	      substed_operand[i] = recog_data.operand[i]
! 		= reg_equiv_constant (regno);
  	    }
! 	  if (reg_equiv_memory_loc (regno) != 0
! 	      && (reg_equiv_address (regno) != 0 || num_not_at_initial_offset))
  	    /* We need not give a valid is_set_dest argument since the case
  	       of a constant equivalence was checked above.  */
  	    substed_operand[i] = recog_data.operand[i]
*************** find_reloads (rtx insn, int replace, int
*** 3280,3286 ****
  		       to override the handling of reg_equiv_address.  */
  		    && !(REG_P (XEXP (operand, 0))
  			 && (ind_levels == 0
! 			     || reg_equiv_address[REGNO (XEXP (operand, 0))] != 0)))
  		  win = 1;
  		break;
  
--- 3280,3286 ----
  		       to override the handling of reg_equiv_address.  */
  		    && !(REG_P (XEXP (operand, 0))
  			 && (ind_levels == 0
! 			     || reg_equiv_address (REGNO (XEXP (operand, 0))) != 0)))
  		  win = 1;
  		break;
  
*************** find_reloads (rtx insn, int replace, int
*** 3304,3312 ****
  			   loading it into a register; hence it will be
  			   offsettable, but we cannot say that reg_equiv_mem
  			   is offsettable without checking.  */
! 			&& ((reg_equiv_mem[REGNO (operand)] != 0
! 			     && offsettable_memref_p (reg_equiv_mem[REGNO (operand)]))
! 			    || (reg_equiv_address[REGNO (operand)] != 0))))
  		  win = 1;
  		if (CONST_POOL_OK_P (operand)
  		    || MEM_P (operand))
--- 3304,3312 ----
  			   loading it into a register; hence it will be
  			   offsettable, but we cannot say that reg_equiv_mem
  			   is offsettable without checking.  */
! 			&& ((reg_equiv_mem (REGNO (operand)) != 0
! 			     && offsettable_memref_p (reg_equiv_mem (REGNO (operand))))
! 			    || (reg_equiv_address (REGNO (operand)) != 0))))
  		  win = 1;
  		if (CONST_POOL_OK_P (operand)
  		    || MEM_P (operand))
*************** find_reloads (rtx insn, int replace, int
*** 3416,3424 ****
  		        else if (REG_P (operand)
  				 && REGNO (operand) >= FIRST_PSEUDO_REGISTER
  				 && reg_renumber[REGNO (operand)] < 0
! 				 && ((reg_equiv_mem[REGNO (operand)] != 0
! 				      && EXTRA_CONSTRAINT_STR (reg_equiv_mem[REGNO (operand)], c, p))
! 				     || (reg_equiv_address[REGNO (operand)] != 0)))
  			  win = 1;
  
  			/* If we didn't already win, we can reload
--- 3416,3424 ----
  		        else if (REG_P (operand)
  				 && REGNO (operand) >= FIRST_PSEUDO_REGISTER
  				 && reg_renumber[REGNO (operand)] < 0
! 				 && ((reg_equiv_mem (REGNO (operand)) != 0
! 				      && EXTRA_CONSTRAINT_STR (reg_equiv_mem (REGNO (operand)), c, p))
! 				     || (reg_equiv_address (REGNO (operand)) != 0)))
  			  win = 1;
  
  			/* If we didn't already win, we can reload
*************** find_reloads_toplev (rtx x, int opnum, e
*** 4652,4671 ****
      {
        /* This code is duplicated for speed in find_reloads.  */
        int regno = REGNO (x);
!       if (reg_equiv_constant[regno] != 0 && !is_set_dest)
! 	x = reg_equiv_constant[regno];
  #if 0
        /*  This creates (subreg (mem...)) which would cause an unnecessary
  	  reload of the mem.  */
!       else if (reg_equiv_mem[regno] != 0)
! 	x = reg_equiv_mem[regno];
  #endif
!       else if (reg_equiv_memory_loc[regno]
! 	       && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
  	{
  	  rtx mem = make_memloc (x, regno);
! 	  if (reg_equiv_address[regno]
! 	      || ! rtx_equal_p (mem, reg_equiv_mem[regno]))
  	    {
  	      /* If this is not a toplevel operand, find_reloads doesn't see
  		 this substitution.  We have to emit a USE of the pseudo so
--- 4652,4671 ----
      {
        /* This code is duplicated for speed in find_reloads.  */
        int regno = REGNO (x);
!       if (reg_equiv_constant (regno) != 0 && !is_set_dest)
! 	x = reg_equiv_constant (regno);
  #if 0
        /*  This creates (subreg (mem...)) which would cause an unnecessary
  	  reload of the mem.  */
!       else if (reg_equiv_mem (regno) != 0)
! 	x = reg_equiv_mem (regno);
  #endif
!       else if (reg_equiv_memory_loc (regno)
! 	       && (reg_equiv_address (regno) != 0 || num_not_at_initial_offset))
  	{
  	  rtx mem = make_memloc (x, regno);
! 	  if (reg_equiv_address (regno)
! 	      || ! rtx_equal_p (mem, reg_equiv_mem (regno)))
  	    {
  	      /* If this is not a toplevel operand, find_reloads doesn't see
  		 this substitution.  We have to emit a USE of the pseudo so
*************** find_reloads_toplev (rtx x, int opnum, e
*** 4715,4724 ****
  
        if (regno >= FIRST_PSEUDO_REGISTER
  	  && reg_renumber[regno] < 0
! 	  && reg_equiv_constant[regno] != 0)
  	{
  	  tem =
! 	    simplify_gen_subreg (GET_MODE (x), reg_equiv_constant[regno],
  				 GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
  	  gcc_assert (tem);
  	  if (CONSTANT_P (tem) && !LEGITIMATE_CONSTANT_P (tem))
--- 4715,4724 ----
  
        if (regno >= FIRST_PSEUDO_REGISTER
  	  && reg_renumber[regno] < 0
! 	  && reg_equiv_constant (regno) != 0)
  	{
  	  tem =
! 	    simplify_gen_subreg (GET_MODE (x), reg_equiv_constant (regno),
  				 GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
  	  gcc_assert (tem);
  	  if (CONSTANT_P (tem) && !LEGITIMATE_CONSTANT_P (tem))
*************** find_reloads_toplev (rtx x, int opnum, e
*** 4751,4762 ****
  	       && (GET_MODE_SIZE (GET_MODE (x))
  		   <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
  #endif
! 	       && (reg_equiv_address[regno] != 0
! 		   || (reg_equiv_mem[regno] != 0
  		       && (! strict_memory_address_addr_space_p
! 			       (GET_MODE (x), XEXP (reg_equiv_mem[regno], 0),
! 				MEM_ADDR_SPACE (reg_equiv_mem[regno]))
! 			   || ! offsettable_memref_p (reg_equiv_mem[regno])
  			   || num_not_at_initial_offset))))
  	x = find_reloads_subreg_address (x, 1, opnum, type, ind_levels,
  					   insn, address_reloaded);
--- 4751,4762 ----
  	       && (GET_MODE_SIZE (GET_MODE (x))
  		   <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
  #endif
! 	       && (reg_equiv_address (regno) != 0
! 		   || (reg_equiv_mem (regno) != 0
  		       && (! strict_memory_address_addr_space_p
! 			       (GET_MODE (x), XEXP (reg_equiv_mem (regno), 0),
! 				MEM_ADDR_SPACE (reg_equiv_mem (regno)))
! 			   || ! offsettable_memref_p (reg_equiv_mem (regno))
  			   || num_not_at_initial_offset))))
  	x = find_reloads_subreg_address (x, 1, opnum, type, ind_levels,
  					   insn, address_reloaded);
*************** make_memloc (rtx ad, int regno)
*** 4794,4800 ****
    /* We must rerun eliminate_regs, in case the elimination
       offsets have changed.  */
    rtx tem
!     = XEXP (eliminate_regs (reg_equiv_memory_loc[regno], VOIDmode, NULL_RTX),
  	    0);
  
    /* If TEM might contain a pseudo, we must copy it to avoid
--- 4794,4800 ----
    /* We must rerun eliminate_regs, in case the elimination
       offsets have changed.  */
    rtx tem
!     = XEXP (eliminate_regs (reg_equiv_memory_loc (regno), VOIDmode, NULL_RTX),
  	    0);
  
    /* If TEM might contain a pseudo, we must copy it to avoid
*************** make_memloc (rtx ad, int regno)
*** 4802,4813 ****
    if (rtx_varies_p (tem, 0))
      tem = copy_rtx (tem);
  
!   tem = replace_equiv_address_nv (reg_equiv_memory_loc[regno], tem);
    tem = adjust_address_nv (tem, GET_MODE (ad), 0);
  
    /* Copy the result if it's still the same as the equivalence, to avoid
       modifying it when we do the substitution for the reload.  */
!   if (tem == reg_equiv_memory_loc[regno])
      tem = copy_rtx (tem);
    return tem;
  }
--- 4802,4813 ----
    if (rtx_varies_p (tem, 0))
      tem = copy_rtx (tem);
  
!   tem = replace_equiv_address_nv (reg_equiv_memory_loc (regno), tem);
    tem = adjust_address_nv (tem, GET_MODE (ad), 0);
  
    /* Copy the result if it's still the same as the equivalence, to avoid
       modifying it when we do the substitution for the reload.  */
!   if (tem == reg_equiv_memory_loc (regno))
      tem = copy_rtx (tem);
    return tem;
  }
*************** find_reloads_address (enum machine_mode 
*** 4876,4893 ****
      {
        regno = REGNO (ad);
  
!       if (reg_equiv_constant[regno] != 0)
  	{
! 	  find_reloads_address_part (reg_equiv_constant[regno], loc,
  				     base_reg_class (mode, MEM, SCRATCH),
  				     GET_MODE (ad), opnum, type, ind_levels);
  	  return 1;
  	}
  
!       tem = reg_equiv_memory_loc[regno];
        if (tem != 0)
  	{
! 	  if (reg_equiv_address[regno] != 0 || num_not_at_initial_offset)
  	    {
  	      tem = make_memloc (ad, regno);
  	      if (! strict_memory_address_addr_space_p (GET_MODE (tem),
--- 4876,4893 ----
      {
        regno = REGNO (ad);
  
!       if (reg_equiv_constant (regno) != 0)
  	{
! 	  find_reloads_address_part (reg_equiv_constant (regno), loc,
  				     base_reg_class (mode, MEM, SCRATCH),
  				     GET_MODE (ad), opnum, type, ind_levels);
  	  return 1;
  	}
  
!       tem = reg_equiv_memory_loc (regno);
        if (tem != 0)
  	{
! 	  if (reg_equiv_address (regno) != 0 || num_not_at_initial_offset)
  	    {
  	      tem = make_memloc (ad, regno);
  	      if (! strict_memory_address_addr_space_p (GET_MODE (tem),
*************** find_reloads_address (enum machine_mode 
*** 4919,4925 ****
  		     in the final reload pass.  */
  		  if (replace_reloads
  		      && num_not_at_initial_offset
! 		      && ! rtx_equal_p (tem, reg_equiv_mem[regno]))
  		    {
  		      *loc = tem;
  		      /* We mark the USE with QImode so that we
--- 4919,4925 ----
  		     in the final reload pass.  */
  		  if (replace_reloads
  		      && num_not_at_initial_offset
! 		      && ! rtx_equal_p (tem, reg_equiv_mem (regno)))
  		    {
  		      *loc = tem;
  		      /* We mark the USE with QImode so that we
*************** find_reloads_address (enum machine_mode 
*** 4965,4971 ****
        if (GET_CODE (ad) == PLUS
  	  && CONST_INT_P (XEXP (ad, 1))
  	  && REG_P (XEXP (ad, 0))
! 	  && reg_equiv_constant[REGNO (XEXP (ad, 0))] == 0)
  	return 0;
  
        subst_reg_equivs_changed = 0;
--- 4965,4971 ----
        if (GET_CODE (ad) == PLUS
  	  && CONST_INT_P (XEXP (ad, 1))
  	  && REG_P (XEXP (ad, 0))
! 	  && reg_equiv_constant (REGNO (XEXP (ad, 0))) == 0)
  	return 0;
  
        subst_reg_equivs_changed = 0;
*************** subst_reg_equivs (rtx ad, rtx insn)
*** 5282,5296 ****
        {
  	int regno = REGNO (ad);
  
! 	if (reg_equiv_constant[regno] != 0)
  	  {
  	    subst_reg_equivs_changed = 1;
! 	    return reg_equiv_constant[regno];
  	  }
! 	if (reg_equiv_memory_loc[regno] && num_not_at_initial_offset)
  	  {
  	    rtx mem = make_memloc (ad, regno);
! 	    if (! rtx_equal_p (mem, reg_equiv_mem[regno]))
  	      {
  		subst_reg_equivs_changed = 1;
  		/* We mark the USE with QImode so that we recognize it
--- 5282,5296 ----
        {
  	int regno = REGNO (ad);
  
! 	if (reg_equiv_constant (regno) != 0)
  	  {
  	    subst_reg_equivs_changed = 1;
! 	    return reg_equiv_constant (regno);
  	  }
! 	if (reg_equiv_memory_loc (regno) && num_not_at_initial_offset)
  	  {
  	    rtx mem = make_memloc (ad, regno);
! 	    if (! rtx_equal_p (mem, reg_equiv_mem (regno)))
  	      {
  		subst_reg_equivs_changed = 1;
  		/* We mark the USE with QImode so that we recognize it
*************** subst_indexed_address (rtx addr)
*** 5393,5405 ****
        if (REG_P (op0)
  	  && (regno = REGNO (op0)) >= FIRST_PSEUDO_REGISTER
  	  && reg_renumber[regno] < 0
! 	  && reg_equiv_constant[regno] != 0)
! 	op0 = reg_equiv_constant[regno];
        else if (REG_P (op1)
  	       && (regno = REGNO (op1)) >= FIRST_PSEUDO_REGISTER
  	       && reg_renumber[regno] < 0
! 	       && reg_equiv_constant[regno] != 0)
! 	op1 = reg_equiv_constant[regno];
        else if (GET_CODE (op0) == PLUS
  	       && (tem = subst_indexed_address (op0)) != op0)
  	op0 = tem;
--- 5393,5405 ----
        if (REG_P (op0)
  	  && (regno = REGNO (op0)) >= FIRST_PSEUDO_REGISTER
  	  && reg_renumber[regno] < 0
! 	  && reg_equiv_constant (regno) != 0)
! 	op0 = reg_equiv_constant (regno);
        else if (REG_P (op1)
  	       && (regno = REGNO (op1)) >= FIRST_PSEUDO_REGISTER
  	       && reg_renumber[regno] < 0
! 	       && reg_equiv_constant (regno) != 0)
! 	op1 = reg_equiv_constant (regno);
        else if (GET_CODE (op0) == PLUS
  	       && (tem = subst_indexed_address (op0)) != op0)
  	op0 = tem;
*************** find_reloads_address_1 (enum machine_mod
*** 5688,5705 ****
  
  	/* A register that is incremented cannot be constant!  */
  	gcc_assert (regno < FIRST_PSEUDO_REGISTER
! 		    || reg_equiv_constant[regno] == 0);
  
  	/* Handle a register that is equivalent to a memory location
  	    which cannot be addressed directly.  */
! 	if (reg_equiv_memory_loc[regno] != 0
! 	    && (reg_equiv_address[regno] != 0
  		|| num_not_at_initial_offset))
  	  {
  	    rtx tem = make_memloc (XEXP (x, 0), regno);
  
! 	    if (reg_equiv_address[regno]
! 		|| ! rtx_equal_p (tem, reg_equiv_mem[regno]))
  	      {
  		rtx orig = tem;
  
--- 5688,5705 ----
  
  	/* A register that is incremented cannot be constant!  */
  	gcc_assert (regno < FIRST_PSEUDO_REGISTER
! 		    || reg_equiv_constant (regno) == 0);
  
  	/* Handle a register that is equivalent to a memory location
  	    which cannot be addressed directly.  */
! 	if (reg_equiv_memory_loc (regno) != 0
! 	    && (reg_equiv_address (regno) != 0
  		|| num_not_at_initial_offset))
  	  {
  	    rtx tem = make_memloc (XEXP (x, 0), regno);
  
! 	    if (reg_equiv_address (regno)
! 		|| ! rtx_equal_p (tem, reg_equiv_mem (regno)))
  	      {
  		rtx orig = tem;
  
*************** find_reloads_address_1 (enum machine_mod
*** 5759,5774 ****
  
  	  /* A register that is incremented cannot be constant!  */
  	  gcc_assert (regno < FIRST_PSEUDO_REGISTER
! 		      || reg_equiv_constant[regno] == 0);
  
  	  /* Handle a register that is equivalent to a memory location
  	     which cannot be addressed directly.  */
! 	  if (reg_equiv_memory_loc[regno] != 0
! 	      && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
  	    {
  	      rtx tem = make_memloc (XEXP (x, 0), regno);
! 	      if (reg_equiv_address[regno]
! 		  || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
  		{
  		  rtx orig = tem;
  
--- 5759,5774 ----
  
  	  /* A register that is incremented cannot be constant!  */
  	  gcc_assert (regno < FIRST_PSEUDO_REGISTER
! 		      || reg_equiv_constant (regno) == 0);
  
  	  /* Handle a register that is equivalent to a memory location
  	     which cannot be addressed directly.  */
! 	  if (reg_equiv_memory_loc (regno) != 0
! 	      && (reg_equiv_address (regno) != 0 || num_not_at_initial_offset))
  	    {
  	      rtx tem = make_memloc (XEXP (x, 0), regno);
! 	      if (reg_equiv_address (regno)
! 		  || ! rtx_equal_p (tem, reg_equiv_mem (regno)))
  		{
  		  rtx orig = tem;
  
*************** find_reloads_address_1 (enum machine_mod
*** 5818,5824 ****
  		 Also don't do this if we can probably update x directly.  */
  	      rtx equiv = (MEM_P (XEXP (x, 0))
  			   ? XEXP (x, 0)
! 			   : reg_equiv_mem[regno]);
  	      enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
  	      if (insn && NONJUMP_INSN_P (insn) && equiv
  		  && memory_operand (equiv, GET_MODE (equiv))
--- 5818,5824 ----
  		 Also don't do this if we can probably update x directly.  */
  	      rtx equiv = (MEM_P (XEXP (x, 0))
  			   ? XEXP (x, 0)
! 			   : reg_equiv_mem (regno));
  	      enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
  	      if (insn && NONJUMP_INSN_P (insn) && equiv
  		  && memory_operand (equiv, GET_MODE (equiv))
*************** find_reloads_address_1 (enum machine_mod
*** 5904,5912 ****
        {
  	int regno = REGNO (x);
  
! 	if (reg_equiv_constant[regno] != 0)
  	  {
! 	    find_reloads_address_part (reg_equiv_constant[regno], loc,
  				       context_reg_class,
  				       GET_MODE (x), opnum, type, ind_levels);
  	    return 1;
--- 5904,5912 ----
        {
  	int regno = REGNO (x);
  
! 	if (reg_equiv_constant (regno) != 0)
  	  {
! 	    find_reloads_address_part (reg_equiv_constant (regno), loc,
  				       context_reg_class,
  				       GET_MODE (x), opnum, type, ind_levels);
  	    return 1;
*************** find_reloads_address_1 (enum machine_mod
*** 5914,5934 ****
  
  #if 0 /* This might screw code in reload1.c to delete prior output-reload
  	 that feeds this insn.  */
! 	if (reg_equiv_mem[regno] != 0)
  	  {
! 	    push_reload (reg_equiv_mem[regno], NULL_RTX, loc, (rtx*) 0,
  			 context_reg_class,
  			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
  	    return 1;
  	  }
  #endif
  
! 	if (reg_equiv_memory_loc[regno]
! 	    && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
  	  {
  	    rtx tem = make_memloc (x, regno);
! 	    if (reg_equiv_address[regno] != 0
! 		|| ! rtx_equal_p (tem, reg_equiv_mem[regno]))
  	      {
  		x = tem;
  		find_reloads_address (GET_MODE (x), &x, XEXP (x, 0),
--- 5914,5934 ----
  
  #if 0 /* This might screw code in reload1.c to delete prior output-reload
  	 that feeds this insn.  */
! 	if (reg_equiv_mem (regno) != 0)
  	  {
! 	    push_reload (reg_equiv_mem (regno), NULL_RTX, loc, (rtx*) 0,
  			 context_reg_class,
  			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
  	    return 1;
  	  }
  #endif
  
! 	if (reg_equiv_memory_loc (regno)
! 	    && (reg_equiv_address (regno) != 0 || num_not_at_initial_offset))
  	  {
  	    rtx tem = make_memloc (x, regno);
! 	    if (reg_equiv_address (regno) != 0
! 		|| ! rtx_equal_p (tem, reg_equiv_mem (regno)))
  	      {
  		x = tem;
  		find_reloads_address (GET_MODE (x), &x, XEXP (x, 0),
*************** find_reloads_subreg_address (rtx x, int 
*** 6103,6115 ****
    int regno = REGNO (SUBREG_REG (x));
    int reloaded = 0;
  
!   if (reg_equiv_memory_loc[regno])
      {
        /* If the address is not directly addressable, or if the address is not
  	 offsettable, then it must be replaced.  */
        if (! force_replace
! 	  && (reg_equiv_address[regno]
! 	      || ! offsettable_memref_p (reg_equiv_mem[regno])))
  	force_replace = 1;
  
        if (force_replace || num_not_at_initial_offset)
--- 6103,6115 ----
    int regno = REGNO (SUBREG_REG (x));
    int reloaded = 0;
  
!   if (reg_equiv_memory_loc (regno))
      {
        /* If the address is not directly addressable, or if the address is not
  	 offsettable, then it must be replaced.  */
        if (! force_replace
! 	  && (reg_equiv_address (regno)
! 	      || ! offsettable_memref_p (reg_equiv_mem (regno))))
  	force_replace = 1;
  
        if (force_replace || num_not_at_initial_offset)
*************** find_reloads_subreg_address (rtx x, int 
*** 6119,6125 ****
  	  /* If the address changes because of register elimination, then
  	     it must be replaced.  */
  	  if (force_replace
! 	      || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
  	    {
  	      unsigned outer_size = GET_MODE_SIZE (GET_MODE (x));
  	      unsigned inner_size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
--- 6119,6125 ----
  	  /* If the address changes because of register elimination, then
  	     it must be replaced.  */
  	  if (force_replace
! 	      || ! rtx_equal_p (tem, reg_equiv_mem (regno)))
  	    {
  	      unsigned outer_size = GET_MODE_SIZE (GET_MODE (x));
  	      unsigned inner_size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
*************** find_reloads_subreg_address (rtx x, int 
*** 6189,6198 ****
  		 If find_reloads_address already completed replaced
  		 the address, there is nothing further to do.  */
  	      if (reloaded == 0
! 		  && reg_equiv_mem[regno] != 0
  		  && !strict_memory_address_addr_space_p
! 			(GET_MODE (x), XEXP (reg_equiv_mem[regno], 0),
! 			 MEM_ADDR_SPACE (reg_equiv_mem[regno])))
  		{
  		  push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0,
  			       base_reg_class (GET_MODE (tem), MEM, SCRATCH),
--- 6189,6198 ----
  		 If find_reloads_address already completed replaced
  		 the address, there is nothing further to do.  */
  	      if (reloaded == 0
! 		  && reg_equiv_mem (regno) != 0
  		  && !strict_memory_address_addr_space_p
! 			(GET_MODE (x), XEXP (reg_equiv_mem (regno), 0),
! 			 MEM_ADDR_SPACE (reg_equiv_mem (regno))))
  		{
  		  push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0,
  			       base_reg_class (GET_MODE (tem), MEM, SCRATCH),
*************** subst_reloads (rtx insn)
*** 6255,6268 ****
  	  for (check_regno = 0; check_regno < max_regno; check_regno++)
  	    {
  #define CHECK_MODF(ARRAY)						\
! 	      gcc_assert (!ARRAY[check_regno]				\
  			  || !loc_mentioned_in_p (r->where,		\
! 						  ARRAY[check_regno]))
  
! 	      CHECK_MODF (reg_equiv_constant);
! 	      CHECK_MODF (reg_equiv_memory_loc);
! 	      CHECK_MODF (reg_equiv_address);
! 	      CHECK_MODF (reg_equiv_mem);
  #undef CHECK_MODF
  	    }
  #endif /* DEBUG_RELOAD */
--- 6255,6268 ----
  	  for (check_regno = 0; check_regno < max_regno; check_regno++)
  	    {
  #define CHECK_MODF(ARRAY)						\
! 	      gcc_assert (!VEC_index (reg_equivs_t, reg_equivs, check_regno).ARRAY		\
  			  || !loc_mentioned_in_p (r->where,		\
! 						  VEC_index (reg_equivs_t, reg_equivs, check_regno).ARRAY))
  
! 	      CHECK_MODF (equiv_constant);
! 	      CHECK_MODF (equiv_memory_loc);
! 	      CHECK_MODF (equiv_address);
! 	      CHECK_MODF (equiv_mem);
  #undef CHECK_MODF
  	    }
  #endif /* DEBUG_RELOAD */
*************** refers_to_regno_for_reload_p (unsigned i
*** 6490,6501 ****
  	 X must therefore either be a constant or be in memory.  */
        if (r >= FIRST_PSEUDO_REGISTER)
  	{
! 	  if (reg_equiv_memory_loc[r])
  	    return refers_to_regno_for_reload_p (regno, endregno,
! 						 reg_equiv_memory_loc[r],
  						 (rtx*) 0);
  
! 	  gcc_assert (reg_equiv_constant[r] || reg_equiv_invariant[r]);
  	  return 0;
  	}
  
--- 6490,6501 ----
  	 X must therefore either be a constant or be in memory.  */
        if (r >= FIRST_PSEUDO_REGISTER)
  	{
! 	  if (reg_equiv_memory_loc (r))
  	    return refers_to_regno_for_reload_p (regno, endregno,
! 						 reg_equiv_memory_loc (r),
  						 (rtx*) 0);
  
! 	  gcc_assert (reg_equiv_constant (r) || reg_equiv_invariant (r));
  	  return 0;
  	}
  
*************** reg_overlap_mentioned_for_reload_p (rtx 
*** 6625,6633 ****
  
        if (regno >= FIRST_PSEUDO_REGISTER)
  	{
! 	  if (reg_equiv_memory_loc[regno])
  	    return refers_to_mem_for_reload_p (in);
! 	  gcc_assert (reg_equiv_constant[regno]);
  	  return 0;
  	}
  
--- 6625,6633 ----
  
        if (regno >= FIRST_PSEUDO_REGISTER)
  	{
! 	  if (reg_equiv_memory_loc (regno))
  	    return refers_to_mem_for_reload_p (in);
! 	  gcc_assert (reg_equiv_constant (regno));
  	  return 0;
  	}
  
*************** refers_to_mem_for_reload_p (rtx x)
*** 6678,6684 ****
  
    if (REG_P (x))
      return (REGNO (x) >= FIRST_PSEUDO_REGISTER
! 	    && reg_equiv_memory_loc[REGNO (x)]);
  
    fmt = GET_RTX_FORMAT (GET_CODE (x));
    for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
--- 6678,6684 ----
  
    if (REG_P (x))
      return (REGNO (x) >= FIRST_PSEUDO_REGISTER
! 	    && reg_equiv_memory_loc (REGNO (x)));
  
    fmt = GET_RTX_FORMAT (GET_CODE (x));
    for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
*************** find_equiv_reg (rtx goal, rtx insn, enum
*** 7032,7038 ****
  		       && ! push_operand (dest, GET_MODE (dest)))
  		return 0;
  	      else if (MEM_P (dest) && regno >= FIRST_PSEUDO_REGISTER
! 		       && reg_equiv_memory_loc[regno] != 0)
  		return 0;
  	      else if (need_stable_sp && push_operand (dest, GET_MODE (dest)))
  		return 0;
--- 7032,7038 ----
  		       && ! push_operand (dest, GET_MODE (dest)))
  		return 0;
  	      else if (MEM_P (dest) && regno >= FIRST_PSEUDO_REGISTER
! 		       && reg_equiv_memory_loc (regno) != 0)
  		return 0;
  	      else if (need_stable_sp && push_operand (dest, GET_MODE (dest)))
  		return 0;
*************** find_equiv_reg (rtx goal, rtx insn, enum
*** 7077,7083 ****
  			       && ! push_operand (dest, GET_MODE (dest)))
  			return 0;
  		      else if (MEM_P (dest) && regno >= FIRST_PSEUDO_REGISTER
! 			       && reg_equiv_memory_loc[regno] != 0)
  			return 0;
  		      else if (need_stable_sp
  			       && push_operand (dest, GET_MODE (dest)))
--- 7077,7083 ----
  			       && ! push_operand (dest, GET_MODE (dest)))
  			return 0;
  		      else if (MEM_P (dest) && regno >= FIRST_PSEUDO_REGISTER
! 			       && reg_equiv_memory_loc (regno) != 0)
  			return 0;
  		      else if (need_stable_sp
  			       && push_operand (dest, GET_MODE (dest)))
Index: reload.h
===================================================================
*** reload.h	(revision 171659)
--- reload.h	(working copy)
*************** struct reload
*** 100,106 ****
    int inc;
    /* A reg for which reload_in is the equivalent.
       If reload_in is a symbol_ref which came from
!      reg_equiv_constant, then this is the pseudo
       which has that symbol_ref as equivalent.  */
    rtx in_reg;
    rtx out_reg;
--- 100,106 ----
    int inc;
    /* A reg for which reload_in is the equivalent.
       If reload_in is a symbol_ref which came from
!      reg_equiv_consant, then this is the pseudo
       which has that symbol_ref as equivalent.  */
    rtx in_reg;
    rtx out_reg;
*************** extern struct target_reload *this_target
*** 204,223 ****
  #define caller_save_initialized_p \
    (this_target_reload->x_caller_save_initialized_p)
  
! extern GTY (()) VEC(rtx,gc) *reg_equiv_memory_loc_vec;
! extern rtx *reg_equiv_constant;
! extern rtx *reg_equiv_invariant;
! extern rtx *reg_equiv_memory_loc;
! extern rtx *reg_equiv_address;
! extern rtx *reg_equiv_mem;
! extern rtx *reg_equiv_alt_mem_list;
! 
! /* Element N is the list of insns that initialized reg N from its equivalent
!    constant or memory slot.  */
! extern GTY((length("reg_equiv_init_size"))) rtx *reg_equiv_init;
! 
! /* The size of the previous array, for GC purposes.  */
! extern GTY(()) int reg_equiv_init_size;
  
  /* All the "earlyclobber" operands of the current insn
     are recorded here.  */
--- 204,265 ----
  #define caller_save_initialized_p \
    (this_target_reload->x_caller_save_initialized_p)
  
! /* Register equivalences.  Indexed by register number.  */
! typedef struct reg_equivs
! {
!   /* The constant value to which pseudo reg N is equivalent,
!      or zero if pseudo reg N is not equivalent to a constant.
!      find_reloads looks at this in order to replace pseudo reg N
!      with the constant it stands for.  */
!   rtx constant;
! 
!   /* An invariant value to which pseudo reg N is equivalent.
!      eliminate_regs_in_insn uses this to replace pseudos in particular
!      contexts.  */
!   rtx invariant;
! 
!   /* A memory location to which pseudo reg N is equivalent,
!      prior to any register elimination (such as frame pointer to stack
!      pointer).  Depending on whether or not it is a valid address, this value
!      is transferred to either equiv_address or equiv_mem.  */
!   rtx memory_loc;
! 
!   /* The address of stack slot to which pseudo reg N is equivalent.
!      This is used when the address is not valid as a memory address
!      (because its displacement is too big for the machine.)  */
!   rtx address;
! 
!   /* The memory slot to which pseudo reg N is equivalent,
!      or zero if pseudo reg N is not equivalent to a memory slot.  */
!   rtx mem;
! 
!   /* An EXPR_LIST of REG_EQUIVs containing MEMs with
!      alternate representations of the location of pseudo reg N.  */
!   rtx alt_mem_list;
! 
!   /* The list of insns that initialized reg N from its equivalent
!      constant or memory slot.  */
!   rtx init;
! } reg_equivs_t;
! 
! #define reg_equiv_constant(ELT) \
!   VEC_index (reg_equivs_t, reg_equivs, (ELT))->constant
! #define reg_equiv_invariant(ELT) \
!   VEC_index (reg_equivs_t, reg_equivs, (ELT))->invariant
! #define reg_equiv_memory_loc(ELT) \
!   VEC_index (reg_equivs_t, reg_equivs, (ELT))->memory_loc
! #define reg_equiv_address(ELT) \
!   VEC_index (reg_equivs_t, reg_equivs, (ELT))->address
! #define reg_equiv_mem(ELT) \
!   VEC_index (reg_equivs_t, reg_equivs, (ELT))->mem
! #define reg_equiv_alt_mem_list(ELT) \
!   VEC_index (reg_equivs_t, reg_equivs, (ELT))->alt_mem_list
! #define reg_equiv_init(ELT) \
!   VEC_index (reg_equivs_t, reg_equivs, (ELT))->init
! 
! DEF_VEC_O(reg_equivs_t);
! DEF_VEC_ALLOC_O(reg_equivs_t, gc);
! extern VEC(reg_equivs_t,gc) *reg_equivs;
  
  /* All the "earlyclobber" operands of the current insn
     are recorded here.  */
*************** extern void debug_reload (void);
*** 420,422 ****
--- 462,471 ----
  /* Compute the actual register we should reload to, in case we're
     reloading to/from a register that is wider than a word.  */
  extern rtx reload_adjust_reg_for_mode (rtx, enum machine_mode);
+ 
+ /* Ideally this function would be in ira.c or reload, but due to dependencies
+    on integrate.h, it's part of integrate.c.  */
+ extern void allocate_initial_values (VEC (reg_equivs_t, gc) *);
+ 
+ /* Allocate or grow the reg_equiv tables, initializing new entries to 0.  */
+ extern void grow_reg_equivs (void);
Index: caller-save.c
===================================================================
*** caller-save.c	(revision 171659)
--- caller-save.c	(working copy)
*************** mark_referenced_regs (rtx *loc, refmarke
*** 1027,1036 ****
        /* If this is a pseudo that did not get a hard register, scan its
  	 memory location, since it might involve the use of another
  	 register, which might be saved.  */
!       else if (reg_equiv_mem[regno] != 0)
! 	mark_referenced_regs (&XEXP (reg_equiv_mem[regno], 0), mark, arg);
!       else if (reg_equiv_address[regno] != 0)
! 	mark_referenced_regs (&reg_equiv_address[regno], mark, arg);
        return;
      }
  
--- 1027,1036 ----
        /* If this is a pseudo that did not get a hard register, scan its
  	 memory location, since it might involve the use of another
  	 register, which might be saved.  */
!       else if (reg_equiv_mem (regno) != 0)
! 	mark_referenced_regs (&XEXP (reg_equiv_mem (regno), 0), mark, arg);
!       else if (reg_equiv_address (regno) != 0)
! 	mark_referenced_regs (&reg_equiv_address (regno), mark, arg);
        return;
      }
  
Index: ira.c
===================================================================
*** ira.c	(revision 171659)
--- ira.c	(working copy)
*************** rtx *ira_reg_equiv_const;
*** 1836,1850 ****
  static void
  find_reg_equiv_invariant_const (void)
  {
!   int i;
    bool invariant_p;
    rtx list, insn, note, constant, x;
  
!   for (i = FIRST_PSEUDO_REGISTER; i < reg_equiv_init_size; i++)
      {
        constant = NULL_RTX;
        invariant_p = false;
!       for (list = reg_equiv_init[i]; list != NULL_RTX; list = XEXP (list, 1))
  	{
  	  insn = XEXP (list, 0);
  	  note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
--- 1836,1850 ----
  static void
  find_reg_equiv_invariant_const (void)
  {
!   unsigned int i;
    bool invariant_p;
    rtx list, insn, note, constant, x;
  
!   for (i = FIRST_PSEUDO_REGISTER; i < VEC_length (reg_equivs_t, reg_equivs); i++)
      {
        constant = NULL_RTX;
        invariant_p = false;
!       for (list = reg_equiv_init (i); list != NULL_RTX; list = XEXP (list, 1))
  	{
  	  insn = XEXP (list, 0);
  	  note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
*************** check_allocation (void)
*** 2104,2120 ****
  static void
  fix_reg_equiv_init (void)
  {
!   int max_regno = max_reg_num ();
!   int i, new_regno;
    rtx x, prev, next, insn, set;
  
!   if (reg_equiv_init_size < max_regno)
      {
!       reg_equiv_init = GGC_RESIZEVEC (rtx, reg_equiv_init, max_regno);
!       while (reg_equiv_init_size < max_regno)
! 	reg_equiv_init[reg_equiv_init_size++] = NULL_RTX;
!       for (i = FIRST_PSEUDO_REGISTER; i < reg_equiv_init_size; i++)
! 	for (prev = NULL_RTX, x = reg_equiv_init[i]; x != NULL_RTX; x = next)
  	  {
  	    next = XEXP (x, 1);
  	    insn = XEXP (x, 0);
--- 2104,2121 ----
  static void
  fix_reg_equiv_init (void)
  {
!   unsigned int max_regno = max_reg_num ();
!   int i, new_regno, max;
    rtx x, prev, next, insn, set;
  
!   if (VEC_length (reg_equivs_t, reg_equivs) < max_regno)
      {
!       max = VEC_length (reg_equivs_t, reg_equivs);
!       grow_reg_equivs ();
!       for (i = FIRST_PSEUDO_REGISTER; i < max; i++)
! 	for (prev = NULL_RTX, x = reg_equiv_init (i);
! 	     x != NULL_RTX;
! 	     x = next)
  	  {
  	    next = XEXP (x, 1);
  	    insn = XEXP (x, 0);
*************** fix_reg_equiv_init (void)
*** 2136,2146 ****
  	    else
  	      {
  		if (prev == NULL_RTX)
! 		  reg_equiv_init[i] = next;
  		else
  		  XEXP (prev, 1) = next;
! 		XEXP (x, 1) = reg_equiv_init[new_regno];
! 		reg_equiv_init[new_regno] = x;
  	      }
  	  }
      }
--- 2137,2147 ----
  	    else
  	      {
  		if (prev == NULL_RTX)
! 		  reg_equiv_init (i) = next;
  		else
  		  XEXP (prev, 1) = next;
! 		XEXP (x, 1) = reg_equiv_init (new_regno);
! 		reg_equiv_init (new_regno) = x;
  	      }
  	  }
      }
*************** no_equiv (rtx reg, const_rtx store ATTRI
*** 2645,2651 ****
       should keep their initialization insns.  */
    if (reg_equiv[regno].is_arg_equivalence)
      return;
!   reg_equiv_init[regno] = NULL_RTX;
    for (; list; list =  XEXP (list, 1))
      {
        rtx insn = XEXP (list, 0);
--- 2646,2652 ----
       should keep their initialization insns.  */
    if (reg_equiv[regno].is_arg_equivalence)
      return;
!   reg_equiv_init (regno) = NULL_RTX;
    for (; list; list =  XEXP (list, 1))
      {
        rtx insn = XEXP (list, 0);
*************** update_equiv_regs (void)
*** 2697,2704 ****
    recorded_label_ref = 0;
  
    reg_equiv = XCNEWVEC (struct equivalence, max_regno);
!   reg_equiv_init = ggc_alloc_cleared_vec_rtx (max_regno);
!   reg_equiv_init_size = max_regno;
  
    init_alias_analysis ();
  
--- 2698,2704 ----
    recorded_label_ref = 0;
  
    reg_equiv = XCNEWVEC (struct equivalence, max_regno);
!   grow_reg_equivs ();
  
    init_alias_analysis ();
  
*************** update_equiv_regs (void)
*** 2763,2770 ****
  
  	      /* Record for reload that this is an equivalencing insn.  */
  	      if (rtx_equal_p (src, XEXP (note, 0)))
! 		reg_equiv_init[regno]
! 		  = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init[regno]);
  
  	      /* Continue normally in case this is a candidate for
  		 replacements.  */
--- 2763,2770 ----
  
  	      /* Record for reload that this is an equivalencing insn.  */
  	      if (rtx_equal_p (src, XEXP (note, 0)))
! 		reg_equiv_init (regno)
! 		  = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init (regno));
  
  	      /* Continue normally in case this is a candidate for
  		 replacements.  */
*************** update_equiv_regs (void)
*** 2864,2871 ****
  	      /* If we haven't done so, record for reload that this is an
  		 equivalencing insn.  */
  	      if (!reg_equiv[regno].is_arg_equivalence)
! 		reg_equiv_init[regno]
! 		  = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init[regno]);
  
  	      /* Record whether or not we created a REG_EQUIV note for a LABEL_REF.
  		 We might end up substituting the LABEL_REF for uses of the
--- 2864,2871 ----
  	      /* If we haven't done so, record for reload that this is an
  		 equivalencing insn.  */
  	      if (!reg_equiv[regno].is_arg_equivalence)
! 		reg_equiv_init (regno)
! 		  = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init (regno));
  
  	      /* Record whether or not we created a REG_EQUIV note for a LABEL_REF.
  		 We might end up substituting the LABEL_REF for uses of the
*************** update_equiv_regs (void)
*** 2965,2971 ****
  	    {
  	      /* This insn makes the equivalence, not the one initializing
  		 the register.  */
! 	      reg_equiv_init[regno]
  		= gen_rtx_INSN_LIST (VOIDmode, insn, NULL_RTX);
  	      df_notes_rescan (init_insn);
  	    }
--- 2965,2971 ----
  	    {
  	      /* This insn makes the equivalence, not the one initializing
  		 the register.  */
! 	      reg_equiv_init (regno)
  		= gen_rtx_INSN_LIST (VOIDmode, insn, NULL_RTX);
  	      df_notes_rescan (init_insn);
  	    }
*************** update_equiv_regs (void)
*** 3068,3074 ****
  		      reg_equiv[regno].init_insns
  			= XEXP (reg_equiv[regno].init_insns, 1);
  
! 		      reg_equiv_init[regno] = NULL_RTX;
  		      bitmap_set_bit (cleared_regs, regno);
  		    }
  		  /* Move the initialization of the register to just before
--- 3068,3074 ----
  		      reg_equiv[regno].init_insns
  			= XEXP (reg_equiv[regno].init_insns, 1);
  
! 		      reg_equiv_init (regno) = NULL_RTX;
  		      bitmap_set_bit (cleared_regs, regno);
  		    }
  		  /* Move the initialization of the register to just before
*************** update_equiv_regs (void)
*** 3101,3107 ****
  		      if (insn == BB_HEAD (bb))
  			BB_HEAD (bb) = PREV_INSN (insn);
  
! 		      reg_equiv_init[regno]
  			= gen_rtx_INSN_LIST (VOIDmode, new_insn, NULL_RTX);
  		      bitmap_set_bit (cleared_regs, regno);
  		    }
--- 3101,3107 ----
  		      if (insn == BB_HEAD (bb))
  			BB_HEAD (bb) = PREV_INSN (insn);
  
! 		      reg_equiv_init (regno)
  			= gen_rtx_INSN_LIST (VOIDmode, new_insn, NULL_RTX);
  		      bitmap_set_bit (cleared_regs, regno);
  		    }
*************** build_insn_chain (void)
*** 3481,3499 ****
    if (dump_file)
      print_insn_chains (dump_file);
  }
- \f
- /* Allocate memory for reg_equiv_memory_loc.  */
- static void
- init_reg_equiv_memory_loc (void)
- {
-   max_regno = max_reg_num ();
  
!   /* And the reg_equiv_memory_loc array.  */
!   VEC_safe_grow (rtx, gc, reg_equiv_memory_loc_vec, max_regno);
!   memset (VEC_address (rtx, reg_equiv_memory_loc_vec), 0,
! 	  sizeof (rtx) * max_regno);
!   reg_equiv_memory_loc = VEC_address (rtx, reg_equiv_memory_loc_vec);
! }
  
  /* All natural loops.  */
  struct loops ira_loops;
--- 3481,3488 ----
    if (dump_file)
      print_insn_chains (dump_file);
  }
  
! \f
  
  /* All natural loops.  */
  struct loops ira_loops;
*************** ira (FILE *f)
*** 3599,3606 ****
    record_loop_exits ();
    current_loops = &ira_loops;
  
-   init_reg_equiv_memory_loc ();
- 
    if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
      fprintf (ira_dump_file, "Building IRA IR\n");
    loops_p = ira_build (optimize
--- 3588,3593 ----
*************** ira (FILE *f)
*** 3670,3676 ****
    if (delete_trivially_dead_insns (get_insns (), max_reg_num ()))
      df_analyze ();
  
!   init_reg_equiv_memory_loc ();
  
    if (max_regno != max_regno_before_ira)
      {
--- 3657,3663 ----
    if (delete_trivially_dead_insns (get_insns (), max_reg_num ()))
      df_analyze ();
  
!   grow_reg_equivs ();
  
    if (max_regno != max_regno_before_ira)
      {
*************** ira (FILE *f)
*** 3680,3686 ****
        regstat_compute_ri ();
      }
  
!   allocate_initial_values (reg_equiv_memory_loc);
  
    overall_cost_before = ira_overall_cost;
    if (ira_conflicts_p)
--- 3667,3673 ----
        regstat_compute_ri ();
      }
  
!   allocate_initial_values (reg_equivs);
  
    overall_cost_before = ira_overall_cost;
    if (ira_conflicts_p)
Index: integrate.c
===================================================================
*** integrate.c	(revision 171659)
--- integrate.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 35,40 ****
--- 35,42 ----
  #include "expr.h"
  #include "output.h"
  #include "recog.h"
+ /* For reg_equivs.  */
+ #include "reload.h"
  #include "integrate.h"
  #include "except.h"
  #include "function.h"
*************** struct rtl_opt_pass pass_initial_value_s
*** 330,336 ****
  /* If the backend knows where to allocate pseudos for hard
     register initial values, register these allocations now.  */
  void
! allocate_initial_values (rtx *reg_equiv_memory_loc)
  {
    if (targetm.allocate_initial_value)
      {
--- 332,338 ----
  /* If the backend knows where to allocate pseudos for hard
     register initial values, register these allocations now.  */
  void
! allocate_initial_values (VEC (reg_equivs_t, gc) *reg_equivs)
  {
    if (targetm.allocate_initial_value)
      {
*************** allocate_initial_values (rtx *reg_equiv_
*** 348,354 ****
  	  if (x && REG_N_SETS (REGNO (ivs->entries[i].pseudo)) <= 1)
  	    {
  	      if (MEM_P (x))
! 		reg_equiv_memory_loc[regno] = x;
  	      else
  		{
  		  basic_block bb;
--- 350,356 ----
  	  if (x && REG_N_SETS (REGNO (ivs->entries[i].pseudo)) <= 1)
  	    {
  	      if (MEM_P (x))
! 		reg_equiv_memory_loc (regno) = x;
  	      else
  		{
  		  basic_block bb;
Index: integrate.h
===================================================================
*** integrate.h	(revision 171659)
--- integrate.h	(working copy)
*************** extern rtx has_hard_reg_initial_val (enu
*** 25,31 ****
  extern rtx get_hard_reg_initial_reg (rtx);
  /* Called from rest_of_compilation.  */
  extern unsigned int emit_initial_value_sets (void);
- extern void allocate_initial_values (rtx *);
  
  /* Check whether there's any attribute in a function declaration that
     makes the function uninlinable.  Returns false if it finds any,
--- 25,30 ----
Index: config/alpha/alpha.c
===================================================================
*** config/alpha/alpha.c	(revision 171659)
--- config/alpha/alpha.c	(working copy)
*************** resolve_reload_operand (rtx op)
*** 555,561 ****
        if (REG_P (tmp)
  	  && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
  	{
! 	  op = reg_equiv_memory_loc[REGNO (tmp)];
  	  if (op == 0)
  	    return 0;
  	}
--- 555,561 ----
        if (REG_P (tmp)
  	  && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
  	{
! 	  op = reg_equiv_memory_loc (REGNO (tmp));
  	  if (op == 0)
  	    return 0;
  	}
Index: config/frv/predicates.md
===================================================================
*** config/frv/predicates.md	(revision 171659)
--- config/frv/predicates.md	(working copy)
***************
*** 55,61 ****
  	tmp = SUBREG_REG (tmp);
        if (GET_CODE (tmp) == REG
  	  && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
! 	op = reg_equiv_memory_loc[REGNO (tmp)];
      }
  
    return op && memory_operand (op, mode);
--- 55,61 ----
  	tmp = SUBREG_REG (tmp);
        if (GET_CODE (tmp) == REG
  	  && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
! 	op = reg_equiv_memory_loc (REGNO (tmp));
      }
  
    return op && memory_operand (op, mode);
Index: config/microblaze/microblaze.c
===================================================================
*** config/microblaze/microblaze.c	(revision 171659)
--- config/microblaze/microblaze.c	(working copy)
*************** double_memory_operand (rtx op, enum mach
*** 326,333 ****
  	  && GET_CODE (op) == REG
  	  && REGNO (op) >= FIRST_PSEUDO_REGISTER
  	  && reg_renumber[REGNO (op)] < 0
! 	  && reg_equiv_mem[REGNO (op)] != 0
! 	  && double_memory_operand (reg_equiv_mem[REGNO (op)], mode))
  	return 1;
        return 0;
      }
--- 326,333 ----
  	  && GET_CODE (op) == REG
  	  && REGNO (op) >= FIRST_PSEUDO_REGISTER
  	  && reg_renumber[REGNO (op)] < 0
! 	  && reg_equiv_mem (REGNO (op)) != 0
! 	  && double_memory_operand (reg_equiv_mem (REGNO (op)), mode))
  	return 1;
        return 0;
      }
Index: config/avr/avr.h
===================================================================
*** config/avr/avr.h	(revision 171659)
--- config/avr/avr.h	(working copy)
*************** do {									    \
*** 393,406 ****
      }									    \
    if (GET_CODE (X) == PLUS						    \
        && REG_P (XEXP (X, 0))						    \
!       && reg_equiv_constant[REGNO (XEXP (X, 0))] == 0			    \
        && GET_CODE (XEXP (X, 1)) == CONST_INT				    \
        && INTVAL (XEXP (X, 1)) >= 1)					    \
      {									    \
        int fit = INTVAL (XEXP (X, 1)) <= (64 - GET_MODE_SIZE (MODE));	    \
        if (fit)								    \
  	{								    \
!           if (reg_equiv_address[REGNO (XEXP (X, 0))] != 0)		    \
  	    {								    \
  	      int regno = REGNO (XEXP (X, 0));				    \
  	      rtx mem = make_memloc (X, regno);				    \
--- 393,406 ----
      }									    \
    if (GET_CODE (X) == PLUS						    \
        && REG_P (XEXP (X, 0))						    \
!       && (reg_equiv_constant (REGNO (XEXP (X, 0))) == 0)		    \
        && GET_CODE (XEXP (X, 1)) == CONST_INT				    \
        && INTVAL (XEXP (X, 1)) >= 1)					    \
      {									    \
        int fit = INTVAL (XEXP (X, 1)) <= (64 - GET_MODE_SIZE (MODE));	    \
        if (fit)								    \
  	{								    \
!           if (reg_equiv_address (REGNO (XEXP (X, 0))) != 0)		    \
  	    {								    \
  	      int regno = REGNO (XEXP (X, 0));				    \
  	      rtx mem = make_memloc (X, regno);				    \
Index: config/xtensa/xtensa.c
===================================================================
*** config/xtensa/xtensa.c	(revision 171659)
--- config/xtensa/xtensa.c	(working copy)
*************** fixup_subreg_mem (rtx x)
*** 1093,1099 ****
      {
        rtx temp =
  	gen_rtx_SUBREG (GET_MODE (x),
! 			reg_equiv_mem [REGNO (SUBREG_REG (x))],
  			SUBREG_BYTE (x));
        x = alter_subreg (&temp);
      }
--- 1093,1099 ----
      {
        rtx temp =
  	gen_rtx_SUBREG (GET_MODE (x),
! 			reg_equiv_mem (REGNO (SUBREG_REG (x))),
  			SUBREG_BYTE (x));
        x = alter_subreg (&temp);
      }
Index: config/mn10300/mn10300.c
===================================================================
*** config/mn10300/mn10300.c	(revision 171659)
--- config/mn10300/mn10300.c	(working copy)
*************** mn10300_secondary_reload (bool in_p, rtx
*** 1430,1436 ****
  
        if (xregno >= FIRST_PSEUDO_REGISTER && xregno != INVALID_REGNUM)
  	{
! 	  addr = reg_equiv_mem [xregno];
  	  if (addr)
  	    addr = XEXP (addr, 0);
  	}
--- 1430,1436 ----
  
        if (xregno >= FIRST_PSEUDO_REGISTER && xregno != INVALID_REGNUM)
  	{
! 	  addr = reg_equiv_mem (xregno);
  	  if (addr)
  	    addr = XEXP (addr, 0);
  	}
Index: config/m68k/m68k.c
===================================================================
*** config/m68k/m68k.c	(revision 171659)
--- config/m68k/m68k.c	(working copy)
*************** emit_move_sequence (rtx *operands, enum 
*** 3729,3735 ****
    if (scratch_reg
        && reload_in_progress && GET_CODE (operand0) == REG
        && REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
!     operand0 = reg_equiv_mem[REGNO (operand0)];
    else if (scratch_reg
  	   && reload_in_progress && GET_CODE (operand0) == SUBREG
  	   && GET_CODE (SUBREG_REG (operand0)) == REG
--- 3729,3735 ----
    if (scratch_reg
        && reload_in_progress && GET_CODE (operand0) == REG
        && REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
!     operand0 = reg_equiv_mem (REGNO (operand0));
    else if (scratch_reg
  	   && reload_in_progress && GET_CODE (operand0) == SUBREG
  	   && GET_CODE (SUBREG_REG (operand0)) == REG
*************** emit_move_sequence (rtx *operands, enum 
*** 3738,3744 ****
       /* We must not alter SUBREG_BYTE (operand0) since that would confuse
  	the code which tracks sets/uses for delete_output_reload.  */
        rtx temp = gen_rtx_SUBREG (GET_MODE (operand0),
! 				 reg_equiv_mem [REGNO (SUBREG_REG (operand0))],
  				 SUBREG_BYTE (operand0));
        operand0 = alter_subreg (&temp);
      }
--- 3738,3744 ----
       /* We must not alter SUBREG_BYTE (operand0) since that would confuse
  	the code which tracks sets/uses for delete_output_reload.  */
        rtx temp = gen_rtx_SUBREG (GET_MODE (operand0),
! 				 reg_equiv_mem (REGNO (SUBREG_REG (operand0))),
  				 SUBREG_BYTE (operand0));
        operand0 = alter_subreg (&temp);
      }
*************** emit_move_sequence (rtx *operands, enum 
*** 3746,3752 ****
    if (scratch_reg
        && reload_in_progress && GET_CODE (operand1) == REG
        && REGNO (operand1) >= FIRST_PSEUDO_REGISTER)
!     operand1 = reg_equiv_mem[REGNO (operand1)];
    else if (scratch_reg
  	   && reload_in_progress && GET_CODE (operand1) == SUBREG
  	   && GET_CODE (SUBREG_REG (operand1)) == REG
--- 3746,3752 ----
    if (scratch_reg
        && reload_in_progress && GET_CODE (operand1) == REG
        && REGNO (operand1) >= FIRST_PSEUDO_REGISTER)
!     operand1 = reg_equiv_mem (REGNO (operand1));
    else if (scratch_reg
  	   && reload_in_progress && GET_CODE (operand1) == SUBREG
  	   && GET_CODE (SUBREG_REG (operand1)) == REG
*************** emit_move_sequence (rtx *operands, enum 
*** 3755,3761 ****
       /* We must not alter SUBREG_BYTE (operand0) since that would confuse
  	the code which tracks sets/uses for delete_output_reload.  */
        rtx temp = gen_rtx_SUBREG (GET_MODE (operand1),
! 				 reg_equiv_mem [REGNO (SUBREG_REG (operand1))],
  				 SUBREG_BYTE (operand1));
        operand1 = alter_subreg (&temp);
      }
--- 3755,3761 ----
       /* We must not alter SUBREG_BYTE (operand0) since that would confuse
  	the code which tracks sets/uses for delete_output_reload.  */
        rtx temp = gen_rtx_SUBREG (GET_MODE (operand1),
! 				 reg_equiv_mem (REGNO (SUBREG_REG (operand1))),
  				 SUBREG_BYTE (operand1));
        operand1 = alter_subreg (&temp);
      }
Index: config/arm/arm.c
===================================================================
*** config/arm/arm.c	(revision 171659)
--- config/arm/arm.c	(working copy)
*************** arm_reload_in_hi (rtx *operands)
*** 10894,10907 ****
  	 are two cases here: the first where there is a simple
  	 stack-slot replacement and a second where the stack-slot is
  	 out of range, or is used as a subreg.  */
!       if (reg_equiv_mem[REGNO (ref)])
  	{
! 	  ref = reg_equiv_mem[REGNO (ref)];
  	  base = find_replacement (&XEXP (ref, 0));
  	}
        else
  	/* The slot is out of range, or was dressed up in a SUBREG.  */
! 	base = reg_equiv_address[REGNO (ref)];
      }
    else
      base = find_replacement (&XEXP (ref, 0));
--- 10894,10907 ----
  	 are two cases here: the first where there is a simple
  	 stack-slot replacement and a second where the stack-slot is
  	 out of range, or is used as a subreg.  */
!       if (reg_equiv_mem (REGNO (ref)))
  	{
! 	  ref = reg_equiv_mem (REGNO (ref));
  	  base = find_replacement (&XEXP (ref, 0));
  	}
        else
  	/* The slot is out of range, or was dressed up in a SUBREG.  */
! 	base = reg_equiv_address (REGNO (ref));
      }
    else
      base = find_replacement (&XEXP (ref, 0));
*************** arm_reload_out_hi (rtx *operands)
*** 11011,11024 ****
  	 are two cases here: the first where there is a simple
  	 stack-slot replacement and a second where the stack-slot is
  	 out of range, or is used as a subreg.  */
!       if (reg_equiv_mem[REGNO (ref)])
  	{
! 	  ref = reg_equiv_mem[REGNO (ref)];
  	  base = find_replacement (&XEXP (ref, 0));
  	}
        else
  	/* The slot is out of range, or was dressed up in a SUBREG.  */
! 	base = reg_equiv_address[REGNO (ref)];
      }
    else
      base = find_replacement (&XEXP (ref, 0));
--- 11011,11024 ----
  	 are two cases here: the first where there is a simple
  	 stack-slot replacement and a second where the stack-slot is
  	 out of range, or is used as a subreg.  */
!       if (reg_equiv_mem (REGNO (ref)))
  	{
! 	  ref = reg_equiv_mem (REGNO (ref));
  	  base = find_replacement (&XEXP (ref, 0));
  	}
        else
  	/* The slot is out of range, or was dressed up in a SUBREG.  */
! 	base = reg_equiv_address (REGNO (ref));
      }
    else
      base = find_replacement (&XEXP (ref, 0));
Index: config/pa/pa.c
===================================================================
*** config/pa/pa.c	(revision 171659)
--- config/pa/pa.c	(working copy)
*************** emit_move_sequence (rtx *operands, enum 
*** 1638,1644 ****
    if (scratch_reg
        && reload_in_progress && GET_CODE (operand0) == REG
        && REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
!     operand0 = reg_equiv_mem[REGNO (operand0)];
    else if (scratch_reg
  	   && reload_in_progress && GET_CODE (operand0) == SUBREG
  	   && GET_CODE (SUBREG_REG (operand0)) == REG
--- 1638,1644 ----
    if (scratch_reg
        && reload_in_progress && GET_CODE (operand0) == REG
        && REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
!     operand0 = reg_equiv_mem (REGNO (operand0));
    else if (scratch_reg
  	   && reload_in_progress && GET_CODE (operand0) == SUBREG
  	   && GET_CODE (SUBREG_REG (operand0)) == REG
*************** emit_move_sequence (rtx *operands, enum 
*** 1647,1653 ****
       /* We must not alter SUBREG_BYTE (operand0) since that would confuse
  	the code which tracks sets/uses for delete_output_reload.  */
        rtx temp = gen_rtx_SUBREG (GET_MODE (operand0),
! 				 reg_equiv_mem [REGNO (SUBREG_REG (operand0))],
  				 SUBREG_BYTE (operand0));
        operand0 = alter_subreg (&temp);
      }
--- 1647,1653 ----
       /* We must not alter SUBREG_BYTE (operand0) since that would confuse
  	the code which tracks sets/uses for delete_output_reload.  */
        rtx temp = gen_rtx_SUBREG (GET_MODE (operand0),
! 				 reg_equiv_mem (REGNO (SUBREG_REG (operand0))),
  				 SUBREG_BYTE (operand0));
        operand0 = alter_subreg (&temp);
      }
*************** emit_move_sequence (rtx *operands, enum 
*** 1655,1661 ****
    if (scratch_reg
        && reload_in_progress && GET_CODE (operand1) == REG
        && REGNO (operand1) >= FIRST_PSEUDO_REGISTER)
!     operand1 = reg_equiv_mem[REGNO (operand1)];
    else if (scratch_reg
  	   && reload_in_progress && GET_CODE (operand1) == SUBREG
  	   && GET_CODE (SUBREG_REG (operand1)) == REG
--- 1655,1661 ----
    if (scratch_reg
        && reload_in_progress && GET_CODE (operand1) == REG
        && REGNO (operand1) >= FIRST_PSEUDO_REGISTER)
!     operand1 = reg_equiv_mem (REGNO (operand1));
    else if (scratch_reg
  	   && reload_in_progress && GET_CODE (operand1) == SUBREG
  	   && GET_CODE (SUBREG_REG (operand1)) == REG
*************** emit_move_sequence (rtx *operands, enum 
*** 1664,1670 ****
       /* We must not alter SUBREG_BYTE (operand0) since that would confuse
  	the code which tracks sets/uses for delete_output_reload.  */
        rtx temp = gen_rtx_SUBREG (GET_MODE (operand1),
! 				 reg_equiv_mem [REGNO (SUBREG_REG (operand1))],
  				 SUBREG_BYTE (operand1));
        operand1 = alter_subreg (&temp);
      }
--- 1664,1670 ----
       /* We must not alter SUBREG_BYTE (operand0) since that would confuse
  	the code which tracks sets/uses for delete_output_reload.  */
        rtx temp = gen_rtx_SUBREG (GET_MODE (operand1),
! 				 reg_equiv_mem (REGNO (SUBREG_REG (operand1))),
  				 SUBREG_BYTE (operand1));
        operand1 = alter_subreg (&temp);
      }
Index: config/vax/vax.c
===================================================================
*** config/vax/vax.c	(revision 171659)
--- config/vax/vax.c	(working copy)
*************** nonindexed_address_p (rtx x, bool strict
*** 1676,1685 ****
    rtx xfoo0;
    if (REG_P (x))
      {
-       extern rtx *reg_equiv_mem;
        if (! reload_in_progress
! 	  || reg_equiv_mem[REGNO (x)] == 0
! 	  || indirectable_address_p (reg_equiv_mem[REGNO (x)], strict, false))
  	return true;
      }
    if (indirectable_constant_address_p (x, false))
--- 1676,1684 ----
    rtx xfoo0;
    if (REG_P (x))
      {
        if (! reload_in_progress
! 	  || reg_equiv_mem (REGNO (x)) == 0
! 	  || indirectable_address_p (reg_equiv_mem (REGNO (x)), strict, false))
  	return true;
      }
    if (indirectable_constant_address_p (x, false))
Index: reload1.c
===================================================================
*** reload1.c	(revision 171659)
--- reload1.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 30,35 ****
--- 30,36 ----
  #include "tm_p.h"
  #include "obstack.h"
  #include "insn-config.h"
+ #include "ggc.h"
  #include "flags.h"
  #include "function.h"
  #include "expr.h"
*************** static regset_head reg_has_output_reload
*** 101,148 ****
     in the current insn.  */
  static HARD_REG_SET reg_is_output_reload;
  
- /* Element N is the constant value to which pseudo reg N is equivalent,
-    or zero if pseudo reg N is not equivalent to a constant.
-    find_reloads looks at this in order to replace pseudo reg N
-    with the constant it stands for.  */
- rtx *reg_equiv_constant;
- 
- /* Element N is an invariant value to which pseudo reg N is equivalent.
-    eliminate_regs_in_insn uses this to replace pseudos in particular
-    contexts.  */
- rtx *reg_equiv_invariant;
- 
- /* Element N is a memory location to which pseudo reg N is equivalent,
-    prior to any register elimination (such as frame pointer to stack
-    pointer).  Depending on whether or not it is a valid address, this value
-    is transferred to either reg_equiv_address or reg_equiv_mem.  */
- rtx *reg_equiv_memory_loc;
- 
- /* We allocate reg_equiv_memory_loc inside a varray so that the garbage
-    collector can keep track of what is inside.  */
- VEC(rtx,gc) *reg_equiv_memory_loc_vec;
- 
- /* Element N is the address of stack slot to which pseudo reg N is equivalent.
-    This is used when the address is not valid as a memory address
-    (because its displacement is too big for the machine.)  */
- rtx *reg_equiv_address;
- 
- /* Element N is the memory slot to which pseudo reg N is equivalent,
-    or zero if pseudo reg N is not equivalent to a memory slot.  */
- rtx *reg_equiv_mem;
- 
- /* Element N is an EXPR_LIST of REG_EQUIVs containing MEMs with
-    alternate representations of the location of pseudo reg N.  */
- rtx *reg_equiv_alt_mem_list;
- 
  /* Widest width in which each pseudo reg is referred to (via subreg).  */
  static unsigned int *reg_max_ref_width;
  
- /* Element N is the list of insns that initialized reg N from its equivalent
-    constant or memory slot.  */
- rtx *reg_equiv_init;
- int reg_equiv_init_size;
- 
  /* Vector to remember old contents of reg_renumber before spilling.  */
  static short *reg_old_renumber;
  
--- 102,110 ----
*************** static int first_label_num;
*** 362,367 ****
--- 324,331 ----
  static char *offsets_known_at;
  static HOST_WIDE_INT (*offsets_at)[NUM_ELIMINABLE_REGS];
  
+ VEC(reg_equivs_t,gc) *reg_equivs;
+ 
  /* Stack of addresses where an rtx has been changed.  We can undo the 
     changes by popping items off the stack and restoring the original
     value at each location. 
*************** replace_pseudos_in (rtx *loc, enum machi
*** 596,609 ****
  	  return;
  	}
  
!       if (reg_equiv_constant[regno])
! 	*loc = reg_equiv_constant[regno];
!       else if (reg_equiv_invariant[regno])
! 	*loc = reg_equiv_invariant[regno];
!       else if (reg_equiv_mem[regno])
! 	*loc = reg_equiv_mem[regno];
!       else if (reg_equiv_address[regno])
! 	*loc = gen_rtx_MEM (GET_MODE (x), reg_equiv_address[regno]);
        else
  	{
  	  gcc_assert (!REG_P (regno_reg_rtx[regno])
--- 560,573 ----
  	  return;
  	}
  
!       if (reg_equiv_constant (regno))
! 	*loc = reg_equiv_constant (regno);
!       else if (reg_equiv_invariant (regno))
! 	*loc = reg_equiv_invariant (regno);
!       else if (reg_equiv_mem (regno))
! 	*loc = reg_equiv_mem (regno);
!       else if (reg_equiv_address (regno))
! 	*loc = gen_rtx_MEM (GET_MODE (x), reg_equiv_address (regno));
        else
  	{
  	  gcc_assert (!REG_P (regno_reg_rtx[regno])
*************** has_nonexceptional_receiver (void)
*** 682,687 ****
--- 646,671 ----
    return false;
  }
  
+ /* Grow (or allocate) the REG_EQUIVS array from its current size (which may be
+    zero elements) to MAX_REG_NUM elements.
+ 
+    Initialize all new fields to NULL and update REG_EQUIVS_SIZE.  */
+ void
+ grow_reg_equivs (void)
+ {
+   int old_size = VEC_length (reg_equivs_t, reg_equivs);
+   int max_regno = max_reg_num ();
+   int i;
+ 
+   VEC_reserve (reg_equivs_t, gc, reg_equivs, max_regno);
+   for (i = old_size; i < max_regno; i++)
+     {
+       VEC_quick_insert (reg_equivs_t, reg_equivs, i, 0);
+       memset (VEC_index (reg_equivs_t, reg_equivs, i), 0, sizeof (reg_equivs_t));
+     }
+     
+ }
+ 
  \f
  /* Global variables used by reload and its subroutines.  */
  
*************** reload (rtx first, int global)
*** 769,774 ****
--- 753,770 ----
        if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i))
  	df_set_regs_ever_live (i, true);
  
+   /* Find all the pseudo registers that didn't get hard regs
+      but do have known equivalent constants or memory slots.
+      These include parameters (known equivalent to parameter slots)
+      and cse'd or loop-moved constant memory addresses.
+ 
+      Record constant equivalents in reg_equiv_constant
+      so they will be substituted by find_reloads.
+      Record memory equivalents in reg_mem_equiv so they can
+      be substituted eventually by altering the REG-rtx's.  */
+ 
+   grow_reg_equivs ();
+   reg_max_ref_width = XCNEWVEC (unsigned int, max_regno);
    reg_old_renumber = XCNEWVEC (short, max_regno);
    memcpy (reg_old_renumber, reg_renumber, max_regno * sizeof (short));
    pseudo_forbidden_regs = XNEWVEC (HARD_REG_SET, max_regno);
*************** reload (rtx first, int global)
*** 882,896 ****
  	 so this problem goes away.  But that's very hairy.  */
  
        for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
! 	if (reg_renumber[i] < 0 && reg_equiv_memory_loc[i])
  	  {
! 	    rtx x = eliminate_regs (reg_equiv_memory_loc[i], VOIDmode,
  				    NULL_RTX);
  
  	    if (strict_memory_address_addr_space_p
  		  (GET_MODE (regno_reg_rtx[i]), XEXP (x, 0),
  		   MEM_ADDR_SPACE (x)))
! 	      reg_equiv_mem[i] = x, reg_equiv_address[i] = 0;
  	    else if (CONSTANT_P (XEXP (x, 0))
  		     || (REG_P (XEXP (x, 0))
  			 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
--- 878,892 ----
  	 so this problem goes away.  But that's very hairy.  */
  
        for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
! 	if (reg_renumber[i] < 0 && reg_equiv_memory_loc (i))
  	  {
! 	    rtx x = eliminate_regs (reg_equiv_memory_loc (i), VOIDmode,
  				    NULL_RTX);
  
  	    if (strict_memory_address_addr_space_p
  		  (GET_MODE (regno_reg_rtx[i]), XEXP (x, 0),
  		   MEM_ADDR_SPACE (x)))
! 	      reg_equiv_mem (i) = x, reg_equiv_address (i) = 0;
  	    else if (CONSTANT_P (XEXP (x, 0))
  		     || (REG_P (XEXP (x, 0))
  			 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
*************** reload (rtx first, int global)
*** 899,905 ****
  			 && (REGNO (XEXP (XEXP (x, 0), 0))
  			     < FIRST_PSEUDO_REGISTER)
  			 && CONSTANT_P (XEXP (XEXP (x, 0), 1))))
! 	      reg_equiv_address[i] = XEXP (x, 0), reg_equiv_mem[i] = 0;
  	    else
  	      {
  		/* Make a new stack slot.  Then indicate that something
--- 895,901 ----
  			 && (REGNO (XEXP (XEXP (x, 0), 0))
  			     < FIRST_PSEUDO_REGISTER)
  			 && CONSTANT_P (XEXP (XEXP (x, 0), 1))))
! 	      reg_equiv_mem (i) = XEXP (x, 0), reg_equiv_mem (i) = 0;
  	    else
  	      {
  		/* Make a new stack slot.  Then indicate that something
*************** reload (rtx first, int global)
*** 908,915 ****
  		   below might change some offset.  reg_equiv_{mem,address}
  		   will be set up for this pseudo on the next pass around
  		   the loop.  */
! 		reg_equiv_memory_loc[i] = 0;
! 		reg_equiv_init[i] = 0;
  		alter_reg (i, -1, true);
  	      }
  	  }
--- 904,911 ----
  		   below might change some offset.  reg_equiv_{mem,address}
  		   will be set up for this pseudo on the next pass around
  		   the loop.  */
! 		reg_equiv_memory_loc (i) = 0;
! 		reg_equiv_init (i) = 0;
  		alter_reg (i, -1, true);
  	      }
  	  }
*************** reload (rtx first, int global)
*** 1023,1032 ****
  
    for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
      {
!       if (reg_renumber[i] < 0 && reg_equiv_init[i] != 0)
  	{
  	  rtx list;
! 	  for (list = reg_equiv_init[i]; list; list = XEXP (list, 1))
  	    {
  	      rtx equiv_insn = XEXP (list, 0);
  
--- 1019,1028 ----
  
    for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
      {
!       if (reg_renumber[i] < 0 && reg_equiv_init (i) != 0)
  	{
  	  rtx list;
! 	  for (list = reg_equiv_init (i); list; list = XEXP (list, 1))
  	    {
  	      rtx equiv_insn = XEXP (list, 0);
  
*************** reload (rtx first, int global)
*** 1094,1104 ****
      {
        rtx addr = 0;
  
!       if (reg_equiv_mem[i])
! 	addr = XEXP (reg_equiv_mem[i], 0);
  
!       if (reg_equiv_address[i])
! 	addr = reg_equiv_address[i];
  
        if (addr)
  	{
--- 1090,1100 ----
      {
        rtx addr = 0;
  
!       if (reg_equiv_mem (i))
! 	addr = XEXP (reg_equiv_mem (i), 0);
  
!       if (reg_equiv_address (i))
! 	addr = reg_equiv_address (i);
  
        if (addr)
  	{
*************** reload (rtx first, int global)
*** 1109,1116 ****
  	      REG_USERVAR_P (reg) = 0;
  	      PUT_CODE (reg, MEM);
  	      XEXP (reg, 0) = addr;
! 	      if (reg_equiv_memory_loc[i])
! 		MEM_COPY_ATTRIBUTES (reg, reg_equiv_memory_loc[i]);
  	      else
  		{
  		  MEM_IN_STRUCT_P (reg) = MEM_SCALAR_P (reg) = 0;
--- 1105,1112 ----
  	      REG_USERVAR_P (reg) = 0;
  	      PUT_CODE (reg, MEM);
  	      XEXP (reg, 0) = addr;
! 	      if (reg_equiv_memory_loc (i))
! 		MEM_COPY_ATTRIBUTES (reg, reg_equiv_memory_loc (i));
  	      else
  		{
  		  MEM_IN_STRUCT_P (reg) = MEM_SCALAR_P (reg) = 0;
*************** reload (rtx first, int global)
*** 1118,1125 ****
  		}
  	      MEM_NOTRAP_P (reg) = 1;
  	    }
! 	  else if (reg_equiv_mem[i])
! 	    XEXP (reg_equiv_mem[i], 0) = addr;
  	}
  
        /* We don't want complex addressing modes in debug insns
--- 1114,1121 ----
  		}
  	      MEM_NOTRAP_P (reg) = 1;
  	    }
! 	  else if (reg_equiv_mem (i))
! 	    XEXP (reg_equiv_mem (i), 0) = addr;
  	}
  
        /* We don't want complex addressing modes in debug insns
*************** reload (rtx first, int global)
*** 1131,1140 ****
  	  rtx equiv = 0;
  	  df_ref use, next;
  
! 	  if (reg_equiv_constant[i])
! 	    equiv = reg_equiv_constant[i];
! 	  else if (reg_equiv_invariant[i])
! 	    equiv = reg_equiv_invariant[i];
  	  else if (reg && MEM_P (reg))
  	    equiv = targetm.delegitimize_address (reg);
  	  else if (reg && REG_P (reg) && (int)REGNO (reg) != i)
--- 1127,1136 ----
  	  rtx equiv = 0;
  	  df_ref use, next;
  
! 	  if (reg_equiv_constant (i))
! 	    equiv = reg_equiv_constant (i);
! 	  else if (reg_equiv_invariant (i))
! 	    equiv = reg_equiv_invariant (i);
  	  else if (reg && MEM_P (reg))
  	    equiv = targetm.delegitimize_address (reg);
  	  else if (reg && REG_P (reg) && (int)REGNO (reg) != i)
*************** reload (rtx first, int global)
*** 1287,1293 ****
  
    /* Indicate that we no longer have known memory locations or constants.  */
    free_reg_equiv ();
!   reg_equiv_init = 0;
    free (reg_max_ref_width);
    free (reg_old_renumber);
    free (pseudo_previous_regs);
--- 1283,1289 ----
  
    /* Indicate that we no longer have known memory locations or constants.  */
    free_reg_equiv ();
! 
    free (reg_max_ref_width);
    free (reg_old_renumber);
    free (pseudo_previous_regs);
*************** calculate_needs_all_insns (int global)
*** 1509,1517 ****
  	  /* Skip insns that only set an equivalence.  */
  	  if (set && REG_P (SET_DEST (set))
  	      && reg_renumber[REGNO (SET_DEST (set))] < 0
! 	      && (reg_equiv_constant[REGNO (SET_DEST (set))]
! 		  || (reg_equiv_invariant[REGNO (SET_DEST (set))]))
! 		      && reg_equiv_init[REGNO (SET_DEST (set))])
  	    continue;
  
  	  /* If needed, eliminate any eliminable registers.  */
--- 1505,1513 ----
  	  /* Skip insns that only set an equivalence.  */
  	  if (set && REG_P (SET_DEST (set))
  	      && reg_renumber[REGNO (SET_DEST (set))] < 0
! 	      && (reg_equiv_constant (REGNO (SET_DEST (set)))
! 		  || (reg_equiv_invariant (REGNO (SET_DEST (set)))))
! 		      && reg_equiv_init (REGNO (SET_DEST (set))))
  	    continue;
  
  	  /* If needed, eliminate any eliminable registers.  */
*************** calculate_needs_all_insns (int global)
*** 1540,1551 ****
  		   || (REG_P (SET_SRC (set)) && REG_P (SET_DEST (set))
  		       && reg_renumber[REGNO (SET_SRC (set))] < 0
  		       && reg_renumber[REGNO (SET_DEST (set))] < 0
! 		       && reg_equiv_memory_loc[REGNO (SET_SRC (set))] != NULL
! 		       && reg_equiv_memory_loc[REGNO (SET_DEST (set))] != NULL
! 		       && rtx_equal_p (reg_equiv_memory_loc
! 				       [REGNO (SET_SRC (set))],
! 				       reg_equiv_memory_loc
! 				       [REGNO (SET_DEST (set))]))))
  		{
  		  if (ira_conflicts_p)
  		    /* Inform IRA about the insn deletion.  */
--- 1536,1545 ----
  		   || (REG_P (SET_SRC (set)) && REG_P (SET_DEST (set))
  		       && reg_renumber[REGNO (SET_SRC (set))] < 0
  		       && reg_renumber[REGNO (SET_DEST (set))] < 0
! 		       && reg_equiv_memory_loc (REGNO (SET_SRC (set))) != NULL
! 		       && reg_equiv_memory_loc (REGNO (SET_DEST (set))) != NULL
! 		       && rtx_equal_p (reg_equiv_memory_loc (REGNO (SET_SRC (set))),
! 				       reg_equiv_memory_loc (REGNO (SET_DEST (set)))))))
  		{
  		  if (ira_conflicts_p)
  		    /* Inform IRA about the insn deletion.  */
*************** calculate_elim_costs_all_insns (void)
*** 1636,1646 ****
  	      /* Skip insns that only set an equivalence.  */
  	      if (set && REG_P (SET_DEST (set))
  		  && reg_renumber[REGNO (SET_DEST (set))] < 0
! 		  && (reg_equiv_constant[REGNO (SET_DEST (set))]
! 		      || (reg_equiv_invariant[REGNO (SET_DEST (set))])))
  		{
  		  unsigned regno = REGNO (SET_DEST (set));
! 		  rtx init = reg_equiv_init[regno];
  		  if (init)
  		    {
  		      rtx t = eliminate_regs_1 (SET_SRC (set), VOIDmode, insn,
--- 1630,1640 ----
  	      /* Skip insns that only set an equivalence.  */
  	      if (set && REG_P (SET_DEST (set))
  		  && reg_renumber[REGNO (SET_DEST (set))] < 0
! 		  && (reg_equiv_constant (REGNO (SET_DEST (set)))
! 		      || reg_equiv_invariant (REGNO (SET_DEST (set)))))
  		{
  		  unsigned regno = REGNO (SET_DEST (set));
! 		  rtx init = reg_equiv_init (regno);
  		  if (init)
  		    {
  		      rtx t = eliminate_regs_1 (SET_SRC (set), VOIDmode, insn,
*************** calculate_elim_costs_all_insns (void)
*** 1664,1672 ****
      }
    for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
      {
!       if (reg_equiv_invariant[i])
  	{
! 	  if (reg_equiv_init[i])
  	    {
  	      int cost = reg_equiv_init_cost[i];
  	      if (dump_file)
--- 1658,1666 ----
      }
    for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
      {
!       if (reg_equiv_invariant (i))
  	{
! 	  if (reg_equiv_init (i))
  	    {
  	      int cost = reg_equiv_init_cost[i];
  	      if (dump_file)
*************** calculate_elim_costs_all_insns (void)
*** 1686,1692 ****
  	}
      }
  
-   free_reg_equiv ();
    free (reg_equiv_init_cost);
  }
  \f
--- 1680,1685 ----
*************** alter_reg (int i, int from_reg, bool don
*** 2173,2181 ****
  
    if (reg_renumber[i] < 0
        && REG_N_REFS (i) > 0
!       && reg_equiv_constant[i] == 0
!       && (reg_equiv_invariant[i] == 0 || reg_equiv_init[i] == 0)
!       && reg_equiv_memory_loc[i] == 0)
      {
        rtx x = NULL_RTX;
        enum machine_mode mode = GET_MODE (regno_reg_rtx[i]);
--- 2166,2175 ----
  
    if (reg_renumber[i] < 0
        && REG_N_REFS (i) > 0
!       && reg_equiv_constant (i) == 0
!       && (reg_equiv_invariant (i) == 0
! 	  || reg_equiv_init (i) == 0)
!       && reg_equiv_memory_loc (i) == 0)
      {
        rtx x = NULL_RTX;
        enum machine_mode mode = GET_MODE (regno_reg_rtx[i]);
*************** alter_reg (int i, int from_reg, bool don
*** 2299,2305 ****
        set_mem_attrs_for_spill (x);
  
        /* Save the stack slot for later.  */
!       reg_equiv_memory_loc[i] = x;
      }
  }
  
--- 2293,2299 ----
        set_mem_attrs_for_spill (x);
  
        /* Save the stack slot for later.  */
!       reg_equiv_memory_loc (i) = x;
      }
  }
  
*************** note_reg_elim_costly (rtx *px, void *dat
*** 2494,2503 ****
  
    if (REG_P (x)
        && REGNO (x) >= FIRST_PSEUDO_REGISTER
!       && reg_equiv_init[REGNO (x)]
!       && reg_equiv_invariant[REGNO (x)])
      {
!       rtx t = reg_equiv_invariant[REGNO (x)];
        rtx new_rtx = eliminate_regs_1 (t, Pmode, insn, true, true);
        int cost = rtx_cost (new_rtx, SET, optimize_bb_for_speed_p (elim_bb));
        int freq = REG_FREQ_FROM_BB (elim_bb);
--- 2488,2497 ----
  
    if (REG_P (x)
        && REGNO (x) >= FIRST_PSEUDO_REGISTER
!       && reg_equiv_init (REGNO (x))
!       && reg_equiv_invariant (REGNO (x)))
      {
!       rtx t = reg_equiv_invariant (REGNO (x));
        rtx new_rtx = eliminate_regs_1 (t, Pmode, insn, true, true);
        int cost = rtx_cost (new_rtx, SET, optimize_bb_for_speed_p (elim_bb));
        int freq = REG_FREQ_FROM_BB (elim_bb);
*************** eliminate_regs_1 (rtx x, enum machine_mo
*** 2582,2595 ****
  
  	}
        else if (reg_renumber && reg_renumber[regno] < 0
! 	       && reg_equiv_invariant && reg_equiv_invariant[regno])
  	{
  	  if (may_use_invariant || (insn && DEBUG_INSN_P (insn)))
! 	    return eliminate_regs_1 (copy_rtx (reg_equiv_invariant[regno]),
  			             mem_mode, insn, true, for_costs);
  	  /* There exists at least one use of REGNO that cannot be
  	     eliminated.  Prevent the defining insn from being deleted.  */
! 	  reg_equiv_init[regno] = NULL_RTX;
  	  if (!for_costs)
  	    alter_reg (regno, -1, true);
  	}
--- 2576,2590 ----
  
  	}
        else if (reg_renumber && reg_renumber[regno] < 0
! 	       && reg_equivs
! 	       && reg_equiv_invariant (regno))
  	{
  	  if (may_use_invariant || (insn && DEBUG_INSN_P (insn)))
! 	    return eliminate_regs_1 (copy_rtx (reg_equiv_invariant (regno)),
  			             mem_mode, insn, true, for_costs);
  	  /* There exists at least one use of REGNO that cannot be
  	     eliminated.  Prevent the defining insn from being deleted.  */
! 	  reg_equiv_init (regno) = NULL_RTX;
  	  if (!for_costs)
  	    alter_reg (regno, -1, true);
  	}
*************** eliminate_regs_1 (rtx x, enum machine_mo
*** 2666,2679 ****
  	    if (GET_CODE (new0) == PLUS && REG_P (new1)
  		&& REGNO (new1) >= FIRST_PSEUDO_REGISTER
  		&& reg_renumber[REGNO (new1)] < 0
! 		&& reg_equiv_constant != 0
! 		&& reg_equiv_constant[REGNO (new1)] != 0)
! 	      new1 = reg_equiv_constant[REGNO (new1)];
  	    else if (GET_CODE (new1) == PLUS && REG_P (new0)
  		     && REGNO (new0) >= FIRST_PSEUDO_REGISTER
  		     && reg_renumber[REGNO (new0)] < 0
! 		     && reg_equiv_constant[REGNO (new0)] != 0)
! 	      new0 = reg_equiv_constant[REGNO (new0)];
  
  	    new_rtx = form_sum (GET_MODE (x), new0, new1);
  
--- 2661,2674 ----
  	    if (GET_CODE (new0) == PLUS && REG_P (new1)
  		&& REGNO (new1) >= FIRST_PSEUDO_REGISTER
  		&& reg_renumber[REGNO (new1)] < 0
! 		&& reg_equivs
! 		&& reg_equiv_constant (REGNO (new1)) != 0)
! 	      new1 = reg_equiv_constant (REGNO (new1));
  	    else if (GET_CODE (new1) == PLUS && REG_P (new0)
  		     && REGNO (new0) >= FIRST_PSEUDO_REGISTER
  		     && reg_renumber[REGNO (new0)] < 0
! 		     && reg_equiv_constant (REGNO (new0)) != 0)
! 	      new0 = reg_equiv_constant (REGNO (new0));
  
  	    new_rtx = form_sum (GET_MODE (x), new0, new1);
  
*************** eliminate_regs_1 (rtx x, enum machine_mo
*** 2835,2848 ****
        if (REG_P (SUBREG_REG (x))
  	  && (GET_MODE_SIZE (GET_MODE (x))
  	      <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
! 	  && reg_equiv_memory_loc != 0
! 	  && reg_equiv_memory_loc[REGNO (SUBREG_REG (x))] != 0)
  	{
  	  new_rtx = SUBREG_REG (x);
  	}
        else
! 	new_rtx = eliminate_regs_1 (SUBREG_REG (x), mem_mode, insn, false,
! 				    for_costs);
  
        if (new_rtx != SUBREG_REG (x))
  	{
--- 2830,2842 ----
        if (REG_P (SUBREG_REG (x))
  	  && (GET_MODE_SIZE (GET_MODE (x))
  	      <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
! 	  && reg_equivs
! 	  && reg_equiv_memory_loc (REGNO (SUBREG_REG (x))) != 0)
  	{
  	  new_rtx = SUBREG_REG (x);
  	}
        else
! 	new_rtx = eliminate_regs_1 (SUBREG_REG (x), mem_mode, insn, false, for_costs);
  
        if (new_rtx != SUBREG_REG (x))
  	{
*************** elimination_effects (rtx x, enum machine
*** 3002,3011 ****
  	      }
  
  	}
!       else if (reg_renumber[regno] < 0 && reg_equiv_constant
! 	       && reg_equiv_constant[regno]
! 	       && ! function_invariant_p (reg_equiv_constant[regno]))
! 	elimination_effects (reg_equiv_constant[regno], mem_mode);
        return;
  
      case PRE_INC:
--- 2996,3006 ----
  	      }
  
  	}
!       else if (reg_renumber[regno] < 0
! 	       && reg_equiv_constant (0)
! 	       && reg_equiv_constant (regno)
! 	       && ! function_invariant_p (reg_equiv_constant (regno)))
! 	elimination_effects (reg_equiv_constant (regno), mem_mode);
        return;
  
      case PRE_INC:
*************** elimination_effects (rtx x, enum machine
*** 3073,3080 ****
        if (REG_P (SUBREG_REG (x))
  	  && (GET_MODE_SIZE (GET_MODE (x))
  	      <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
! 	  && reg_equiv_memory_loc != 0
! 	  && reg_equiv_memory_loc[REGNO (SUBREG_REG (x))] != 0)
  	return;
  
        elimination_effects (SUBREG_REG (x), mem_mode);
--- 3068,3075 ----
        if (REG_P (SUBREG_REG (x))
  	  && (GET_MODE_SIZE (GET_MODE (x))
  	      <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
! 	  && reg_equivs != 0
! 	  && reg_equiv_memory_loc (REGNO (SUBREG_REG (x))) != 0)
  	return;
  
        elimination_effects (SUBREG_REG (x), mem_mode);
*************** init_eliminable_invariants (rtx first, b
*** 4100,4110 ****
    int i;
    rtx insn;
  
!   reg_equiv_constant = XCNEWVEC (rtx, max_regno);
!   reg_equiv_invariant = XCNEWVEC (rtx, max_regno);
!   reg_equiv_mem = XCNEWVEC (rtx, max_regno);
!   reg_equiv_alt_mem_list = XCNEWVEC (rtx, max_regno);
!   reg_equiv_address = XCNEWVEC (rtx, max_regno);
    if (do_subregs)
      reg_max_ref_width = XCNEWVEC (unsigned int, max_regno);
    else
--- 4095,4101 ----
    int i;
    rtx insn;
  
!   grow_reg_equivs ();
    if (do_subregs)
      reg_max_ref_width = XCNEWVEC (unsigned int, max_regno);
    else
*************** init_eliminable_invariants (rtx first, b
*** 4166,4172 ****
  		  /* Always unshare the equivalence, so we can
  		     substitute into this insn without touching the
  		       equivalence.  */
! 		  reg_equiv_memory_loc[i] = copy_rtx (x);
  		}
  	      else if (function_invariant_p (x))
  		{
--- 4157,4163 ----
  		  /* Always unshare the equivalence, so we can
  		     substitute into this insn without touching the
  		       equivalence.  */
! 		  reg_equiv_memory_loc (i) = copy_rtx (x);
  		}
  	      else if (function_invariant_p (x))
  		{
*************** init_eliminable_invariants (rtx first, b
*** 4174,4214 ****
  		    {
  		      /* This is PLUS of frame pointer and a constant,
  			 and might be shared.  Unshare it.  */
! 		      reg_equiv_invariant[i] = copy_rtx (x);
  		      num_eliminable_invariants++;
  		    }
  		  else if (x == frame_pointer_rtx || x == arg_pointer_rtx)
  		    {
! 		      reg_equiv_invariant[i] = x;
  		      num_eliminable_invariants++;
  		    }
  		  else if (LEGITIMATE_CONSTANT_P (x))
! 		    reg_equiv_constant[i] = x;
  		  else
  		    {
! 		      reg_equiv_memory_loc[i]
  			= force_const_mem (GET_MODE (SET_DEST (set)), x);
! 		      if (! reg_equiv_memory_loc[i])
! 			reg_equiv_init[i] = NULL_RTX;
  		    }
  		}
  	      else
  		{
! 		  reg_equiv_init[i] = NULL_RTX;
  		  continue;
  		}
  	    }
  	  else
! 	    reg_equiv_init[i] = NULL_RTX;
  	}
      }
  
    if (dump_file)
      for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
!       if (reg_equiv_init[i])
  	{
  	  fprintf (dump_file, "init_insns for %u: ", i);
! 	  print_inline_rtx (dump_file, reg_equiv_init[i], 20);
  	  fprintf (dump_file, "\n");
  	}
  }
--- 4165,4205 ----
  		    {
  		      /* This is PLUS of frame pointer and a constant,
  			 and might be shared.  Unshare it.  */
! 		      reg_equiv_invariant (i) = copy_rtx (x);
  		      num_eliminable_invariants++;
  		    }
  		  else if (x == frame_pointer_rtx || x == arg_pointer_rtx)
  		    {
! 		      reg_equiv_invariant (i) = x;
  		      num_eliminable_invariants++;
  		    }
  		  else if (LEGITIMATE_CONSTANT_P (x))
! 		    reg_equiv_constant (i) = x;
  		  else
  		    {
! 		      reg_equiv_memory_loc (i)
  			= force_const_mem (GET_MODE (SET_DEST (set)), x);
! 		      if (! reg_equiv_memory_loc (i))
! 			reg_equiv_init (i) = NULL_RTX;
  		    }
  		}
  	      else
  		{
! 		  reg_equiv_init (i) = NULL_RTX;
  		  continue;
  		}
  	    }
  	  else
! 	    reg_equiv_init (i) = NULL_RTX;
  	}
      }
  
    if (dump_file)
      for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
!       if (reg_equiv_init (i))
  	{
  	  fprintf (dump_file, "init_insns for %u: ", i);
! 	  print_inline_rtx (dump_file, reg_equiv_init (i), 20);
  	  fprintf (dump_file, "\n");
  	}
  }
*************** free_reg_equiv (void)
*** 4221,4234 ****
  {
    int i;
  
-   if (reg_equiv_constant)
-     free (reg_equiv_constant);
-   if (reg_equiv_invariant)
-     free (reg_equiv_invariant);
-   reg_equiv_constant = 0;
-   reg_equiv_invariant = 0;
-   VEC_free (rtx, gc, reg_equiv_memory_loc_vec);
-   reg_equiv_memory_loc = 0;
  
    if (offsets_known_at)
      free (offsets_known_at);
--- 4212,4217 ----
*************** free_reg_equiv (void)
*** 4238,4249 ****
    offsets_known_at = 0;
  
    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
!     if (reg_equiv_alt_mem_list[i])
!       free_EXPR_LIST_list (&reg_equiv_alt_mem_list[i]);
!   free (reg_equiv_alt_mem_list);
  
-   free (reg_equiv_mem);
-   free (reg_equiv_address);
  }
  \f
  /* Kick all pseudos out of hard register REGNO.
--- 4221,4231 ----
    offsets_known_at = 0;
  
    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
!     if (reg_equiv_alt_mem_list (i))
!       free_EXPR_LIST_list (&reg_equiv_alt_mem_list (i));
!   VEC_free (reg_equivs_t, gc, reg_equivs);
!   reg_equivs = NULL;
  
  }
  \f
  /* Kick all pseudos out of hard register REGNO.
*************** emit_input_reload_insns (struct insn_cha
*** 7299,7313 ****
  	tmp = SUBREG_REG (tmp);
        if (REG_P (tmp)
  	  && REGNO (tmp) >= FIRST_PSEUDO_REGISTER
! 	  && (reg_equiv_memory_loc[REGNO (tmp)] != 0
! 	      || reg_equiv_constant[REGNO (tmp)] != 0))
  	{
! 	  if (! reg_equiv_mem[REGNO (tmp)]
  	      || num_not_at_initial_offset
  	      || GET_CODE (oldequiv) == SUBREG)
  	    real_oldequiv = rl->in;
  	  else
! 	    real_oldequiv = reg_equiv_mem[REGNO (tmp)];
  	}
  
        tmp = old;
--- 7281,7295 ----
  	tmp = SUBREG_REG (tmp);
        if (REG_P (tmp)
  	  && REGNO (tmp) >= FIRST_PSEUDO_REGISTER
! 	  && (reg_equiv_memory_loc (REGNO (tmp)) != 0
! 	      || reg_equiv_constant (REGNO (tmp)) != 0))
  	{
! 	  if (! reg_equiv_mem (REGNO (tmp))
  	      || num_not_at_initial_offset
  	      || GET_CODE (oldequiv) == SUBREG)
  	    real_oldequiv = rl->in;
  	  else
! 	    real_oldequiv = reg_equiv_mem (REGNO (tmp));
  	}
  
        tmp = old;
*************** emit_input_reload_insns (struct insn_cha
*** 7315,7329 ****
  	tmp = SUBREG_REG (tmp);
        if (REG_P (tmp)
  	  && REGNO (tmp) >= FIRST_PSEUDO_REGISTER
! 	  && (reg_equiv_memory_loc[REGNO (tmp)] != 0
! 	      || reg_equiv_constant[REGNO (tmp)] != 0))
  	{
! 	  if (! reg_equiv_mem[REGNO (tmp)]
  	      || num_not_at_initial_offset
  	      || GET_CODE (old) == SUBREG)
  	    real_old = rl->in;
  	  else
! 	    real_old = reg_equiv_mem[REGNO (tmp)];
  	}
  
        second_reload_reg = rld[secondary_reload].reg_rtx;
--- 7297,7311 ----
  	tmp = SUBREG_REG (tmp);
        if (REG_P (tmp)
  	  && REGNO (tmp) >= FIRST_PSEUDO_REGISTER
! 	  && (reg_equiv_memory_loc (REGNO (tmp)) != 0
! 	      || reg_equiv_constant (REGNO (tmp)) != 0))
  	{
! 	  if (! reg_equiv_mem (REGNO (tmp))
  	      || num_not_at_initial_offset
  	      || GET_CODE (old) == SUBREG)
  	    real_old = rl->in;
  	  else
! 	    real_old = reg_equiv_mem (REGNO (tmp));
  	}
  
        second_reload_reg = rld[secondary_reload].reg_rtx;
*************** emit_input_reload_insns (struct insn_cha
*** 7493,7508 ****
  
        if ((REG_P (oldequiv)
  	   && REGNO (oldequiv) >= FIRST_PSEUDO_REGISTER
! 	   && (reg_equiv_memory_loc[REGNO (oldequiv)] != 0
! 	       || reg_equiv_constant[REGNO (oldequiv)] != 0))
  	  || (GET_CODE (oldequiv) == SUBREG
  	      && REG_P (SUBREG_REG (oldequiv))
  	      && (REGNO (SUBREG_REG (oldequiv))
  		  >= FIRST_PSEUDO_REGISTER)
! 	      && ((reg_equiv_memory_loc
! 		   [REGNO (SUBREG_REG (oldequiv))] != 0)
! 		  || (reg_equiv_constant
! 		      [REGNO (SUBREG_REG (oldequiv))] != 0)))
  	  || (CONSTANT_P (oldequiv)
  	      && (targetm.preferred_reload_class (oldequiv,
  						  REGNO_REG_CLASS (REGNO (reloadreg)))
--- 7475,7488 ----
  
        if ((REG_P (oldequiv)
  	   && REGNO (oldequiv) >= FIRST_PSEUDO_REGISTER
! 	   && (reg_equiv_memory_loc (REGNO (oldequiv)) != 0
! 	       || reg_equiv_constant (REGNO (oldequiv)) != 0))
  	  || (GET_CODE (oldequiv) == SUBREG
  	      && REG_P (SUBREG_REG (oldequiv))
  	      && (REGNO (SUBREG_REG (oldequiv))
  		  >= FIRST_PSEUDO_REGISTER)
! 	      && ((reg_equiv_memory_loc (REGNO (SUBREG_REG (oldequiv))) != 0)
! 		  || (reg_equiv_constant (REGNO (SUBREG_REG (oldequiv))) != 0)))
  	  || (CONSTANT_P (oldequiv)
  	      && (targetm.preferred_reload_class (oldequiv,
  						  REGNO_REG_CLASS (REGNO (reloadreg)))
*************** emit_output_reload_insns (struct insn_ch
*** 7560,7567 ****
        int tertiary_reload = rld[secondary_reload].secondary_out_reload;
  
        if (REG_P (old) && REGNO (old) >= FIRST_PSEUDO_REGISTER
! 	  && reg_equiv_mem[REGNO (old)] != 0)
! 	real_old = reg_equiv_mem[REGNO (old)];
  
        if (secondary_reload_class (0, rl->rclass, mode, real_old) != NO_REGS)
  	{
--- 7540,7547 ----
        int tertiary_reload = rld[secondary_reload].secondary_out_reload;
  
        if (REG_P (old) && REGNO (old) >= FIRST_PSEUDO_REGISTER
! 	  && reg_equiv_mem (REGNO (old)) != 0)
! 	real_old = reg_equiv_mem (REGNO (old));
  
        if (secondary_reload_class (0, rl->rclass, mode, real_old) != NO_REGS)
  	{
*************** delete_output_reload (rtx insn, int j, i
*** 8690,8696 ****
  
    while (GET_CODE (reg) == SUBREG)
      reg = SUBREG_REG (reg);
!   substed = reg_equiv_memory_loc[REGNO (reg)];
  
    /* This is unsafe if the operand occurs more often in the current
       insn than it is inherited.  */
--- 8670,8676 ----
  
    while (GET_CODE (reg) == SUBREG)
      reg = SUBREG_REG (reg);
!   substed = reg_equiv_memory_loc (REGNO (reg));
  
    /* This is unsafe if the operand occurs more often in the current
       insn than it is inherited.  */
*************** delete_output_reload (rtx insn, int j, i
*** 8723,8729 ****
      n_occurrences += count_occurrences (PATTERN (insn),
  					eliminate_regs (substed, VOIDmode,
  							NULL_RTX), 0);
!   for (i1 = reg_equiv_alt_mem_list[REGNO (reg)]; i1; i1 = XEXP (i1, 1))
      {
        gcc_assert (!rtx_equal_p (XEXP (i1, 0), substed));
        n_occurrences += count_occurrences (PATTERN (insn), XEXP (i1, 0), 0);
--- 8703,8709 ----
      n_occurrences += count_occurrences (PATTERN (insn),
  					eliminate_regs (substed, VOIDmode,
  							NULL_RTX), 0);
!   for (i1 = reg_equiv_alt_mem_list (REGNO (reg)); i1; i1 = XEXP (i1, 1))
      {
        gcc_assert (!rtx_equal_p (XEXP (i1, 0), substed));
        n_occurrences += count_occurrences (PATTERN (insn), XEXP (i1, 0), 0);

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Move reg_equiv* arrays into a single VEC structure
  2011-03-30 14:26 Move reg_equiv* arrays into a single VEC structure Jeff Law
@ 2011-03-30 15:02 ` Richard Guenther
  2011-03-30 17:26 ` Richard Sandiford
  2011-03-30 19:50 ` H.J. Lu
  2 siblings, 0 replies; 6+ messages in thread
From: Richard Guenther @ 2011-03-30 15:02 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches

On Wed, Mar 30, 2011 at 4:23 PM, Jeff Law <law@redhat.com> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> As originally discussed here:
>
> http://gcc.gnu.org/ml/gcc-patches/2010-05/msg00987.html
>
> Changes since the original submission:
>
> Per Richi's suggestion I changed the patch to use a GC'd VEC.  I defined
> accessor macros so that a ton of reformatting isn't needed and finally I
> made the appropriate tweaks to the few backends that peeked at the
> reg_equiv arrays.
>
> Given the changes and the length of time since the original submission,
> I think it's probably best to get a fresh approval rather than rely on
> the prior approval.

Looks good to me.

Thanks,
Richard.

> Bootstrapped and regression tested on x86_64-unknown-linux-gnu.
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.11 (GNU/Linux)
> Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
>
> iQEcBAEBAgAGBQJNkzznAAoJEBRtltQi2kC7VgYH/0yTkwWkDRyalReMk3whdIXO
> 8qw5H6c9Gz+Yj+EnnPySKsFIvJKMBTQHIpdCzjTCVWD/Z7LSJwERzzlNCPrQu2au
> dpOoUYCTAwgSW0Us9B+2Bcf2DABinYLV+hgKAKFEVi98CheZe3hZZ14lm5mlYDec
> INYKyfqYHmyahT8fa6ABY2kp0X2xhQhJ0VAGPI34kytJpgLpIdtRwq6PsdsPM0PJ
> frLAY5xIEmJqBB30RaPqnD07u06xZHi+S9gfAJa4LJTUqVALNusYdZzZajKMtF3i
> BCXK4UFk+J2MlM9xZkVWqQiryLc6arVT2bMQcvz7tXTMZkY6ZdZ7sKFBgKea6vM=
> =iMqQ
> -----END PGP SIGNATURE-----
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Move reg_equiv* arrays into a single VEC structure
  2011-03-30 14:26 Move reg_equiv* arrays into a single VEC structure Jeff Law
  2011-03-30 15:02 ` Richard Guenther
@ 2011-03-30 17:26 ` Richard Sandiford
  2011-03-31  1:10   ` Jeff Law
  2011-03-31 15:57   ` Jeff Law
  2011-03-30 19:50 ` H.J. Lu
  2 siblings, 2 replies; 6+ messages in thread
From: Richard Sandiford @ 2011-03-30 17:26 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches

Nice cleanup thanks.  Just noticed a couple of things:

Jeff Law <law@redhat.com> writes:
> *************** struct reload
> *** 100,106 ****
>     int inc;
>     /* A reg for which reload_in is the equivalent.
>        If reload_in is a symbol_ref which came from
> !      reg_equiv_constant, then this is the pseudo
>        which has that symbol_ref as equivalent.  */
>     rtx in_reg;
>     rtx out_reg;
> --- 100,106 ----
>     int inc;
>     /* A reg for which reload_in is the equivalent.
>        If reload_in is a symbol_ref which came from
> !      reg_equiv_consant, then this is the pseudo
>        which has that symbol_ref as equivalent.  */
>     rtx in_reg;
>     rtx out_reg;

Adds typo.

> *************** elimination_effects (rtx x, enum machine
> *** 3002,3011 ****
>   	      }
>   
>   	}
> !       else if (reg_renumber[regno] < 0 && reg_equiv_constant
> ! 	       && reg_equiv_constant[regno]
> ! 	       && ! function_invariant_p (reg_equiv_constant[regno]))
> ! 	elimination_effects (reg_equiv_constant[regno], mem_mode);
>         return;
>   
>       case PRE_INC:
> --- 2996,3006 ----
>   	      }
>   
>   	}
> !       else if (reg_renumber[regno] < 0
> ! 	       && reg_equiv_constant (0)
> ! 	       && reg_equiv_constant (regno)
> ! 	       && ! function_invariant_p (reg_equiv_constant (regno)))
> ! 	elimination_effects (reg_equiv_constant (regno), mem_mode);
>         return;
>   
>       case PRE_INC:

Looks like this should be s/reg_equiv_constant (0)/reg_equivs != 0/.

Richard

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Move reg_equiv* arrays into a single VEC structure
  2011-03-30 14:26 Move reg_equiv* arrays into a single VEC structure Jeff Law
  2011-03-30 15:02 ` Richard Guenther
  2011-03-30 17:26 ` Richard Sandiford
@ 2011-03-30 19:50 ` H.J. Lu
  2 siblings, 0 replies; 6+ messages in thread
From: H.J. Lu @ 2011-03-30 19:50 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches

On Wed, Mar 30, 2011 at 7:23 AM, Jeff Law <law@redhat.com> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> As originally discussed here:
>
> http://gcc.gnu.org/ml/gcc-patches/2010-05/msg00987.html
>
> Changes since the original submission:
>
> Per Richi's suggestion I changed the patch to use a GC'd VEC.  I defined
> accessor macros so that a ton of reformatting isn't needed and finally I
> made the appropriate tweaks to the few backends that peeked at the
> reg_equiv arrays.
>
> Given the changes and the length of time since the original submission,
> I think it's probably best to get a fresh approval rather than rely on
> the prior approval.
>
> Bootstrapped and regression tested on x86_64-unknown-linux-gnu.
>

It breaks GCC bootstrap on Linux/x86:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48371

-- 
H.J.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Move reg_equiv* arrays into a single VEC structure
  2011-03-30 17:26 ` Richard Sandiford
@ 2011-03-31  1:10   ` Jeff Law
  2011-03-31 15:57   ` Jeff Law
  1 sibling, 0 replies; 6+ messages in thread
From: Jeff Law @ 2011-03-31  1:10 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 03/30/11 10:51, Richard Sandiford wrote:
> Nice cleanup thanks.  Just noticed a couple of things:
> 
> Jeff Law <law@redhat.com> writes:
>> *************** struct reload
>> *** 100,106 ****
>>     int inc;
>>     /* A reg for which reload_in is the equivalent.
>>        If reload_in is a symbol_ref which came from
>> !      reg_equiv_constant, then this is the pseudo
>>        which has that symbol_ref as equivalent.  */
>>     rtx in_reg;
>>     rtx out_reg;
>> --- 100,106 ----
>>     int inc;
>>     /* A reg for which reload_in is the equivalent.
>>        If reload_in is a symbol_ref which came from
>> !      reg_equiv_consant, then this is the pseudo
>>        which has that symbol_ref as equivalent.  */
>>     rtx in_reg;
>>     rtx out_reg;
> 
> Adds typo.
Yea.  I had changed the comment when I was using VEC_blah directly, then
introduced the typo when I went to using accessor macros and wanted to
change the comment back to its original form :(

I just checked in a fix for the typo.

> 
>> *************** elimination_effects (rtx x, enum machine
>> *** 3002,3011 ****
>>   	      }
>>   
>>   	}
>> !       else if (reg_renumber[regno] < 0 && reg_equiv_constant
>> ! 	       && reg_equiv_constant[regno]
>> ! 	       && ! function_invariant_p (reg_equiv_constant[regno]))
>> ! 	elimination_effects (reg_equiv_constant[regno], mem_mode);
>>         return;
>>   
>>       case PRE_INC:
>> --- 2996,3006 ----
>>   	      }
>>   
>>   	}
>> !       else if (reg_renumber[regno] < 0
>> ! 	       && reg_equiv_constant (0)
>> ! 	       && reg_equiv_constant (regno)
>> ! 	       && ! function_invariant_p (reg_equiv_constant (regno)))
>> ! 	elimination_effects (reg_equiv_constant (regno), mem_mode);
>>         return;
>>   
>>       case PRE_INC:
> 
> Looks like this should be s/reg_equiv_constant (0)/reg_equivs != 0/.
I thought I'd fixed these.  I certainly remember looking at them and
thinking that can't be right at some point.  I'll look at it again more
closely tomorrow and take appropriate corrective action.

Thanks for the feedback,
Jeff
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJNk8ZSAAoJEBRtltQi2kC7+qYH/R0i1/YC3efnLuQjZ0uieuCU
0b/sMDvP+0xngPbKKn9YviBuNhUv2/poPG1OOOQtolHeZ5c8rftecZKMRgjtmX9W
jYxhuY2OLBBTLLPo4eFDdBbEP/m90RGEBtumeIx1isPTOjQ3LVuBF+9GB+wbnr/W
OLox1MSfPT7GV3pbBeSMiHiKkw5VOeFKd4vBIbefWAPgjO0G8LFexBYWkw04j1F5
tXbuLn/cnSb4PLoRgrCxDv4XS8Wzx1YJcFtcnjn+a2t1HPUARkSYCSn8o94Yytub
k263YKwgRsqwxnrXmGght4+K2kuVjitANa6iX24DWTa+eJBruQ9ObA/f3Xs1P5E=
=SgX4
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Move reg_equiv* arrays into a single VEC structure
  2011-03-30 17:26 ` Richard Sandiford
  2011-03-31  1:10   ` Jeff Law
@ 2011-03-31 15:57   ` Jeff Law
  1 sibling, 0 replies; 6+ messages in thread
From: Jeff Law @ 2011-03-31 15:57 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

[-- Attachment #1: Type: text/plain, Size: 2303 bytes --]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 03/30/11 10:51, Richard Sandiford wrote:
> Nice cleanup thanks.  Just noticed a couple of things:
> 
> Jeff Law <law@redhat.com> writes:
>> *************** struct reload
>> *** 100,106 ****
>>     int inc;
>>     /* A reg for which reload_in is the equivalent.
>>        If reload_in is a symbol_ref which came from
>> !      reg_equiv_constant, then this is the pseudo
>>        which has that symbol_ref as equivalent.  */
>>     rtx in_reg;
>>     rtx out_reg;
>> --- 100,106 ----
>>     int inc;
>>     /* A reg for which reload_in is the equivalent.
>>        If reload_in is a symbol_ref which came from
>> !      reg_equiv_consant, then this is the pseudo
>>        which has that symbol_ref as equivalent.  */
>>     rtx in_reg;
>>     rtx out_reg;
> 
> Adds typo.
> 
>> *************** elimination_effects (rtx x, enum machine
>> *** 3002,3011 ****
>>   	      }
>>   
>>   	}
>> !       else if (reg_renumber[regno] < 0 && reg_equiv_constant
>> ! 	       && reg_equiv_constant[regno]
>> ! 	       && ! function_invariant_p (reg_equiv_constant[regno]))
>> ! 	elimination_effects (reg_equiv_constant[regno], mem_mode);
>>         return;
>>   
>>       case PRE_INC:
>> --- 2996,3006 ----
>>   	      }
>>   
>>   	}
>> !       else if (reg_renumber[regno] < 0
>> ! 	       && reg_equiv_constant (0)
>> ! 	       && reg_equiv_constant (regno)
>> ! 	       && ! function_invariant_p (reg_equiv_constant (regno)))
>> ! 	elimination_effects (reg_equiv_constant (regno), mem_mode);
>>         return;
>>   
>>       case PRE_INC:
> 
> Looks like this should be s/reg_equiv_constant (0)/reg_equivs != 0/.
Bootstrapped & regression tested on x86_64-unknown-linux-gnu.  Installed
as obvious.

jeff

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJNlKPmAAoJEBRtltQi2kC7f1kH/1t6YammyGZdUelSmGgoxLOI
dbmzBULytfTvtR3s6reYtqpLxf5h6zGVEQtSNGxdH+59/X79pFYz/zfJcWRgWYBu
zuua5tAqZdMzGB8xZOOh81U924Pw16nzC3KwX1Bbj7LJFzr95zu7FOvzahR6ikEi
gmsu7liwOu+eEIgYEo9YV1j05XXDwBGsxvJFCuUzH2R6kE9tGafck/E+H5l9+oUw
Rlbza01ukFGJHSimOPdO4TDCYmhR8u/FwMtJWO05wKfhBC6xw2ronI7bo2cKgMUM
GVMNGncfIisKYVa8rzso7aKBnzcPnmG8E4tJ2wvXe+OsvDe5Nj9XWQrRV8mtOHo=
=j7SI
-----END PGP SIGNATURE-----

[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 806 bytes --]

	* reload1.c (elimination_effects): Fix typo in recent change.

Index: reload1.c
===================================================================
*** reload1.c	(revision 171787)
--- reload1.c	(working copy)
*************** elimination_effects (rtx x, enum machine
*** 2997,3003 ****
  
  	}
        else if (reg_renumber[regno] < 0
! 	       && reg_equiv_constant (0)
  	       && reg_equiv_constant (regno)
  	       && ! function_invariant_p (reg_equiv_constant (regno)))
  	elimination_effects (reg_equiv_constant (regno), mem_mode);
--- 2997,3003 ----
  
  	}
        else if (reg_renumber[regno] < 0
! 	       && reg_equivs != 0
  	       && reg_equiv_constant (regno)
  	       && ! function_invariant_p (reg_equiv_constant (regno)))
  	elimination_effects (reg_equiv_constant (regno), mem_mode);

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-03-31 15:55 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-30 14:26 Move reg_equiv* arrays into a single VEC structure Jeff Law
2011-03-30 15:02 ` Richard Guenther
2011-03-30 17:26 ` Richard Sandiford
2011-03-31  1:10   ` Jeff Law
2011-03-31 15:57   ` Jeff Law
2011-03-30 19:50 ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).