This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: cprop testing


On Fri, Dec 14, 2001 at 04:53:33PM -0500, David Edelsohn wrote:
> 	By the way, I think if you invoke a PowerPC Linux or eABI compiler
> with -mcpu=common, it should generate code similar to the default AIX
> achitecture, although still not using the TOC, etc.  I don't know if that
> simplifies your debug environment.

Not really.  The following appears to cure the expmed.c abort.
I've restarted the aix bootstrap, but that machine seems to be
dreadfully slow compared to my x86 linux boxes...


r~



	* regrename.c (struct value_data): Add max_value_regs.
	(init_value_data): Initialize it.
	(kill_value): Kill values that overlap the dying register.
	(set_value_regno): New.
	(kill_set_value, kill_autoinc_value, copy_value): Use it.
	(copyprop_hardreg_forward_1): Kill earlyclobber operands
	before looking at inputs.

Index: regrename.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regrename.c,v
retrieving revision 1.27
diff -c -p -d -r1.27 regrename.c
*** regrename.c	2001/12/14 06:47:56	1.27
--- regrename.c	2001/12/14 22:13:53
*************** struct value_data_entry
*** 984,993 ****
--- 984,996 ----
  struct value_data
  {
    struct value_data_entry e[FIRST_PSEUDO_REGISTER];
+   unsigned int max_value_regs;
  };
  
  static void kill_value_regno PARAMS ((unsigned, struct value_data *));
  static void kill_value PARAMS ((rtx, struct value_data *));
+ static void set_value_regno PARAMS ((unsigned, enum machine_mode,
+ 				     struct value_data *));
  static void init_value_data PARAMS ((struct value_data *));
  static void kill_clobbered_value PARAMS ((rtx, rtx, void *));
  static void kill_set_value PARAMS ((rtx, rtx, void *));
*************** kill_value (x, vd)
*** 1054,1066 ****
      {
        unsigned int regno = REGNO (x);
        unsigned int n = HARD_REGNO_NREGS (regno, GET_MODE (x));
!       unsigned int i;
  
        for (i = 0; i < n; ++i)
  	kill_value_regno (regno + i, vd);
      }
  }
  
  /* Initialize VD such that there are no known relationships between regs.  */
  
  static void
--- 1057,1102 ----
      {
        unsigned int regno = REGNO (x);
        unsigned int n = HARD_REGNO_NREGS (regno, GET_MODE (x));
!       unsigned int i, j;
  
+       /* Kill the value we're told to kill.  */
        for (i = 0; i < n; ++i)
  	kill_value_regno (regno + i, vd);
+ 
+       /* Kill everything that overlapped what we're told to kill.  */
+       if (regno < vd->max_value_regs)
+ 	j = 0;
+       else
+ 	j = regno - vd->max_value_regs;
+       for (; j < regno; ++j)
+ 	{
+ 	  if (vd->e[j].mode == VOIDmode)
+ 	    continue;
+ 	  n = HARD_REGNO_NREGS (regno, vd->e[j].mode);
+ 	  if (j + n > regno)
+ 	    for (i = 0; i < n; ++i)
+ 	      kill_value_regno (j + i, vd);
+ 	}
      }
  }
  
+ /* Remember that REGNO is valid in MODE.  */
+ 
+ static void
+ set_value_regno (regno, mode, vd)
+      unsigned int regno;
+      enum machine_mode mode;
+      struct value_data *vd;
+ {
+   unsigned int nregs;
+ 
+   vd->e[regno].mode = mode;
+ 
+   nregs = HARD_REGNO_NREGS (regno, mode);
+   if (nregs > vd->max_value_regs)
+     vd->max_value_regs = nregs;
+ }
+ 
  /* Initialize VD such that there are no known relationships between regs.  */
  
  static void
*************** init_value_data (vd)
*** 1074,1079 ****
--- 1110,1116 ----
        vd->e[i].oldest_regno = i;
        vd->e[i].next_regno = INVALID_REGNUM;
      }
+   vd->max_value_regs = 0;
  }
  
  /* Called through note_stores.  If X is clobbered, kill its value.  */
*************** kill_set_value (x, set, data)
*** 1102,1108 ****
    if (GET_CODE (set) != CLOBBER && REG_P (x))
      {
        kill_value (x, vd);
!       vd->e[REGNO (x)].mode = GET_MODE (x);
      }
  }
  
--- 1139,1145 ----
    if (GET_CODE (set) != CLOBBER && REG_P (x))
      {
        kill_value (x, vd);
!       set_value_regno (REGNO (x), GET_MODE (x), vd);
      }
  }
  
*************** kill_autoinc_value (px, data)
*** 1122,1128 ****
      {
        x = XEXP (x, 0);
        kill_value (x, vd);
!       vd->e[REGNO (x)].mode = Pmode;
        return -1;
      }
  
--- 1159,1165 ----
      {
        x = XEXP (x, 0);
        kill_value (x, vd);
!       set_value_regno (REGNO (x), Pmode, vd);
        return -1;
      }
  
*************** copy_value (dest, src, vd)
*** 1160,1166 ****
       assign it now and assume the value came from an input argument
       or somesuch.  */
    if (vd->e[sr].mode == VOIDmode)
!     vd->e[sr].mode = vd->e[dr].mode;
  
    /* Link DR at the end of the value chain used by SR.  */
  
--- 1197,1203 ----
       assign it now and assume the value came from an input argument
       or somesuch.  */
    if (vd->e[sr].mode == VOIDmode)
!     set_value_regno (sr, vd->e[dr].mode, vd);
  
    /* Link DR at the end of the value chain used by SR.  */
  
*************** copyprop_hardreg_forward_1 (bb, vd)
*** 1425,1430 ****
--- 1462,1472 ----
        /* Kill all auto-incremented values.  */
        /* ??? REG_INC is useless, since stack pushes aren't done that way.  */
        for_each_rtx (&PATTERN (insn), kill_autoinc_value, vd);
+ 
+       /* Kill all early-clobbered operands.  */
+       for (i = 0; i < n_ops; i++)
+ 	if (recog_op_alt[i][alt].earlyclobber)
+ 	  kill_value (recog_data.operand[i], vd);
  
        /* Special-case plain move instructions, since we may well
  	 be able to do the move from a different register class.  */


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