This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
fix target/5312
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 14 Mar 2002 22:54:58 -0800
- Subject: 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;
}