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]

ia64.c: make NOPs visible to the compiler


This patch adds a function that adds NOP instructions after the final
scheduling pass where appropriate (i.e. where bundling requires one).
While the assembler can do this as well, there still is a minor source
for misunderstandings between compiler and assembler.  This patch might
also be useful as groundwork for potential further optimizations that
need to know exactly where NOPs are scheduled.

Bootstrapped on ia64-linux (in slightly different form); applied only
to the mainline.


Bernd

	* ia64.c (gen_nop_type): New function.
	(ia64_emit_nops): New function.
	(ia64_reorg): Call it.

Index: config/ia64/ia64.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/ia64/ia64.c,v
retrieving revision 1.76
diff -u -p -r1.76 ia64.c
--- ia64.c	2001/03/01 14:04:23	1.76
+++ ia64.c	2001/03/01 14:12:27
@@ -4788,6 +4788,8 @@ static void find_best_packet PARAMS ((in
 static int itanium_reorder PARAMS ((FILE *, rtx *, rtx *, int));
 static void dump_current_packet PARAMS ((FILE *));
 static void schedule_stop PARAMS ((FILE *));
+static rtx gen_nop_type PARAMS ((enum attr_type));
+static void ia64_emit_nops PARAMS ((void));

 /* Map a bundle number to its pseudo-op.  */

@@ -5998,6 +6000,99 @@ emit_predicate_relation_info ()
     }
 }

+/* Generate a NOP instruction of type T.  We will 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 ();
+    }
+}
+
+/* After the last scheduling pass, fill in NOPs.  It's easier to do this
+   here than while scheduling.  */
+
+static void
+ia64_emit_nops ()
+{
+  rtx insn;
+  const struct bundle *b = 0;
+  int bundle_pos = 0;
+
+  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+    {
+      rtx pat;
+      enum attr_type t;
+      pat = INSN_P (insn) ? PATTERN (insn) : const0_rtx;
+      if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER)
+	continue;
+      if ((GET_CODE (pat) == UNSPEC && XINT (pat, 1) == 22)
+	  || GET_CODE (insn) == CODE_LABEL)
+	{
+	  if (b)
+	    while (bundle_pos < 3)
+	      {
+		emit_insn_before (gen_nop_type (b->t[bundle_pos]), insn);
+		bundle_pos++;
+	      }
+	  if (GET_CODE (insn) != CODE_LABEL)
+	    b = bundle + INTVAL (XVECEXP (pat, 0, 0));
+	  else
+	    b = 0;
+	  bundle_pos = 0;
+	  continue;
+	}
+      else if (GET_CODE (pat) == UNSPEC_VOLATILE && XINT (pat, 1) == 2)
+	{
+	  int t = INTVAL (XVECEXP (pat, 0, 0));
+	  if (b)
+	    while (bundle_pos < t)
+	      {
+		emit_insn_before (gen_nop_type (b->t[bundle_pos]), insn);
+		bundle_pos++;
+	      }
+	  continue;
+	}
+
+      if (bundle_pos == 3)
+	b = 0;
+
+      if (b && INSN_P (insn))
+	{
+	  t = ia64_safe_type (insn);
+	  if (t == TYPE_UNKNOWN)
+	    continue;
+	  while (bundle_pos < 3)
+	    {
+	      if (t == b->t[bundle_pos]
+		  || (t == TYPE_A && (b->t[bundle_pos] == TYPE_M
+				      || b->t[bundle_pos] == TYPE_I)))
+		break;
+
+	      emit_insn_before (gen_nop_type (b->t[bundle_pos]), insn);
+	      bundle_pos++;
+	    }
+	  if (bundle_pos < 3)
+	    bundle_pos++;
+	}
+    }
+}
+
 /* Perform machine dependent operations on the rtl chain INSNS.  */

 void
@@ -6022,6 +6117,7 @@ ia64_reorg (insns)
       /* This relies on the NOTE_INSN_BASIC_BLOCK notes to be in the same
 	 place as they were during scheduling.  */
       emit_insn_group_barriers (rtl_dump_file, insns);
+      ia64_emit_nops ();
     }
   else
     emit_all_insn_group_barriers (rtl_dump_file, insns);


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