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]

sched.c (update_flow_info): Add code to ! found_orig_dest case to...


This fixes a latent bug uncovered by the post-reload-flow pass.  An as yet
unsubmitted port has splitters that optimize away no-op moves, and
update_flow_info didn't know how to deal with that.

The problem actually existed before the post-reload-flow pass went in, but
was hidden because the port was emitting SUBREGs of multi-reg hard registers.
This isn't valid, but it wasn't noticed until the post-reload-flow pass
exposed it.

I have already checked in this patch.

1998-10-29  Jim Wilson  <wilson@cygnus.com>

	* sched.c (update_flow_info): Add code to ! found_orig_dest case to
	handle deleted no-op moves of hard registers.
	* haifa-sched.c (update_flow_info): Likewise.

Index: sched.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/sched.c,v
retrieving revision 1.137
diff -p -r1.137 sched.c
*** sched.c	1998/10/24 03:26:55	1.137
--- sched.c	1998/10/30 00:28:09
*************** update_flow_info (notes, first, last, or
*** 4174,4181 ****
  	}
        else if (! found_orig_dest)
  	{
! 	  /* This should never happen.  */
! 	  abort ();
  	}
      }
  
--- 4174,4201 ----
  	}
        else if (! found_orig_dest)
  	{
! 	  int i, regno;
! 
! 	  /* Should never reach here for a pseudo reg.  */
! 	  if (REGNO (orig_dest) >= FIRST_PSEUDO_REGISTER)
! 	    abort ();
! 
! 	  /* This can happen for a hard register, if the splitter
! 	     does not bother to emit instructions which would be no-ops.
! 	     We try to verify that this is the case by checking to see if
! 	     the original instruction uses all of the registers that it
! 	     set.  This case is OK, because deleting a no-op can not affect
! 	     REG_DEAD notes on other insns.  If this is not the case, then
! 	     abort.  */
! 	  
! 	  regno = REGNO (orig_dest);
! 	  for (i = HARD_REGNO_NREGS (regno, GET_MODE (orig_dest)) - 1;
! 	       i >= 0; i--)
! 	    if (! refers_to_regno_p (regno + i, regno + i + 1, orig_insn,
! 				     NULL_PTR))
! 	      break;
! 	  if (i >= 0)
! 	    abort ();
  	}
      }
  
Index: haifa-sched.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/haifa-sched.c,v
retrieving revision 1.100
diff -p -r1.100 haifa-sched.c
*** haifa-sched.c	1998/10/24 03:26:56	1.100
--- haifa-sched.c	1998/10/30 00:28:09
*************** update_flow_info (notes, first, last, or
*** 8342,8349 ****
  	}
        else if (!found_orig_dest)
  	{
! 	  /* This should never happen.  */
! 	  abort ();
  	}
      }
  
--- 8342,8369 ----
  	}
        else if (!found_orig_dest)
  	{
! 	  int i, regno;
! 
! 	  /* Should never reach here for a pseudo reg.  */
! 	  if (REGNO (orig_dest) >= FIRST_PSEUDO_REGISTER)
! 	    abort ();
! 
! 	  /* This can happen for a hard register, if the splitter
! 	     does not bother to emit instructions which would be no-ops.
! 	     We try to verify that this is the case by checking to see if
! 	     the original instruction uses all of the registers that it
! 	     set.  This case is OK, because deleting a no-op can not affect
! 	     REG_DEAD notes on other insns.  If this is not the case, then
! 	     abort.  */
! 	  
! 	  regno = REGNO (orig_dest);
! 	  for (i = HARD_REGNO_NREGS (regno, GET_MODE (orig_dest)) - 1;
! 	       i >= 0; i--)
! 	    if (! refers_to_regno_p (regno + i, regno + i + 1, orig_insn,
! 				     NULL_PTR))
! 	      break;
! 	  if (i >= 0)
! 	    abort ();
  	}
      }
  



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