This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix for ia64 abort
- To: <gcc-patches at gcc dot gnu dot org>
- Subject: Fix for ia64 abort
- From: Bernd Schmidt <bernds at cambridge dot redhat dot com>
- Date: Thu, 15 Mar 2001 10:54:38 +0000 (GMT)
This fixes the problem recently discovered by Richard Henderson. The
motto for the ia64 scheduling code is "rotate early, rotate often" :-)
This also fixes the placement of nops around asm statements.
Bootstrapped on ia64-linux (libjava didn't build due to an apparently
unrelated problem).
Bernd
* config/ia64/ia64.c (maybe_rotate): New function, broken out of
ia64_sched_reorder.
(ia64_sched_reorder): Call maybe_rotate; also rotate after
scheduling a stop bit.
(ia64_emit_nops): Correctly handle ASMs.
Index: gcc/config/ia64/ia64.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/ia64/ia64.c,v
retrieving revision 1.78
diff -u -p -r1.78 ia64.c
--- gcc/config/ia64/ia64.c 2001/03/01 14:25:30 1.78
+++ gcc/config/ia64/ia64.c 2001/03/15 10:47:04
@@ -5643,6 +5643,20 @@ schedule_stop (dump)
dump_current_packet (dump);
}
+/* If necessary, perform one or two rotations on the scheduling state.
+ This should only be called if we are starting a new cycle. */
+
+static void
+maybe_rotate (dump)
+ FILE *dump;
+{
+ if (sched_data.cur == 6)
+ rotate_two_bundles (dump);
+ else if (sched_data.cur >= 3)
+ rotate_one_bundle (dump);
+ sched_data.first_slot = sched_data.cur;
+}
+
/* We are about to being issuing insns for this clock cycle.
Override the default sort algorithm to better slot instructions. */
@@ -5666,13 +5680,7 @@ ia64_sched_reorder (dump, sched_verbose,
}
if (reorder_type == 0)
- {
- if (sched_data.cur == 6)
- rotate_two_bundles (sched_verbose ? dump : NULL);
- else if (sched_data.cur >= 3)
- rotate_one_bundle (sched_verbose ? dump : NULL);
- sched_data.first_slot = sched_data.cur;
- }
+ maybe_rotate (sched_verbose ? dump : NULL);
/* First, move all USEs, CLOBBERs and other crud out of the way. */
highest = ready[n_ready - 1];
@@ -5690,12 +5698,17 @@ ia64_sched_reorder (dump, sched_verbose,
{
schedule_stop (sched_verbose ? dump : NULL);
sched_data.last_was_stop = 1;
+ maybe_rotate (sched_verbose ? dump : NULL);
+ if (dump)
+ fprintf (dump, "// UNKNOWN insn; group barrier needed.\n");
}
else if (GET_CODE (PATTERN (insn)) == ASM_INPUT
|| asm_noperands (PATTERN (insn)) >= 0)
{
/* It must be an asm of some kind. */
cycle_end_fill_slots (sched_verbose ? dump : NULL);
+ if (dump)
+ fprintf (dump, "// UNKNOWN (asm).\n");
}
return 1;
}
@@ -5721,6 +5734,7 @@ ia64_sched_reorder (dump, sched_verbose,
{
schedule_stop (sched_verbose ? dump : NULL);
sched_data.last_was_stop = 1;
+ maybe_rotate (sched_verbose ? dump : NULL);
if (reorder_type == 1)
return 0;
}
@@ -6075,6 +6089,17 @@ ia64_emit_nops ()
if (b && INSN_P (insn))
{
t = ia64_safe_type (insn);
+ if (asm_noperands (PATTERN (insn)) >= 0
+ || GET_CODE (PATTERN (insn)) == ASM_INPUT)
+ {
+ while (bundle_pos < 3)
+ {
+ emit_insn_before (gen_nop_type (b->t[bundle_pos]), insn);
+ bundle_pos++;
+ }
+ continue;
+ }
+
if (t == TYPE_UNKNOWN)
continue;
while (bundle_pos < 3)