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: RFA: Fix PR middle-end/20714


Richard Henderson wrote:



At minimum I'd like "insns" renamed to "first" or something.  My
eyes don't seem to distinguish insn/insns well.  Also, break this
condition up.

Otherwise it looks like an ok approach.


r~


I have appended an updated patch. Testing now on i686-pc-linux-gnu native and
X sh-elf.
2005-05-13  J"orn Rennecke <joern.rennecke@st.com>

	PR middle-end/20714:
	* optabs.c (no_conflict_data): New struct.
	(no_conflict_move_test): New function.
	(emit_no_conflict_block): Use it.

Index: optabs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.278
diff -p -r1.278 optabs.c
*** optabs.c	10 May 2005 16:24:41 -0000	1.278
--- optabs.c	13 May 2005 13:41:57 -0000
*************** emit_unop_insn (int icode, rtx target, r
*** 2943,2948 ****
--- 2943,2981 ----
      emit_move_insn (target, temp);
  }
  
+ struct no_conflict_data
+ {
+   rtx target, first, insn;
+   bool must_stay;
+ };
+ 
+ /* Called via note_stores by emit_no_conflict_block.  Set P->must_stay
+    if the currently examined clobber / store has to stay in the list of
+    insns that constitute the actual no_conflict block.  */
+ static void
+ no_conflict_move_test (rtx dest, rtx set, void *p0)
+ {
+   struct no_conflict_data *p= p0;
+ 
+   /* If this inns directly contributes to setting the target, it must stay.  */
+   if (reg_overlap_mentioned_p (p->target, dest))
+     p->must_stay = true;
+   /* If we haven't committed to keeping any other insns in the list yet,
+      there is nothing more to check.  */
+   else if (p->insn == p->first)
+     return;
+   /* If this insn sets / clobbers a register that feeds one of the insns
+      already in the list, this insn has to stay too.  */
+   else if (reg_mentioned_p (dest, PATTERN (p->first))
+ 	   || reg_used_between_p (dest, p->first, p->insn)
+ 	   /* Likewise if this insn depends on a register set by a previous
+ 	      insn in the list.  */
+ 	   || (GET_CODE (set) == SET
+ 	       && (modified_in_p (SET_SRC (set), p->first)
+ 		   || modified_between_p (SET_SRC (set), p->first, p->insn))))
+     p->must_stay = true;
+ }
+ 
  /* Emit code to perform a series of operations on a multi-word quantity, one
     word at a time.
  
*************** emit_no_conflict_block (rtx insns, rtx t
*** 2988,2995 ****
       these from the list.  */
    for (insn = insns; insn; insn = next)
      {
!       rtx set = 0, note;
!       int i;
  
        next = NEXT_INSN (insn);
  
--- 3021,3028 ----
       these from the list.  */
    for (insn = insns; insn; insn = next)
      {
!       rtx note;
!       struct no_conflict_data data;
  
        next = NEXT_INSN (insn);
  
*************** emit_no_conflict_block (rtx insns, rtx t
*** 3000,3021 ****
        if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
  	remove_note (insn, note);
  
!       if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
! 	  || GET_CODE (PATTERN (insn)) == CLOBBER)
! 	set = PATTERN (insn);
!       else if (GET_CODE (PATTERN (insn)) == PARALLEL)
! 	{
! 	  for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
! 	    if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
! 	      {
! 		set = XVECEXP (PATTERN (insn), 0, i);
! 		break;
! 	      }
! 	}
! 
!       gcc_assert (set);
! 
!       if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
  	{
  	  if (PREV_INSN (insn))
  	    NEXT_INSN (PREV_INSN (insn)) = next;
--- 3033,3044 ----
        if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
  	remove_note (insn, note);
  
!       data.target = target;
!       data.first = insns;
!       data.insn = insn;
!       data.must_stay = 0;
!       note_stores (PATTERN (insn), no_conflict_move_test, &data);
!       if (! data.must_stay)
  	{
  	  if (PREV_INSN (insn))
  	    NEXT_INSN (PREV_INSN (insn)) = next;

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