public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Use target-insns.def for calls
@ 2015-08-24 12:55 Richard Sandiford
  2015-08-24 17:54 ` Jeff Law
  0 siblings, 1 reply; 2+ messages in thread
From: Richard Sandiford @ 2015-08-24 12:55 UTC (permalink / raw)
  To: gcc-patches

This is the most complicated part of the conversion, since it is the only
instance in which named patterns take optional operands.  That still seems
like a reasonable feature to have, so I extended the target-insns.def code
to support it rather than update ports to accept all operands.

With that change we can get rid of the GEN_CALL etc. macros, which existed
only to drop the unused operands.  Several ports used these macros themselves,
but it makes more sense for ports to call their gen_* functions directly.
Using GEN_CALL often meant that ports were passing dummy trailing
arguments in the knowledge that GEN_CALL would discard them.

calls.c had support for sibcall_pop and sibcall_value_pop, but no port
defines those patterns and the code looks inconsistent with the corresponding
call_pop vs. call code.  I've therefore dropped it rather than add untested
entries to the .def file.  (The patterns were also undocumented.)

The calls.c code was a bit confusing in that it tested whether
sibcall and sibcall_value are available when ECF_SIBCALL is set.
By this point the decision about whether to use a sibcall has already
been made, and we set SIBLING_CALL_P directly from ECF_SIBCALL, so we
would silently generate wrong code if we emitted a normal call instead.
The patch therefore drops the have_* checks and calls the generator
regardless.  The generator will assert that the pattern is available.

Tested on x86_64-linux-gnu.  Also tested by building one target per cpu
directory and checking that there were no changes in the assembly output
for gcc.dg, g++.dg and gcc.c-torture.  OK to install?

Thanks,
Richard

gcc/
	* genflags.c (gen_macro): Delete.
	(gen_proto): Don't create GEN.*CALL.* macros.
	* gensupport.h (get_file_location): Declare.
	* gensupport.c (rtx_locs): New variable.
	(read_md_rtx): Record rtx locations.
	(get_file_location): New function.
	* target-insns.def (call, call_pop, call_value, call_value_pop)
	(sibcall, sibcall_value): New patterns.
	* gentarget-def.c (parse_argument): New function.
	(def_target_insn): Use it.  Handle optional operands.  Raise an
	error if an .md pattern has the wrong number of operands for the
	pattern name.  Remove the names of unused operands from the prototype.
	* builtins.c (expand_builtin_apply): Use targetm functions
	instead of HAVE_call_value and GEN_CALL_VALUE.
	* calls.c (emit_call_1): Likewise.  Remove support for sibcall_pop
	and sibcall_value_pop.
	* config/aarch64/aarch64.md (untyped_call): Use gen_call instead
	of GEN_CALL.
	* config/alpha/alpha.md (untyped_call): Likewise.
	* config/iq2000/iq2000.md (untyped_call): Likewise.
	* config/m68k/m68k.md (untyped_call): Likewise.
	* config/mips/mips.md (untyped_call): Likewise.
	* config/pa/pa.md (untyped_call): Likewise.
	* config/rs6000/rs6000.md (untyped_call): Likewise.
	* config/sparc/sparc.md (untyped_call): Likewise.
	* config/tilegx/tilegx.md (untyped_call): Likewise.
	* config/tilepro/tilepro.md (untyped_call): Likewise.
	* config/visium/visium.md (untyped_call): Likewise.
	* config/alpha/alpha.c (alpha_emit_xfloating_libcall): Use
	gen_call_value instead of GEN_CALL_VALUE.
	* config/arm/arm.md (untyped_call): Likewise.
	* config/cr16/cr16.c (cr16_function_arg): Remove reference to
	GEN_CALL.

Index: gcc/genflags.c
===================================================================
--- gcc/genflags.c	2015-08-23 21:02:50.008436173 +0100
+++ gcc/genflags.c	2015-08-23 21:02:50.004436217 +0100
@@ -42,7 +42,6 @@ Software Foundation; either version 3, o
 static void max_operand_1 (rtx);
 static int num_operands (rtx);
 static void gen_proto (rtx);
-static void gen_macro (const char *, int, int);
 
 /* Count the number of match_operand's found.  */
 
@@ -92,32 +91,6 @@ num_operands (rtx insn)
   return max_opno + 1;
 }
 
-/* Print out a wrapper macro for a function which corrects the number
-   of arguments it takes.  Any missing arguments are assumed to be at
-   the end.  */
-static void
-gen_macro (const char *name, int real, int expect)
-{
-  int i;
-
-  gcc_assert (real <= expect);
-  gcc_assert (real);
-
-  /* #define GEN_CALL(A, B, C, D) gen_call((A), (B)) */
-  fputs ("#define GEN_", stdout);
-  for (i = 0; name[i]; i++)
-    putchar (TOUPPER (name[i]));
-
-  putchar ('(');
-  for (i = 0; i < expect - 1; i++)
-    printf ("%c, ", i + 'A');
-  printf ("%c) gen_%s (", i + 'A', name);
-
-  for (i = 0; i < real - 1; i++)
-    printf ("(%c), ", i + 'A');
-  printf ("(%c))\n", i + 'A');
-}
-
 /* Print out prototype information for a generator function.  If the
    insn pattern has been elided, print out a dummy generator that
    does nothing.  */
@@ -130,25 +103,6 @@ gen_proto (rtx insn)
   const char *name = XSTR (insn, 0);
   int truth = maybe_eval_c_test (XSTR (insn, 2));
 
-  /* Many md files don't refer to the last two operands passed to the
-     call patterns.  This means their generator functions will be two
-     arguments too short.  Instead of changing every md file to touch
-     those operands, we wrap the prototypes in macros that take the
-     correct number of arguments.  */
-  if (name[0] == 'c' || name[0] == 's')
-    {
-      if (!strcmp (name, "call")
-	  || !strcmp (name, "call_pop")
-	  || !strcmp (name, "sibcall")
-	  || !strcmp (name, "sibcall_pop"))
-	gen_macro (name, num, 4);
-      else if (!strcmp (name, "call_value")
-	       || !strcmp (name, "call_value_pop")
-	       || !strcmp (name, "sibcall_value")
-	       || !strcmp (name, "sibcall_value_pop"))
-	gen_macro (name, num, 5);
-    }
-
   if (truth != 0)
     printf ("extern rtx        gen_%-*s (", max_id_len, name);
   else
Index: gcc/gensupport.h
===================================================================
--- gcc/gensupport.h	2015-08-23 21:02:50.008436173 +0100
+++ gcc/gensupport.h	2015-08-23 21:02:50.004436217 +0100
@@ -132,6 +132,7 @@ struct pattern_stats
 
 extern void get_pattern_stats (struct pattern_stats *ranges, rtvec vec);
 extern void compute_test_codes (rtx, file_location, char *);
+extern file_location get_file_location (rtx);
 extern const char *get_emit_function (rtx);
 extern bool needs_barrier_p (rtx);
 
Index: gcc/gensupport.c
===================================================================
--- gcc/gensupport.c	2015-08-23 21:02:50.008436173 +0100
+++ gcc/gensupport.c	2015-08-23 21:02:50.004436217 +0100
@@ -93,6 +93,9 @@ static struct queue_elem **other_tail =
 static struct queue_elem *define_subst_attr_queue;
 static struct queue_elem **define_subst_attr_tail = &define_subst_attr_queue;
 
+/* Mapping from DEFINE_* rtxes to their location in the source file.  */
+static hash_map <rtx, file_location> *rtx_locs;
+
 static void remove_constraints (rtx);
 
 static int is_predicable (struct queue_elem *);
@@ -2619,9 +2622,24 @@ read_md_rtx (md_rtx_info *info)
   else
     info->index = -1;
 
+  if (!rtx_locs)
+    rtx_locs = new hash_map <rtx, file_location>;
+  rtx_locs->put (info->def, info->loc);
+
   return true;
 }
 
+/* Return the file location of DEFINE_* rtx X, which was previously
+   returned by read_md_rtx.  */
+file_location
+get_file_location (rtx x)
+{
+  gcc_assert (rtx_locs);
+  file_location *entry = rtx_locs->get (x);
+  gcc_assert (entry);
+  return *entry;
+}
+
 /* Return the number of possible INSN_CODEs.  Only meaningful once the
    whole file has been processed.  */
 unsigned int
Index: gcc/target-insns.def
===================================================================
--- gcc/target-insns.def	2015-08-23 21:02:50.008436173 +0100
+++ gcc/target-insns.def	2015-08-23 21:22:49.702933996 +0100
@@ -27,15 +27,23 @@
 
    where NAME is the name of the pattern and PROTOTYPE is its C prototype.
    The prototype should use parameter names of the form "x0", "x1", etc.
-   Patterns that take no operands should have a prototype "(void)".
+   for the operands that the .md pattern is required to have, followed by
+   parameter names of the form "optN" for operands that the .md pattern
+   may choose to ignore.  Patterns that never take operands should have
+   a prototype "(void)".
 
-   Instructions should be documented in md.texi rather than here.  */
+   Pattern names should be documented in md.texi rather than here.  */
 DEF_TARGET_INSN (allocate_stack, (rtx x0, rtx x1))
 DEF_TARGET_INSN (atomic_test_and_set, (rtx x0, rtx x1, rtx x2))
 DEF_TARGET_INSN (builtin_longjmp, (rtx x0))
 DEF_TARGET_INSN (builtin_setjmp_receiver, (rtx x0))
 DEF_TARGET_INSN (builtin_setjmp_setup, (rtx x0))
 DEF_TARGET_INSN (canonicalize_funcptr_for_compare, (rtx x0, rtx x1))
+DEF_TARGET_INSN (call, (rtx x0, rtx opt1, rtx opt2, rtx opt3))
+DEF_TARGET_INSN (call_pop, (rtx x0, rtx opt1, rtx opt2, rtx opt3))
+DEF_TARGET_INSN (call_value, (rtx x0, rtx x1, rtx opt2, rtx opt3, rtx opt4))
+DEF_TARGET_INSN (call_value_pop, (rtx x0, rtx x1, rtx opt2, rtx opt3,
+				  rtx opt4))
 DEF_TARGET_INSN (casesi, (rtx x0, rtx x1, rtx x2, rtx x3, rtx x4))
 DEF_TARGET_INSN (check_stack, (rtx x0))
 DEF_TARGET_INSN (clear_cache, (rtx x0, rtx x1))
@@ -68,7 +76,10 @@ DEF_TARGET_INSN (return, (void))
 DEF_TARGET_INSN (save_stack_block, (rtx x0, rtx x1))
 DEF_TARGET_INSN (save_stack_function, (rtx x0, rtx x1))
 DEF_TARGET_INSN (save_stack_nonlocal, (rtx x0, rtx x1))
+DEF_TARGET_INSN (sibcall, (rtx x0, rtx opt1, rtx opt2, rtx opt3))
 DEF_TARGET_INSN (sibcall_epilogue, (void))
+DEF_TARGET_INSN (sibcall_value, (rtx x0, rtx x1, rtx opt2, rtx opt3,
+				 rtx opt4))
 DEF_TARGET_INSN (simple_return, (void))
 DEF_TARGET_INSN (split_stack_prologue, (void))
 DEF_TARGET_INSN (split_stack_space_check, (rtx x0, rtx x1))
Index: gcc/gentarget-def.c
===================================================================
--- gcc/gentarget-def.c	2015-08-23 21:02:50.008436173 +0100
+++ gcc/gentarget-def.c	2015-08-23 21:21:16.895978023 +0100
@@ -60,6 +60,43 @@ insn_hasher::equal (rtx x, const char *y
    from the C condition to the function name.  */
 static hash_map <nofree_string_hash, const char *> *have_funcs;
 
+/* Return true if the part of the prototype at P is for an argument
+   name.  If so, point *END_OUT to the first character after the name.
+   If OPNO_OUT is nonnull, set *OPNO_OUT to the number of the associated
+   operand.  If REQUIRED_OUT is nonnull, set *REQUIRED_OUT to whether the
+   .md pattern is required to match the operand.  */
+
+static bool
+parse_argument (const char *p, const char **end_out,
+		unsigned int *opno_out = 0,
+		bool *required_out = 0)
+{
+  while (ISSPACE (*p))
+    p++;
+  if (p[0] == 'x' && ISDIGIT (p[1]))
+    {
+      p += 1;
+      if (required_out)
+	*required_out = true;
+    }
+  else if (p[0] == 'o' && p[1] == 'p' && p[2] == 't' && ISDIGIT (p[3]))
+    {
+      p += 3;
+      if (required_out)
+	*required_out = false;
+    }
+  else
+    return false;
+
+  char *endptr;
+  unsigned int opno = strtol (p, &endptr, 10);
+  if (opno_out)
+    *opno_out = opno;
+  *end_out = endptr;
+  return true;
+}
+
+
 /* Output hook definitions for pattern NAME, which has target-insns.def
    prototype PROTOTYPE.  */
 
@@ -78,21 +115,27 @@ def_target_insn (const char *name, const
   char *suffix = XALLOCAVEC (char, strlen (prototype) + 1);
   i = 0;
   unsigned int opno = 0;
+  unsigned int required_ops = 0;
+  unsigned int this_opno;
+  bool required_p;
   for (const char *p = prototype; *p; ++p)
-    if (*p == 'x' && ISDIGIT (p[1]))
+    if (parse_argument (p, &p, &this_opno, &required_p))
       {
-	/* This should be a parameter name of the form "x<OPNO>".
-	   That doesn't contribute to the suffix, so skip ahead and
-	   process the following character.  */
-	char *endptr;
-	if ((unsigned int) strtol (p + 1, &endptr, 10) != opno
-	    || (*endptr != ',' && *endptr != ')'))
+	if (this_opno != opno || (*p != ',' && *p != ')'))
 	  {
 	    error ("invalid prototype for '%s'", name);
 	    exit (FATAL_EXIT_CODE);
 	  }
+	if (required_p && required_ops < opno)
+	  {
+	    error ("prototype for '%s' has required operands after"
+		   " optional operands", name);
+	    exit (FATAL_EXIT_CODE);
+	  }
 	opno += 1;
-	p = endptr;
+	if (required_p)
+	  required_ops = opno;
+	/* Skip over ')'s.  */
 	if (*p == ',')
 	  suffix[i++] = '_';
       }
@@ -117,6 +160,22 @@ def_target_insn (const char *name, const
   const char *have_name = name;
   if (rtx insn = insns->find_with_hash (name, hash))
     {
+      pattern_stats stats;
+      get_pattern_stats (&stats, XVEC (insn, 1));
+      unsigned int actual_ops = stats.num_generator_args;
+      if (opno == required_ops && opno != actual_ops)
+	error_at (get_file_location (insn),
+		  "'%s' must have %d operands (excluding match_dups)",
+		  name, required_ops);
+      else if (actual_ops < required_ops)
+	error_at (get_file_location (insn),
+		  "'%s' must have at least %d operands (excluding match_dups)",
+		  name, required_ops);
+      else if (actual_ops > opno)
+	error_at (get_file_location (insn),
+		  "'%s' must have no more than %d operands"
+		  " (excluding match_dups)", name, opno);
+
       const char *test = XSTR (insn, 2);
       truth = maybe_eval_c_test (test);
       gcc_assert (truth != 0);
@@ -139,13 +198,23 @@ def_target_insn (const char *name, const
 	  have_name = entry;
 	}
       printf ("\nstatic rtx_insn *\n");
-      printf ("target_gen_%s %s\n", name, prototype);
-      printf ("{\n");
+      printf ("target_gen_%s ", name);
+      /* Print the prototype with the argument names after ACTUAL_OPS
+	 removed.  */
+      const char *p = prototype, *end;
+      while (*p)
+	if (parse_argument (p, &end, &this_opno) && this_opno >= actual_ops)
+	  p = end;
+	else
+	  fputc (*p++, stdout);
+
+      printf ("\n{\n");
       if (truth < 0)
 	printf ("  gcc_checking_assert (targetm.have_%s ());\n", name);
       printf ("  return insnify (gen_%s (", name);
-      for (i = 0; i < opno; ++i)
-	printf ("%sx%d", i == 0 ? "" : ", ", i);
+      for (i = 0; i < actual_ops; ++i)
+	printf ("%s%s%d", i == 0 ? "" : ", ",
+		i < required_ops ? "x" : "opt", i);
       printf ("));\n");
       printf ("}\n");
     }
@@ -157,18 +226,11 @@ def_target_insn (const char *name, const
 	  *slot = xstrdup (suffix);
 	  printf ("\nstatic rtx_insn *\n");
 	  printf ("invalid_%s ", suffix);
+	  /* Print the prototype with the argument names removed.  */
 	  const char *p = prototype;
 	  while (*p)
-	    {
-	      if (p[0] == 'x' && ISDIGIT (p[1]))
-		{
-		  char *endptr;
-		  strtol (p + 1, &endptr, 10);
-		  p = endptr;
-		}
-	      else
-		fputc (*p++, stdout);
-	    }
+	    if (!parse_argument (p, &p))
+	      fputc (*p++, stdout);
 	  printf ("\n{\n");
 	  printf ("  gcc_unreachable ();\n");
 	  printf ("}\n");
Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c	2015-08-23 21:02:50.008436173 +0100
+++ gcc/builtins.c	2015-08-23 21:02:49.988436398 +0100
@@ -1686,9 +1686,7 @@ expand_builtin_apply (rtx function, rtx
       emit_call_insn (targetm.gen_untyped_call (mem, result,
 						result_vector (1, result)));
     }
-  else
-#ifdef HAVE_call_value
-  if (HAVE_call_value)
+  else if (targetm.have_call_value ())
     {
       rtx valreg = 0;
 
@@ -1699,19 +1697,18 @@ expand_builtin_apply (rtx function, rtx
       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
 	if ((mode = apply_result_mode[regno]) != VOIDmode)
 	  {
-	    gcc_assert (!valreg); /* HAVE_untyped_call required.  */
+	    gcc_assert (!valreg); /* have_untyped_call required.  */
 
 	    valreg = gen_rtx_REG (mode, regno);
 	  }
 
-      emit_call_insn (GEN_CALL_VALUE (valreg,
-				      gen_rtx_MEM (FUNCTION_MODE, function),
-				      const0_rtx, NULL_RTX, const0_rtx));
+      emit_insn (targetm.gen_call_value (valreg,
+					 gen_rtx_MEM (FUNCTION_MODE, function),
+					 const0_rtx, NULL_RTX, const0_rtx));
 
       emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
     }
   else
-#endif
     gcc_unreachable ();
 
   /* Find the CALL insn we just emitted, and attach the register usage
Index: gcc/calls.c
===================================================================
--- gcc/calls.c	2015-08-23 21:02:50.008436173 +0100
+++ gcc/calls.c	2015-08-23 21:02:49.992436353 +0100
@@ -291,7 +291,7 @@ emit_call_1 (rtx funexp, tree fntree ATT
 	     cumulative_args_t args_so_far ATTRIBUTE_UNUSED)
 {
   rtx rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
-  rtx call, funmem;
+  rtx call, funmem, pat;
   int already_popped = 0;
   HOST_WIDE_INT n_popped
     = targetm.calls.return_pops_args (fndecl, funtype, stack_size);
@@ -330,90 +330,50 @@ emit_call_1 (rtx funexp, tree fntree ATT
   else if (fntree)
     set_mem_expr (funmem, build_simple_mem_ref (CALL_EXPR_FN (fntree)));
 
-#if defined (HAVE_sibcall_pop) && defined (HAVE_sibcall_value_pop)
-  if ((ecf_flags & ECF_SIBCALL)
-      && HAVE_sibcall_pop && HAVE_sibcall_value_pop
-      && (n_popped > 0 || stack_size == 0))
+  if (ecf_flags & ECF_SIBCALL)
     {
-      rtx n_pop = GEN_INT (n_popped);
-      rtx pat;
-
-      /* If this subroutine pops its own args, record that in the call insn
-	 if possible, for the sake of frame pointer elimination.  */
-
       if (valreg)
-	pat = GEN_SIBCALL_VALUE_POP (valreg, funmem, rounded_stack_size_rtx,
-				     next_arg_reg, n_pop);
+	pat = targetm.gen_sibcall_value (valreg, funmem,
+					 rounded_stack_size_rtx,
+					 next_arg_reg, NULL_RTX);
       else
-	pat = GEN_SIBCALL_POP (funmem, rounded_stack_size_rtx, next_arg_reg,
-			       n_pop);
-
-      emit_call_insn (pat);
-      already_popped = 1;
+	pat = targetm.gen_sibcall (funmem, rounded_stack_size_rtx,
+				   next_arg_reg, GEN_INT (struct_value_size));
     }
-  else
-#endif
-
-#if defined (HAVE_call_pop) && defined (HAVE_call_value_pop)
   /* If the target has "call" or "call_value" insns, then prefer them
      if no arguments are actually popped.  If the target does not have
      "call" or "call_value" insns, then we must use the popping versions
      even if the call has no arguments to pop.  */
-#if defined (HAVE_call) && defined (HAVE_call_value)
-  if (HAVE_call && HAVE_call_value && HAVE_call_pop && HAVE_call_value_pop
-      && n_popped > 0)
-#else
-  if (HAVE_call_pop && HAVE_call_value_pop)
-#endif
+  else if (n_popped > 0
+	   || !(valreg
+		? targetm.have_call_value ()
+		: targetm.have_call ()))
     {
       rtx n_pop = GEN_INT (n_popped);
-      rtx pat;
 
       /* If this subroutine pops its own args, record that in the call insn
 	 if possible, for the sake of frame pointer elimination.  */
 
       if (valreg)
-	pat = GEN_CALL_VALUE_POP (valreg, funmem, rounded_stack_size_rtx,
-				  next_arg_reg, n_pop);
+	pat = targetm.gen_call_value_pop (valreg, funmem,
+					  rounded_stack_size_rtx,
+					  next_arg_reg, n_pop);
       else
-	pat = GEN_CALL_POP (funmem, rounded_stack_size_rtx, next_arg_reg,
-			    n_pop);
+	pat = targetm.gen_call_pop (funmem, rounded_stack_size_rtx,
+				    next_arg_reg, n_pop);
 
-      emit_call_insn (pat);
       already_popped = 1;
     }
   else
-#endif
-
-#if defined (HAVE_sibcall) && defined (HAVE_sibcall_value)
-  if ((ecf_flags & ECF_SIBCALL)
-      && HAVE_sibcall && HAVE_sibcall_value)
     {
       if (valreg)
-	emit_call_insn (GEN_SIBCALL_VALUE (valreg, funmem,
-					   rounded_stack_size_rtx,
-					   next_arg_reg, NULL_RTX));
+	pat = targetm.gen_call_value (valreg, funmem, rounded_stack_size_rtx,
+				      next_arg_reg, NULL_RTX);
       else
-	emit_call_insn (GEN_SIBCALL (funmem, rounded_stack_size_rtx,
-				     next_arg_reg,
-				     GEN_INT (struct_value_size)));
+	pat = targetm.gen_call (funmem, rounded_stack_size_rtx, next_arg_reg,
+				GEN_INT (struct_value_size));
     }
-  else
-#endif
-
-#if defined (HAVE_call) && defined (HAVE_call_value)
-  if (HAVE_call && HAVE_call_value)
-    {
-      if (valreg)
-	emit_call_insn (GEN_CALL_VALUE (valreg, funmem, rounded_stack_size_rtx,
-					next_arg_reg, NULL_RTX));
-      else
-	emit_call_insn (GEN_CALL (funmem, rounded_stack_size_rtx, next_arg_reg,
-				  GEN_INT (struct_value_size)));
-    }
-  else
-#endif
-    gcc_unreachable ();
+  emit_insn (pat);
 
   /* Find the call we just emitted.  */
   rtx_call_insn *call_insn = last_call_insn ();
Index: gcc/config/aarch64/aarch64.md
===================================================================
--- gcc/config/aarch64/aarch64.md	2015-08-23 21:02:50.008436173 +0100
+++ gcc/config/aarch64/aarch64.md	2015-08-23 21:02:49.992436353 +0100
@@ -768,7 +768,7 @@ (define_expand "untyped_call"
 {
   int i;
 
-  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
+  emit_call_insn (gen_call (operands[0], const0_rtx, NULL));
 
   for (i = 0; i < XVECLEN (operands[2], 0); i++)
     {
Index: gcc/config/alpha/alpha.md
===================================================================
--- gcc/config/alpha/alpha.md	2015-08-23 21:02:50.008436173 +0100
+++ gcc/config/alpha/alpha.md	2015-08-23 21:02:49.992436353 +0100
@@ -3646,7 +3646,7 @@ (define_expand "untyped_call"
 {
   int i;
 
-  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
+  emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
 
   for (i = 0; i < XVECLEN (operands[2], 0); i++)
     {
Index: gcc/config/iq2000/iq2000.md
===================================================================
--- gcc/config/iq2000/iq2000.md	2015-08-23 21:02:50.008436173 +0100
+++ gcc/config/iq2000/iq2000.md	2015-08-23 21:02:49.996436308 +0100
@@ -1708,7 +1708,7 @@ (define_expand "untyped_call"
     {
       int i;
 
-      emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
+      emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
 
       for (i = 0; i < XVECLEN (operands[2], 0); i++)
 	{
Index: gcc/config/m68k/m68k.md
===================================================================
--- gcc/config/m68k/m68k.md	2015-08-23 21:02:50.008436173 +0100
+++ gcc/config/m68k/m68k.md	2015-08-23 21:02:49.996436308 +0100
@@ -6908,7 +6908,7 @@ (define_expand "untyped_call"
 {
   int i;
 
-  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
+  emit_call_insn (gen_call (operands[0], const0_rtx));
 
   for (i = 0; i < XVECLEN (operands[2], 0); i++)
     {
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md	2015-08-23 21:02:50.008436173 +0100
+++ gcc/config/mips/mips.md	2015-08-23 21:02:49.996436308 +0100
@@ -7055,7 +7055,7 @@ (define_expand "untyped_call"
 {
   int i;
 
-  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
+  emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
 
   for (i = 0; i < XVECLEN (operands[2], 0); i++)
     {
Index: gcc/config/pa/pa.md
===================================================================
--- gcc/config/pa/pa.md	2015-08-23 21:02:50.008436173 +0100
+++ gcc/config/pa/pa.md	2015-08-23 21:02:50.000436263 +0100
@@ -8248,7 +8248,7 @@ (define_expand "untyped_call"
 {
   int i;
 
-  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
+  emit_call_insn (gen_call (operands[0], const0_rtx));
 
   for (i = 0; i < XVECLEN (operands[2], 0); i++)
     {
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	2015-08-23 21:02:50.008436173 +0100
+++ gcc/config/rs6000/rs6000.md	2015-08-23 21:02:50.000436263 +0100
@@ -9516,7 +9516,7 @@ (define_expand "untyped_call"
 {
   int i;
 
-  emit_call_insn (GEN_CALL (operands[0], const0_rtx, const0_rtx, const0_rtx));
+  emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
 
   for (i = 0; i < XVECLEN (operands[2], 0); i++)
     {
Index: gcc/config/sparc/sparc.md
===================================================================
--- gcc/config/sparc/sparc.md	2015-08-23 21:02:50.008436173 +0100
+++ gcc/config/sparc/sparc.md	2015-08-23 21:02:50.000436263 +0100
@@ -6403,7 +6403,7 @@ (define_expand "untyped_call"
 
   /* Pass constm1 to indicate that it may expect a structure value, but
      we don't know what size it is.  */
-  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
+  emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
 
   /* Save the function value registers.  */
   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
Index: gcc/config/tilegx/tilegx.md
===================================================================
--- gcc/config/tilegx/tilegx.md	2015-08-23 21:02:50.008436173 +0100
+++ gcc/config/tilegx/tilegx.md	2015-08-23 21:02:50.000436263 +0100
@@ -2670,7 +2670,7 @@ (define_expand "untyped_call"
 {
   int i;
 
-  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
+  emit_call_insn (gen_call (operands[0], const0_rtx));
 
   for (i = 0; i < XVECLEN (operands[2], 0); i++)
     {
Index: gcc/config/tilepro/tilepro.md
===================================================================
--- gcc/config/tilepro/tilepro.md	2015-08-23 21:02:50.008436173 +0100
+++ gcc/config/tilepro/tilepro.md	2015-08-23 21:02:50.004436217 +0100
@@ -1516,7 +1516,7 @@ (define_expand "untyped_call"
 {
   int i;
 
-  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
+  emit_call_insn (gen_call (operands[0], const0_rtx));
 
   for (i = 0; i < XVECLEN (operands[2], 0); i++)
     {
Index: gcc/config/visium/visium.md
===================================================================
--- gcc/config/visium/visium.md	2015-08-23 21:02:50.008436173 +0100
+++ gcc/config/visium/visium.md	2015-08-23 21:02:50.004436217 +0100
@@ -2375,7 +2375,7 @@ (define_expand "untyped_call"
 {
   int i;
 
-  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
+  emit_call_insn (gen_call (operands[0], const0_rtx, NULL));
 
   for (i = 0; i < XVECLEN (operands[2], 0); i++)
     {
Index: gcc/config/alpha/alpha.c
===================================================================
--- gcc/config/alpha/alpha.c	2015-08-23 21:02:50.008436173 +0100
+++ gcc/config/alpha/alpha.c	2015-08-23 21:02:49.992436353 +0100
@@ -3110,7 +3110,7 @@ alpha_emit_xfloating_libcall (rtx func,
     }
 
   tmp = gen_rtx_MEM (QImode, func);
-  tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
+  tmp = emit_call_insn (gen_call_value (reg, tmp, const0_rtx,
 					const0_rtx, const0_rtx));
   CALL_INSN_FUNCTION_USAGE (tmp) = usage;
   RTL_CONST_CALL_P (tmp) = 1;
Index: gcc/config/arm/arm.md
===================================================================
--- gcc/config/arm/arm.md	2015-08-23 21:02:50.008436173 +0100
+++ gcc/config/arm/arm.md	2015-08-23 21:02:49.996436308 +0100
@@ -8162,8 +8162,7 @@ (define_expand "untyped_call"
         size += GET_MODE_SIZE (GET_MODE (src));
       }
 
-    emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
-				    const0_rtx));
+    emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
 
     size = 0;
 
Index: gcc/config/cr16/cr16.c
===================================================================
--- gcc/config/cr16/cr16.c	2015-08-23 21:02:50.008436173 +0100
+++ gcc/config/cr16/cr16.c	2015-08-23 21:02:49.996436308 +0100
@@ -583,7 +583,7 @@ cr16_function_arg (cumulative_args_t cum
   /* function_arg () is called with this type just after all the args have 
      had their registers assigned. The rtx that function_arg returns from 
      this type is supposed to pass to 'gen_call' but currently it is not 
-     implemented (see macro GEN_CALL).  */
+     implemented.  */
   if (type == void_type_node)
     return NULL_RTX;
 

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Use target-insns.def for calls
  2015-08-24 12:55 Use target-insns.def for calls Richard Sandiford
@ 2015-08-24 17:54 ` Jeff Law
  0 siblings, 0 replies; 2+ messages in thread
From: Jeff Law @ 2015-08-24 17:54 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford

On 08/24/2015 06:54 AM, Richard Sandiford wrote:
> calls.c had support for sibcall_pop and sibcall_value_pop, but no port
> defines those patterns and the code looks inconsistent with the corresponding
> call_pop vs. call code.  I've therefore dropped it rather than add untested
> entries to the .def file.  (The patterns were also undocumented.)
Sounds reasonable.  Interestingly enough, there are certainly cases 
where a popping sibcall would be helpful, but if we're not using them, 
then dropping seems best.


>
> The calls.c code was a bit confusing in that it tested whether
> sibcall and sibcall_value are available when ECF_SIBCALL is set.
> By this point the decision about whether to use a sibcall has already
> been made, and we set SIBLING_CALL_P directly from ECF_SIBCALL, so we
> would silently generate wrong code if we emitted a normal call instead.
> The patch therefore drops the have_* checks and calls the generator
> regardless.  The generator will assert that the pattern is available.
>
> Tested on x86_64-linux-gnu.  Also tested by building one target per cpu
> directory and checking that there were no changes in the assembly output
> for gcc.dg, g++.dg and gcc.c-torture.  OK to install?
>
> Thanks,
> Richard
>
> gcc/
> 	* genflags.c (gen_macro): Delete.
> 	(gen_proto): Don't create GEN.*CALL.* macros.
> 	* gensupport.h (get_file_location): Declare.
> 	* gensupport.c (rtx_locs): New variable.
> 	(read_md_rtx): Record rtx locations.
> 	(get_file_location): New function.
> 	* target-insns.def (call, call_pop, call_value, call_value_pop)
> 	(sibcall, sibcall_value): New patterns.
> 	* gentarget-def.c (parse_argument): New function.
> 	(def_target_insn): Use it.  Handle optional operands.  Raise an
> 	error if an .md pattern has the wrong number of operands for the
> 	pattern name.  Remove the names of unused operands from the prototype.
> 	* builtins.c (expand_builtin_apply): Use targetm functions
> 	instead of HAVE_call_value and GEN_CALL_VALUE.
> 	* calls.c (emit_call_1): Likewise.  Remove support for sibcall_pop
> 	and sibcall_value_pop.
> 	* config/aarch64/aarch64.md (untyped_call): Use gen_call instead
> 	of GEN_CALL.
> 	* config/alpha/alpha.md (untyped_call): Likewise.
> 	* config/iq2000/iq2000.md (untyped_call): Likewise.
> 	* config/m68k/m68k.md (untyped_call): Likewise.
> 	* config/mips/mips.md (untyped_call): Likewise.
> 	* config/pa/pa.md (untyped_call): Likewise.
> 	* config/rs6000/rs6000.md (untyped_call): Likewise.
> 	* config/sparc/sparc.md (untyped_call): Likewise.
> 	* config/tilegx/tilegx.md (untyped_call): Likewise.
> 	* config/tilepro/tilepro.md (untyped_call): Likewise.
> 	* config/visium/visium.md (untyped_call): Likewise.
> 	* config/alpha/alpha.c (alpha_emit_xfloating_libcall): Use
> 	gen_call_value instead of GEN_CALL_VALUE.
> 	* config/arm/arm.md (untyped_call): Likewise.
> 	* config/cr16/cr16.c (cr16_function_arg): Remove reference to
> 	GEN_CALL.
OK

Thanks,
Jeff


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-08-24 17:41 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-24 12:55 Use target-insns.def for calls Richard Sandiford
2015-08-24 17:54 ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).