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]

Fix gen_nop_type abort in ia64.c


Consider this situation: we have an M and an L type insn ready for
scheduling.  We select an MLX bundle and schedule the M.  As a
result of scheduling the M insn, an asm instuction becomes ready.
When we next call ia64_sched_reorder, we'll immediately emit the
asm, without looking at the other ready insns.  The problem is that
this ends the cycle, and we have an unfilled L and X slot - and we
abort when try to generate an L type nop instruction (since we
shouldn't select MLX if there's no L type insn).

The solution is to defer scheduling asms until nothing else is
ready.  Tested like the previous patches.


Bernd

	* config/ia64/ia64.c (ia64_sched_reorder): Defer scheduling of
	asms if other insns are available.

Index: config/ia64/ia64.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/config/ia64/ia64.c,v
retrieving revision 1.96
diff -u -p -r1.96 ia64.c
--- config/ia64/ia64.c	2001/05/22 20:10:18	1.96
+++ config/ia64/ia64.c	2001/08/05 09:46:18
@@ -5930,10 +5957,10 @@ ia64_sched_reorder (dump, sched_verbose,
      int *pn_ready;
      int reorder_type, clock_var;
 {
+  int n_asms;
   int n_ready = *pn_ready;
   rtx *e_ready = ready + n_ready;
   rtx *insnp;
-  rtx highest;

   if (sched_verbose)
     {
@@ -5977,7 +6004,7 @@ ia64_sched_reorder (dump, sched_verbose,
     maybe_rotate (sched_verbose ? dump : NULL);

   /* First, move all USEs, CLOBBERs and other crud out of the way.  */
-  highest = ready[n_ready - 1];
+  n_asms = 0;
   for (insnp = ready; insnp < e_ready; insnp++)
     if (insnp < e_ready)
       {
@@ -5985,24 +6012,42 @@ ia64_sched_reorder (dump, sched_verbose,
 	enum attr_type t = ia64_safe_type (insn);
 	if (t == TYPE_UNKNOWN)
 	  {
-	    highest = ready[n_ready - 1];
-	    ready[n_ready - 1] = insn;
-	    *insnp = highest;
-	    if (ia64_final_schedule && group_barrier_needed_p (insn))
+	    if (GET_CODE (PATTERN (insn)) == ASM_INPUT
+		|| asm_noperands (PATTERN (insn)) >= 0)
 	      {
-		schedule_stop (sched_verbose ? dump : NULL);
-		sched_data.last_was_stop = 1;
-		maybe_rotate (sched_verbose ? dump : NULL);
+		rtx lowest = ready[0];
+		ready[0] = insn;
+		*insnp = lowest;
+		n_asms++;
 	      }
-	    else if (GET_CODE (PATTERN (insn)) == ASM_INPUT
-		     || asm_noperands (PATTERN (insn)) >= 0)
+	    else
 	      {
-		/* It must be an asm of some kind.  */
-		cycle_end_fill_slots (sched_verbose ? dump : NULL);
+		rtx highest = ready[n_ready - 1];
+		ready[n_ready - 1] = insn;
+		*insnp = highest;
+		if (ia64_final_schedule && group_barrier_needed_p (insn))
+		  {
+		    schedule_stop (sched_verbose ? dump : NULL);
+		    sched_data.last_was_stop = 1;
+		    maybe_rotate (sched_verbose ? dump : NULL);
+		  }
+
+		return 1;
 	      }
-	    return 1;
 	  }
       }
+  if (n_asms < n_ready)
+    {
+      /* Some normal insns to process.  Skip the asms.  */
+      ready += n_asms;
+      n_ready -= n_asms;
+    }
+  else if (n_ready > 0)
+    {
+      /* Only asm insns left.  */
+      cycle_end_fill_slots (sched_verbose ? dump : NULL);
+      return 1;
+    }

   if (ia64_final_schedule)
     {


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