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]

fix target/5312


The call to cycle_end_fill_slots within maybe_rotate is the
critical part of the fix.  Otherwise we schedule the first L
insn, have sched_data.first_slot = 1, then abort because we
can no longer find a packet that matches (since L insns are
always in slot 2).

The rest of the changes are minor mistakes exposed by the
checking that the extra call to cycle_end_fill_slots performs.


r~


        * config/ia64/ia64.c: Include tm_p.h last.
        (gen_nop_type): Remove duplicate definition.
        (cycle_end_fill_slots): Set sched_data for second L slot.
        (maybe_rotate): Call cycle_end_fill_slots to fill in nop slots.
        (nop_cycles_until): Fix typos.

        * gcc.dg/20020313-1.c: New.

Index: gcc/testsuite/gcc.dg/20020313-1.c
===================================================================
RCS file: 20020313-1.c
diff -N 20020313-1.c
--- /dev/null	Tue May  5 13:32:27 1998
+++ gcc/testsuite/gcc.dg/20020313-1.c	Thu Mar 14 22:39:01 2002
@@ -0,0 +1,70 @@
+/* PR 5312 
+   The problem here is that the ia64 scheduler saw a sequence of L L M type
+   insns, and messed up its internal state on which slot it was issuing
+   to, and aborted.  */
+
+/* { dg-do compile { target ia64-*-* } } */
+/* { dg-options "-O2 -mconstant-gp" } */
+
+typedef unsigned long __u64;
+typedef unsigned int __u32;
+typedef struct { } spinlock_t;
+struct cpuinfo_ia64 {
+        union {
+                struct {
+                        __u32 irq_count;
+                        __u32 bh_count;
+                } f;
+                __u64 irq_and_bh_counts;
+        } irq_stat;
+        __u32 softirq_pending;
+} __attribute__ ((aligned ((1UL << 14)))) ;
+enum
+{
+        TCA_UNSPEC,
+        TCA_KIND,
+        TCA_OPTIONS,
+        TCA_STATS,
+        TCA_XSTATS,
+        TCA_RATE,
+};
+struct tc_stats
+{
+        __u64 bytes;
+        __u32 packets;
+        __u32 drops;
+        __u32 overlimits;
+        __u32 bps;
+        __u32 pps;
+        __u32 qlen;
+        __u32 backlog;
+        spinlock_t *lock;
+};
+struct sk_buff {
+        unsigned int data_len;
+        unsigned char *tail;
+        unsigned char *end;
+};
+static inline int skb_is_nonlinear(const struct sk_buff *skb)
+{
+        return skb->data_len;
+}
+static inline int skb_tailroom(const struct sk_buff *skb)
+{
+        return skb_is_nonlinear(skb) ? 0 : skb->end-skb->tail;
+}
+struct rtattr
+{
+        unsigned short rta_len;
+        unsigned short rta_type;
+};
+int qdisc_copy_stats(struct sk_buff *skb, struct tc_stats *st)
+{
+        do { do { (((struct cpuinfo_ia64 *) (0xa000000000000000 + 2*(1UL << 14)))->irq_stat.f.bh_count)++; __asm__ __volatile__("": : :"memory"); } while (0); (void)(st->lock); } while (0);
+        ({ if (skb_tailroom(skb) < (int)( (((( ((sizeof(struct rtattr))+4 -1) & ~(4 -1) ) + ((char*)&st->lock - (char*)st)))+4 -1) & ~(4 -1) )) goto rtattr_failure; __rta_fill(skb, TCA_STATS, (char*)&st->lock - (char*)st, st); });
+        do { do { } while(0); do { do { __asm__ __volatile__("": : :"memory"); (((struct cpuinfo_ia64 *) (0xa000000000000000 + 2*(1UL << 14)))->irq_stat.f.bh_count)--; } while (0); if (__builtin_expect((((struct cpuinfo_ia64 *) (0xa000000000000000 + 2*(1UL << 14)))->softirq_pending), 0) && (((struct cpuinfo_ia64 *) (0xa000000000000000 + 2*(1UL << 14)))->irq_stat.f.bh_count) == 0) do_softirq(); } while (0); } while (0);
+        return 0;
+rtattr_failure:
+        do { do { } while(0); do { do { __asm__ __volatile__("": : :"memory"); (((struct cpuinfo_ia64 *) (0xa000000000000000 + 2*(1UL << 14)))->irq_stat.f.bh_count)--; } while (0); if (__builtin_expect((((struct cpuinfo_ia64 *) (0xa000000000000000 + 2*(1UL << 14)))->softirq_pending), 0) && (((struct cpuinfo_ia64 *) (0xa000000000000000 + 2*(1UL << 14)))->irq_stat.f.bh_count) == 0) do_softirq(); } while (0); } while (0);
+        return -1;
+}
Index: gcc/config/ia64/ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.c,v
retrieving revision 1.139.2.5
diff -c -p -d -u -r1.139.2.5 ia64.c
--- gcc/config/ia64/ia64.c	2002/03/13 07:48:02	1.139.2.5
+++ gcc/config/ia64/ia64.c	2002/03/15 06:39:02
@@ -24,7 +24,6 @@ Boston, MA 02111-1307, USA.  */
 #include "system.h"
 #include "rtl.h"
 #include "tree.h"
-#include "tm_p.h"
 #include "regs.h"
 #include "hard-reg-set.h"
 #include "real.h"
@@ -46,6 +45,7 @@ Boston, MA 02111-1307, USA.  */
 #include "timevar.h"
 #include "target.h"
 #include "target-def.h"
+#include "tm_p.h"
 
 /* This is used for communication between ASM_OUTPUT_LABEL and
    ASM_OUTPUT_LABELREF.  */
@@ -5478,32 +5478,6 @@ ia64_emit_insn_before (insn, before)
   emit_insn_before (insn, before);
 }
 
-#if 0
-/* Generate a nop insn of the given type.  Note we never generate L type
-   nops.  */
-
-static rtx
-gen_nop_type (t)
-     enum attr_type t;
-{
-  switch (t)
-    {
-    case TYPE_M:
-      return gen_nop_m ();
-    case TYPE_I:
-      return gen_nop_i ();
-    case TYPE_B:
-      return gen_nop_b ();
-    case TYPE_F:
-      return gen_nop_f ();
-    case TYPE_X:
-      return gen_nop_x ();
-    default:
-      abort ();
-    }
-}
-#endif
-
 /* When rotating a bundle out of the issue window, insert a bundle selector
    insn in front of it.  DUMP is the scheduling dump file or NULL.  START
    is either 0 or 3, depending on whether we want to emit a bundle selector
@@ -5568,8 +5542,8 @@ cycle_end_fill_slots (dump)
 	  if (slot > sched_data.split)
 	    abort ();
 	  if (dump)
-	    fprintf (dump, "// Packet needs %s, have %s\n", type_names[packet->t[slot]],
-		     type_names[t]);
+	    fprintf (dump, "// Packet needs %s, have %s\n",
+		     type_names[packet->t[slot]], type_names[t]);
 	  sched_data.types[slot] = packet->t[slot];
 	  sched_data.insns[slot] = 0;
 	  sched_data.stopbit[slot] = 0;
@@ -5581,15 +5555,22 @@ cycle_end_fill_slots (dump)
 
 	  slot++;
 	}
+
       /* Do _not_ use T here.  If T == TYPE_A, then we'd risk changing the
 	 actual slot type later.  */
       sched_data.types[slot] = packet->t[slot];
       sched_data.insns[slot] = tmp_insns[i];
       sched_data.stopbit[slot] = 0;
       slot++;
+
       /* TYPE_L instructions always fill up two slots.  */
       if (t == TYPE_L)
-	slot++;
+	{
+	  sched_data.types[slot] = packet->t[slot];
+	  sched_data.insns[slot] = 0;
+	  sched_data.stopbit[slot] = 0;
+	  slot++;
+	}
     }
 
   /* This isn't right - there's no need to pad out until the forced split;
@@ -6065,6 +6046,7 @@ static void
 maybe_rotate (dump)
      FILE *dump;
 {
+  cycle_end_fill_slots (dump);
   if (sched_data.cur == 6)
     rotate_two_bundles (dump);
   else if (sched_data.cur >= 3)
@@ -6115,7 +6097,7 @@ nop_cycles_until (clock_var, dump)
 	  for (i = sched_data.cur; i < split; i++)
 	    {
 	      rtx t = sched_emit_insn (gen_nop_type (sched_data.packet->t[i]));
-	      sched_data.types[i] = sched_data.packet->t[sched_data.cur];
+	      sched_data.types[i] = sched_data.packet->t[i];
 	      sched_data.insns[i] = t;
 	      sched_data.stopbit[i] = 0;
 	    }
@@ -6129,7 +6111,7 @@ nop_cycles_until (clock_var, dump)
 	  for (i = sched_data.cur; i < 6; i++)
 	    {
 	      rtx t = sched_emit_insn (gen_nop_type (sched_data.packet->t[i]));
-	      sched_data.types[i] = sched_data.packet->t[sched_data.cur];
+	      sched_data.types[i] = sched_data.packet->t[i];
 	      sched_data.insns[i] = t;
 	      sched_data.stopbit[i] = 0;
 	    }


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