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: Load hoisting bug


	This patch has been bootstrapped on powerpc-ibm-aix4.3.3.0 and
i686-pc-linux-gnu with no new regressions.

David


	* loop.c (scan_loop, move_movables, count_one_set): Do not
	overlook hard registers when computing statistics.

Index: loop.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/loop.c,v
retrieving revision 1.372
diff -c -p -r1.372 loop.c
*** loop.c	2001/12/13 14:23:21	1.372
--- loop.c	2001/12/17 18:52:17
*************** scan_loop (loop, flags)
*** 607,613 ****
  {
    struct loop_info *loop_info = LOOP_INFO (loop);
    struct loop_regs *regs = LOOP_REGS (loop);
!   int i;
    rtx loop_start = loop->start;
    rtx loop_end = loop->end;
    rtx p;
--- 607,613 ----
  {
    struct loop_info *loop_info = LOOP_INFO (loop);
    struct loop_regs *regs = LOOP_REGS (loop);
!   int i, nregs;
    rtx loop_start = loop->start;
    rtx loop_end = loop->end;
    rtx p;
*************** scan_loop (loop, flags)
*** 893,899 ****
  				   SET_DEST (set), copy_rtx (SET_SRC (set)));
  
  		  delete_insn (p);
! 		  regs->array[regno].set_in_loop = 0;
  		  continue;
  		}
  
--- 893,903 ----
  				   SET_DEST (set), copy_rtx (SET_SRC (set)));
  
  		  delete_insn (p);
! 		  nregs = regno < FIRST_PSEUDO_REGISTER
! 		    ? HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (set)))
! 		    : 1;
! 		  for (i = 0; i < nregs; i++)
! 		    regs->array[regno+i].set_in_loop = 0;
  		  continue;
  		}
  
*************** scan_loop (loop, flags)
*** 923,929 ****
  	      m->savings = regs->array[regno].n_times_set;
  	      if (find_reg_note (p, REG_RETVAL, NULL_RTX))
  		m->savings += libcall_benefit (p);
! 	      regs->array[regno].set_in_loop = move_insn ? -2 : -1;
  	      /* Add M to the end of the chain MOVABLES.  */
  	      loop_movables_add (movables, m);
  
--- 927,937 ----
  	      m->savings = regs->array[regno].n_times_set;
  	      if (find_reg_note (p, REG_RETVAL, NULL_RTX))
  		m->savings += libcall_benefit (p);
! 	      nregs = regno < FIRST_PSEUDO_REGISTER
! 		? HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (set)))
! 		: 1;
! 	      for (i = 0; i < nregs; i++)
! 		regs->array[regno+i].set_in_loop = move_insn ? -2 : -1;
  	      /* Add M to the end of the chain MOVABLES.  */
  	      loop_movables_add (movables, m);
  
*************** scan_loop (loop, flags)
*** 1024,1030 ****
  		  m->match = 0;
  		  m->lifetime = LOOP_REG_LIFETIME (loop, regno);
  		  m->savings = 1;
! 		  regs->array[regno].set_in_loop = -1;
  		  /* Add M to the end of the chain MOVABLES.  */
  		  loop_movables_add (movables, m);
  		}
--- 1032,1042 ----
  		  m->match = 0;
  		  m->lifetime = LOOP_REG_LIFETIME (loop, regno);
  		  m->savings = 1;
! 		  nregs = regno < FIRST_PSEUDO_REGISTER
! 		    ? HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (set)))
! 		    : 1;
! 		  for (i = 0; i < nregs; i++)
! 		    regs->array[regno+i].set_in_loop = -1;
  		  /* Add M to the end of the chain MOVABLES.  */
  		  loop_movables_add (movables, m);
  		}
*************** move_movables (loop, movables, threshold
*** 2145,2151 ****
  
  	      /* The reg set here is now invariant.  */
  	      if (! m->partial)
! 		regs->array[regno].set_in_loop = 0;
  
  	      m->done = 1;
  
--- 2157,2169 ----
  
  	      /* The reg set here is now invariant.  */
  	      if (! m->partial)
! 		{
! 		  int i, n = regno < FIRST_PSEUDO_REGISTER
! 		    ? HARD_REGNO_NREGS (regno, GET_MODE (m->set_dest))
! 		    : 1;
! 		  for (i = 0; i < n; i++)
! 		    regs->array[regno+i].set_in_loop = 0;
! 		}
  
  	      m->done = 1;
  
*************** move_movables (loop, movables, threshold
*** 2205,2211 ****
  		      /* The reg merged here is now invariant,
  			 if the reg it matches is invariant.  */
  		      if (! m->partial)
! 			regs->array[m1->regno].set_in_loop = 0;
  		    }
  	    }
  	  else if (loop_dump_stream)
--- 2223,2235 ----
  		      /* The reg merged here is now invariant,
  			 if the reg it matches is invariant.  */
  		      if (! m->partial)
! 			{
! 			  int i, n = regno < FIRST_PSEUDO_REGISTER
! 			    ? HARD_REGNO_NREGS (regno, GET_MODE (m1->set_dest))
! 			    : 1;
! 			  for (i = 0; i < n; i++)
! 			    regs->array[m1->regno+i].set_in_loop = 0;
! 			}
  		    }
  	    }
  	  else if (loop_dump_stream)
*************** count_one_set (regs, insn, x, last_set)
*** 3445,3467 ****
  	dest = XEXP (dest, 0);
        if (GET_CODE (dest) == REG)
  	{
  	  int regno = REGNO (dest);
! 	  /* If this is the first setting of this reg
! 	     in current basic block, and it was set before,
! 	     it must be set in two basic blocks, so it cannot
! 	     be moved out of the loop.  */
! 	  if (regs->array[regno].set_in_loop > 0
! 	      && last_set == 0)
! 	    regs->array[regno].may_not_optimize = 1;
! 	  /* If this is not first setting in current basic block,
! 	     see if reg was used in between previous one and this.
! 	     If so, neither one can be moved.  */
! 	  if (last_set[regno] != 0
! 	      && reg_used_between_p (dest, last_set[regno], insn))
! 	    regs->array[regno].may_not_optimize = 1;
! 	  if (regs->array[regno].set_in_loop < 127)
! 	    ++regs->array[regno].set_in_loop;
! 	  last_set[regno] = insn;
  	}
      }
  }
--- 3469,3498 ----
  	dest = XEXP (dest, 0);
        if (GET_CODE (dest) == REG)
  	{
+ 	  int i;
  	  int regno = REGNO (dest);
! 	  int nregs = regno < FIRST_PSEUDO_REGISTER
! 	    ? HARD_REGNO_NREGS (regno, GET_MODE (dest))
! 	    : 1;
! 	  for (i = 0; i < nregs; i++)
! 	    {
! 	      /* If this is the first setting of this reg
! 		 in current basic block, and it was set before,
! 		 it must be set in two basic blocks, so it cannot
! 		 be moved out of the loop.  */
! 	      if (regs->array[regno].set_in_loop > 0
! 		  && last_set == 0)
! 		regs->array[regno+i].may_not_optimize = 1;
! 	      /* If this is not first setting in current basic block,
! 		 see if reg was used in between previous one and this.
! 		 If so, neither one can be moved.  */
! 	      if (last_set[regno] != 0
! 		  && reg_used_between_p (dest, last_set[regno], insn))
! 		regs->array[regno+i].may_not_optimize = 1;
! 	      if (regs->array[regno+i].set_in_loop < 127)
! 		++regs->array[regno+i].set_in_loop;
! 	      last_set[regno+i] = insn;
! 	    }
  	}
      }
  }


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