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]

RFA: Fix for PR


Hi Guys,

  Attached is a patch that fixes PR 27346, a scheduling bug on the 3.4
  branch which is exposed for the v850 toolchain.  The problem is that
  when add_branch_dependences() is scanning backwards from the end of
  a basic block to find the first instruction that it can safely
  schedule it does not take into account that for cc0 targets there can
  be multiple cc0 setter/consumer pairs and that none of these pairs
  should be split up.

  The patch fixes the problem by extending the search backwards until
  the first cc0 setter in the basic block is found and marking it, and
  all instructions following, as CANT_MOVE.

  Tested with no regressions on a v850-elf and a i386-pc-linux-gnu
  toolchain.

  Please may I apply this patch to the 3.4 branch ?

Cheers
  Nick

gcc/ChangeLog
2006-01-10  Nick Clifton  <nickc@redhat.com>

	PR 27346
	* sched-rgn.c (add_branch_dependences): For cc0 targets extend
	the dependencies inside a block back to the very first cc0 setter
	in the block.

Index: sched-rgn.c
===================================================================
--- sched-rgn.c	(revision 109541)
+++ sched-rgn.c	(working copy)
@@ -2078,6 +2078,42 @@
       insn = PREV_INSN (insn);
     }
 
+#ifdef HAVE_cc0
+  /* There may be other cc0 setters earlier on in this block.
+     Look for them and include them in the set not to be disturbed.  */
+  if (insn != head && last != NULL_RTX)
+    {
+      rtx earlier_cc0_setter = NULL_RTX;
+
+      for (insn = last; insn != NULL_RTX && insn != head;)
+	{
+	  insn = prev_nonnote_insn (insn);
+	  if (sets_cc0_p (insn))
+	    earlier_cc0_setter = insn;
+	}
+
+      if (earlier_cc0_setter != NULL_RTX)      
+	{
+	  insn = last;
+	  do
+	    {
+	      insn = prev_nonnote_insn (insn);
+
+	      if (last != 0 && ! find_insn_list (insn, LOG_LINKS (last)))
+		{
+		  add_dependence (last, insn, REG_DEP_ANTI);
+		  INSN_REF_COUNT (insn)++;
+		}
+	      
+	      CANT_MOVE (insn) = 1;
+	      
+	      last = insn;
+	    }
+	  while (insn != earlier_cc0_setter);
+	}
+    }
+#endif
+
   /* Make sure these insns are scheduled last in their block.  */
   insn = last;
   if (insn != 0)


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