From 11dd0155a4db6125964882a7250a378d36be1770 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 26 Jun 2014 16:37:50 -0400
Subject: [PATCH 042/249] Use rtx_insn internally within generated functions

With this patch, "insn" and "curr_insn" as used from C++ fragments in .md
files are strengthened from rtx to rtx_insn *, allowing numerous
target-specific functions to have their params be similiar strengthened.

The top-level interfaces ("recog", "split", "peephole2") continue to take
a plain rtx for "insn", to avoid introducing dependencies on other
patches.

gcc/
	* recog.h (insn_output_fn): Update this function typedef to match
	the changes below to the generated output functions, strengthening
	the 2nd param from rtx to rtx_insn *.

	* final.c (get_insn_template): Add a checked cast to rtx_insn * on
	insn when invoking an output function, to match the new signature
	of insn_output_fn with a stronger second param.

	* genconditions.c (write_header): In the generated code for
	gencondmd.c, strengthen the global "insn" from rtx to rtx_insn *
	to match the other changes in this patch.

	* genemit.c (gen_split): Strengthen the 1st param "curr_insn" of
	the generated "gen_" functions from rtx to rtx_insn * within their
	implementations.

	* genrecog.c (write_subroutine): Strengthen the 2nd param "insn" of
	the subfunctions within the generated "recog_", "split", "peephole2"
	function trees from rtx to rtx_insn *.  For now, the top-level
	generated functions ("recog", "split", "peephole2") continue to
	take a plain rtx for "insn", to avoid introducing dependencies on
	other patches.  Rename this 2nd param from "insn" to
	"uncast_insn", and reintroduce "insn" as a local variable of type
	rtx_insn *, initialized at the top of the generated function with
	a checked cast on "uncast_insn".
	(make_insn_sequence): Strengthen the 1st param "curr_insn" of
	the generated "gen_" functions from rtx to rtx_insn * within their
	prototypes.

	* genoutput.c (process_template): Strengthen the 2nd param within
	the generated "output_" functions "insn" from rtx to rtx_insn *.
---
 gcc/final.c         |  3 ++-
 gcc/genconditions.c |  2 +-
 gcc/genemit.c       |  8 ++++----
 gcc/genoutput.c     |  4 ++--
 gcc/genrecog.c      | 29 ++++++++++++++++++++++-------
 gcc/recog.h         |  2 +-
 6 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/gcc/final.c b/gcc/final.c
index 38f6e0c..3a78aad 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -2055,7 +2055,8 @@ get_insn_template (int code, rtx insn)
       return insn_data[code].output.multi[which_alternative];
     case INSN_OUTPUT_FORMAT_FUNCTION:
       gcc_assert (insn);
-      return (*insn_data[code].output.function) (recog_data.operand, insn);
+      return (*insn_data[code].output.function) (recog_data.operand,
+						 as_a <rtx_insn *> (insn));
 
     default:
       gcc_unreachable ();
diff --git a/gcc/genconditions.c b/gcc/genconditions.c
index dc22c78..8390797 100644
--- a/gcc/genconditions.c
+++ b/gcc/genconditions.c
@@ -95,7 +95,7 @@ write_header (void)
 
   puts ("\
 /* Dummy external declarations.  */\n\
-extern rtx insn;\n\
+extern rtx_insn *insn;\n\
 extern rtx ins1;\n\
 extern rtx operands[];\n\
 \n\
diff --git a/gcc/genemit.c b/gcc/genemit.c
index 16b5644..1bc73f0 100644
--- a/gcc/genemit.c
+++ b/gcc/genemit.c
@@ -557,15 +557,15 @@ gen_split (rtx split)
   /* Output the prototype, function name and argument declarations.  */
   if (GET_CODE (split) == DEFINE_PEEPHOLE2)
     {
-      printf ("extern rtx gen_%s_%d (rtx, rtx *);\n",
+      printf ("extern rtx gen_%s_%d (rtx_insn *, rtx *);\n",
 	      name, insn_code_number);
-      printf ("rtx\ngen_%s_%d (rtx curr_insn ATTRIBUTE_UNUSED, rtx *operands%s)\n",
+      printf ("rtx\ngen_%s_%d (rtx_insn *curr_insn ATTRIBUTE_UNUSED, rtx *operands%s)\n",
 	      name, insn_code_number, unused);
     }
   else
     {
-      printf ("extern rtx gen_split_%d (rtx, rtx *);\n", insn_code_number);
-      printf ("rtx\ngen_split_%d (rtx curr_insn ATTRIBUTE_UNUSED, rtx *operands%s)\n",
+      printf ("extern rtx gen_split_%d (rtx_insn *, rtx *);\n", insn_code_number);
+      printf ("rtx\ngen_split_%d (rtx_insn *curr_insn ATTRIBUTE_UNUSED, rtx *operands%s)\n",
 	      insn_code_number, unused);
     }
   printf ("{\n");
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index b3ce120..b33a361 100644
--- a/gcc/genoutput.c
+++ b/gcc/genoutput.c
@@ -652,7 +652,7 @@ process_template (struct data *d, const char *template_code)
       d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
 
       puts ("\nstatic const char *");
-      printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED)\n",
+      printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, rtx_insn *insn ATTRIBUTE_UNUSED)\n",
 	      d->code_number);
       puts ("{");
       print_md_ptr_loc (template_code);
@@ -681,7 +681,7 @@ process_template (struct data *d, const char *template_code)
 	  d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
 	  puts ("\nstatic const char *");
 	  printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, "
-		  "rtx insn ATTRIBUTE_UNUSED)\n", d->code_number);
+		  "rtx_insn *insn ATTRIBUTE_UNUSED)\n", d->code_number);
 	  puts ("{");
 	  puts ("  switch (which_alternative)\n    {");
 	}
diff --git a/gcc/genrecog.c b/gcc/genrecog.c
index 457b59c..27f0c10 100644
--- a/gcc/genrecog.c
+++ b/gcc/genrecog.c
@@ -2180,6 +2180,7 @@ write_subroutine (struct decision_head *head, enum routine_type type)
   const char *s_or_e;
   char extension[32];
   int i;
+  const char *insn_param;
 
   s_or_e = subfunction ? "static " : "";
 
@@ -2190,21 +2191,27 @@ write_subroutine (struct decision_head *head, enum routine_type type)
   else
     strcpy (extension, "_insns");
 
+  /* For now, the top-level functions take a plain "rtx", and perform a
+     checked cast to "rtx_insn *" for use throughout the rest of the
+     function and the code it calls.  */
+  insn_param = subfunction ? "rtx_insn *insn" : "rtx uncast_insn";
+
   switch (type)
     {
     case RECOG:
       printf ("%sint\n\
-recog%s (rtx x0 ATTRIBUTE_UNUSED,\n\trtx insn ATTRIBUTE_UNUSED,\n\tint *pnum_clobbers ATTRIBUTE_UNUSED)\n", s_or_e, extension);
+recog%s (rtx x0 ATTRIBUTE_UNUSED,\n\t%s ATTRIBUTE_UNUSED,\n\tint *pnum_clobbers ATTRIBUTE_UNUSED)\n",
+	      s_or_e, extension, insn_param);
       break;
     case SPLIT:
       printf ("%srtx\n\
-split%s (rtx x0 ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED)\n",
-	      s_or_e, extension);
+split%s (rtx x0 ATTRIBUTE_UNUSED, %s ATTRIBUTE_UNUSED)\n",
+	      s_or_e, extension, insn_param);
       break;
     case PEEPHOLE2:
       printf ("%srtx\n\
-peephole2%s (rtx x0 ATTRIBUTE_UNUSED,\n\trtx insn ATTRIBUTE_UNUSED,\n\tint *_pmatch_len ATTRIBUTE_UNUSED)\n",
-	      s_or_e, extension);
+peephole2%s (rtx x0 ATTRIBUTE_UNUSED,\n\t%s ATTRIBUTE_UNUSED,\n\tint *_pmatch_len ATTRIBUTE_UNUSED)\n",
+	      s_or_e, extension, insn_param);
       break;
     }
 
@@ -2217,6 +2224,14 @@ peephole2%s (rtx x0 ATTRIBUTE_UNUSED,\n\trtx insn ATTRIBUTE_UNUSED,\n\tint *_pma
   if (!subfunction)
     printf ("  recog_data.insn = NULL_RTX;\n");
 
+  /* For now add the downcast to rtx_insn *, at the top of each top-level
+     function.  */
+  if (!subfunction)
+    {
+      printf ("  rtx_insn *insn ATTRIBUTE_UNUSED;\n");
+      printf ("  insn = as_a_nullable <rtx_insn *> (uncast_insn);\n");
+    }
+
   if (head->first)
     write_tree (head, &root_pos, type, 1);
   else
@@ -2461,12 +2476,12 @@ make_insn_sequence (rtx insn, enum routine_type type)
 
     case SPLIT:
       /* Define the subroutine we will call below and emit in genemit.  */
-      printf ("extern rtx gen_split_%d (rtx, rtx *);\n", next_insn_code);
+      printf ("extern rtx gen_split_%d (rtx_insn *, rtx *);\n", next_insn_code);
       break;
 
     case PEEPHOLE2:
       /* Define the subroutine we will call below and emit in genemit.  */
-      printf ("extern rtx gen_peephole2_%d (rtx, rtx *);\n",
+      printf ("extern rtx gen_peephole2_%d (rtx_insn *, rtx *);\n",
 	      next_insn_code);
       break;
     }
diff --git a/gcc/recog.h b/gcc/recog.h
index 8c8d55f..3f5b98c 100644
--- a/gcc/recog.h
+++ b/gcc/recog.h
@@ -264,7 +264,7 @@ extern struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS][MAX_RECOG_ALT
    each insn-code value.  */
 
 typedef int (*insn_operand_predicate_fn) (rtx, enum machine_mode);
-typedef const char * (*insn_output_fn) (rtx *, rtx);
+typedef const char * (*insn_output_fn) (rtx *, rtx_insn *);
 
 struct insn_gen_fn
 {
-- 
1.8.5.3

