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]

patch for local alloc / global alloc / reload problem


This change allows gcc to attempt and find a hard register
for a pseudo register which was allocated to a hard register
by local-alloc and later spilled by reload.  The effect of
the patch can be seen by compiling:

  int
  func(int a, int b, int c, int d)
    {
    int g;
    int h;
    int i;
    int j;
    int m;

    g = a;
    h = b;
    i = c;
    j = d;

    for (m = g; m < j; m += j) {
      j = j / m;
      m %= g * j;
      }

    return m;
    }

on an x86 using -O -S -da and looking at the resulting .greg
and .s files.  Without the patch a local register is spilled
to the stack, with the patch the register is spilled and ends
up back in a hard register.

Notes:

  1) There may be some overlap between this patch and work
     that Bernd Schmidt is doing.

  2) I could use a quick description of what reg_may_share
     does.

ChangeLog:

Wed Aug 26 00:04:27 EDT 1998  John Wehle  (john@feith.com)

	* global.c (global_alloc): Assign allocation-numbers
	even for registers allocated by local_alloc in case
	they are later spilled and retry_global_alloc is called.
	(mark_reg_store, mark_reg_clobber,
	mark_reg_conflicts, mark_reg_death): Always record a
	conflict with a pseudo register even if it has been
	assigned to a hard register.
	(dump_conflicts): Don't dump pseudo registers already
	assigned to a hard register.

Enjoy!

-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/global.c.ORIGINAL	Sun Aug 23 18:02:40 1998
--- gcc/global.c	Wed Aug 26 00:01:52 1998
***************
*** 389,401 ****
      /* Note that reg_live_length[i] < 0 indicates a "constant" reg
         that we are supposed to refrain from putting in a hard reg.
         -2 means do make an allocno but don't allocate it.  */
!     if (REG_N_REFS (i) != 0 && reg_renumber[i] < 0 && REG_LIVE_LENGTH (i) != -1
  	/* Don't allocate pseudos that cross calls,
  	   if this function receives a nonlocal goto.  */
  	&& (! current_function_has_nonlocal_label
  	    || REG_N_CALLS_CROSSED (i) == 0))
        {
! 	if (reg_may_share[i] && reg_allocno[reg_may_share[i]] >= 0)
  	  reg_allocno[i] = reg_allocno[reg_may_share[i]];
  	else
  	  reg_allocno[i] = max_allocno++;
--- 389,402 ----
      /* Note that reg_live_length[i] < 0 indicates a "constant" reg
         that we are supposed to refrain from putting in a hard reg.
         -2 means do make an allocno but don't allocate it.  */
!     if (REG_N_REFS (i) != 0
! 	&& REG_LIVE_LENGTH (i) != -1
  	/* Don't allocate pseudos that cross calls,
  	   if this function receives a nonlocal goto.  */
  	&& (! current_function_has_nonlocal_label
  	    || REG_N_CALLS_CROSSED (i) == 0))
        {
! 	if (reg_renumber[i] < 0 && reg_may_share[i] && reg_allocno[reg_may_share[i]] >= 0)
  	  reg_allocno[i] = reg_allocno[reg_may_share[i]];
  	else
  	  reg_allocno[i] = max_allocno++;
***************
*** 433,439 ****
    bzero ((char *) local_reg_live_length, sizeof local_reg_live_length);
    bzero ((char *) local_reg_n_refs, sizeof local_reg_n_refs);
    for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
!     if (reg_allocno[i] < 0 && reg_renumber[i] >= 0)
        {
  	int regno = reg_renumber[i];
  	int endregno = regno + HARD_REGNO_NREGS (regno, PSEUDO_REGNO_MODE (i));
--- 434,440 ----
    bzero ((char *) local_reg_live_length, sizeof local_reg_live_length);
    bzero ((char *) local_reg_n_refs, sizeof local_reg_n_refs);
    for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
!     if (reg_renumber[i] >= 0)
        {
  	int regno = reg_renumber[i];
  	int endregno = regno + HARD_REGNO_NREGS (regno, PSEUDO_REGNO_MODE (i));
***************
*** 561,567 ****
  	 except for parameters marked with reg_live_length[regno] == -2.  */
  
        for (i = 0; i < max_allocno; i++)
! 	if (REG_LIVE_LENGTH (allocno_reg[allocno_order[i]]) >= 0)
  	  {
  	    /* If we have more than one register class,
  	       first try allocating in the class that is cheapest
--- 562,569 ----
  	 except for parameters marked with reg_live_length[regno] == -2.  */
  
        for (i = 0; i < max_allocno; i++)
! 	if (reg_renumber[allocno_reg[allocno_order[i]]] < 0
! 	    && REG_LIVE_LENGTH (allocno_reg[allocno_order[i]]) >= 0)
  	  {
  	    /* If we have more than one register class,
  	       first try allocating in the class that is cheapest
***************
*** 1364,1372 ****
  
    regno = REGNO (reg);
  
-   if (reg_renumber[regno] >= 0)
-     regno = reg_renumber[regno] /* + word */;
- 
    /* Either this is one of the max_allocno pseudo regs not allocated,
       or it is or has a hardware reg.  First handle the pseudo-regs.  */
    if (regno >= FIRST_PSEUDO_REGISTER)
--- 1366,1371 ----
***************
*** 1377,1384 ****
  	  record_one_conflict (regno);
  	}
      }
    /* Handle hardware regs (and pseudos allocated to hard regs).  */
!   else if (! fixed_regs[regno])
      {
        register int last = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
        while (regno < last)
--- 1376,1387 ----
  	  record_one_conflict (regno);
  	}
      }
+ 
+   if (reg_renumber[regno] >= 0)
+     regno = reg_renumber[regno] /* + word */;
+ 
    /* Handle hardware regs (and pseudos allocated to hard regs).  */
!   if (regno < FIRST_PSEUDO_REGISTER && ! fixed_regs[regno])
      {
        register int last = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
        while (regno < last)
***************
*** 1420,1428 ****
  
    regno = REGNO (reg);
  
-   if (reg_renumber[regno] >= 0)
-     regno = reg_renumber[regno] /* + word */;
- 
    /* Either this is one of the max_allocno pseudo regs not allocated,
       or it is or has a hardware reg.  First handle the pseudo-regs.  */
    if (regno >= FIRST_PSEUDO_REGISTER)
--- 1423,1428 ----
***************
*** 1433,1440 ****
  	  record_one_conflict (regno);
  	}
      }
    /* Handle hardware regs (and pseudos allocated to hard regs).  */
!   else if (! fixed_regs[regno])
      {
        register int last = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
        while (regno < last)
--- 1433,1444 ----
  	  record_one_conflict (regno);
  	}
      }
+ 
+   if (reg_renumber[regno] >= 0)
+     regno = reg_renumber[regno] /* + word */;
+ 
    /* Handle hardware regs (and pseudos allocated to hard regs).  */
!   if (regno < FIRST_PSEUDO_REGISTER && ! fixed_regs[regno])
      {
        register int last = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
        while (regno < last)
***************
*** 1463,1471 ****
  
    regno = REGNO (reg);
  
-   if (reg_renumber[regno] >= 0)
-     regno = reg_renumber[regno];
- 
    /* Either this is one of the max_allocno pseudo regs not allocated,
       or it is or has a hardware reg.  First handle the pseudo-regs.  */
    if (regno >= FIRST_PSEUDO_REGISTER)
--- 1467,1472 ----
***************
*** 1473,1480 ****
        if (reg_allocno[regno] >= 0)
  	record_one_conflict (regno);
      }
    /* Handle hardware regs (and pseudos allocated to hard regs).  */
!   else if (! fixed_regs[regno])
      {
        register int last = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
        while (regno < last)
--- 1474,1485 ----
        if (reg_allocno[regno] >= 0)
  	record_one_conflict (regno);
      }
+ 
+   if (reg_renumber[regno] >= 0)
+     regno = reg_renumber[regno];
+ 
    /* Handle hardware regs (and pseudos allocated to hard regs).  */
!   if (regno < FIRST_PSEUDO_REGISTER && ! fixed_regs[regno])
      {
        register int last = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
        while (regno < last)
***************
*** 1494,1503 ****
  {
    register int regno = REGNO (reg);
  
-   /* For pseudo reg, see if it has been assigned a hardware reg.  */
-   if (reg_renumber[regno] >= 0)
-     regno = reg_renumber[regno];
- 
    /* Either this is one of the max_allocno pseudo regs not allocated,
       or it is a hardware reg.  First handle the pseudo-regs.  */
    if (regno >= FIRST_PSEUDO_REGISTER)
--- 1499,1504 ----
***************
*** 1505,1512 ****
        if (reg_allocno[regno] >= 0)
  	CLEAR_ALLOCNO_LIVE (reg_allocno[regno]);
      }
    /* Handle hardware regs (and pseudos allocated to hard regs).  */
!   else if (! fixed_regs[regno])
      {
        /* Pseudo regs already assigned hardware regs are treated
  	 almost the same as explicit hardware regs.  */
--- 1506,1518 ----
        if (reg_allocno[regno] >= 0)
  	CLEAR_ALLOCNO_LIVE (reg_allocno[regno]);
      }
+ 
+   /* For pseudo reg, see if it has been assigned a hardware reg.  */
+   if (reg_renumber[regno] >= 0)
+     regno = reg_renumber[regno];
+ 
    /* Handle hardware regs (and pseudos allocated to hard regs).  */
!   if (regno < FIRST_PSEUDO_REGISTER && ! fixed_regs[regno])
      {
        /* Pseudo regs already assigned hardware regs are treated
  	 almost the same as explicit hardware regs.  */
***************
*** 1661,1670 ****
  {
    register int i;
    register int has_preferences;
!   fprintf (file, ";; %d regs to allocate:", max_allocno);
    for (i = 0; i < max_allocno; i++)
      {
        int j;
        fprintf (file, " %d", allocno_reg[allocno_order[i]]);
        for (j = 0; j < max_regno; j++)
  	if (reg_allocno[j] == allocno_order[i]
--- 1667,1686 ----
  {
    register int i;
    register int has_preferences;
!   register int nregs;
!   nregs = 0;
!   for (i = 0; i < max_allocno; i++)
!     {
!       if (reg_renumber[allocno_reg[allocno_order[i]]] >= 0)
!         continue;
!       nregs++;
!     }
!   fprintf (file, ";; %d regs to allocate:", nregs);
    for (i = 0; i < max_allocno; i++)
      {
        int j;
+       if (reg_renumber[allocno_reg[allocno_order[i]]] >= 0)
+ 	continue;
        fprintf (file, " %d", allocno_reg[allocno_order[i]]);
        for (j = 0; j < max_regno; j++)
  	if (reg_allocno[j] == allocno_order[i]
***************
*** 1678,1683 ****
--- 1694,1701 ----
    for (i = 0; i < max_allocno; i++)
      {
        register int j;
+       if (reg_renumber[allocno_reg[i]] >= 0)
+ 	continue;
        fprintf (file, ";; %d conflicts:", allocno_reg[i]);
        for (j = 0; j < max_allocno; j++)
  	if (CONFLICTP (i, j) || CONFLICTP (j, i))
-------------------------------------------------------------------------
|   Feith Systems  |   Voice: 1-215-646-8000  |  Email: john@feith.com  |
|    John Wehle    |     Fax: 1-215-540-5495  |                         |
-------------------------------------------------------------------------



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