diff mbox

[PTX] simplify call emission

Message ID 56571496.3000904@acm.org
State New
Headers show

Commit Message

Nathan Sidwell Nov. 26, 2015, 2:17 p.m. UTC
I've committed this patch to simplify some more call emission machinery.

write_func_decl_from_insn was doing more work than necessary.
1) it doesn't need to examine the callee to figure out whether this is an 
indirect call or not.  It's callers have already done this, and can pass in the 
relevant info (name or NULL).

2) it doesn't need to deal with split regs.  That was already done when the call 
was expanded.

nvptx_output_call_insn had the same issue with split regs.

I changed the formatting slightly, so the proto-1.c testcase needed a tweak. 
While there I canged the fn name from nearly-but-not-quite acc_on_device, to 
'foo', so it didn;t look superficially like a builtin test.

nathan
diff mbox

Patch

2015-11-26  Nathan Sidwell  <nathan@acm.org>

	* config/nvptx/nvptx.c (write_func_decl_from_insn): Replace callee
	arg with name.  Don't deal with split regs.  Tweak formatting.
	(nvptx_expand_call): Adjust write_func_decl_from_insn call.
	(nvptx_output_call_insn): Don't deal with split regs here.

	testsuite/
	* gcc.target/nvptx/proto-1.c: Adjust expected asm.


Index: config/nvptx/nvptx.c
===================================================================
--- config/nvptx/nvptx.c	(revision 230963)
+++ config/nvptx/nvptx.c	(working copy)
@@ -719,69 +719,46 @@  nvptx_output_return (void)
    generated by emit_library_call for which no decl exists.  */
 
 static void
-write_func_decl_from_insn (std::stringstream &s, rtx result, rtx pat,
-			   rtx callee)
+write_func_decl_from_insn (std::stringstream &s, const char *name,
+			   rtx result, rtx pat)
 {
-  bool callprototype = register_operand (callee, Pmode);
-  const char *name = "_";
-  if (!callprototype)
+  if (!name)
+    {
+      s << "\t.callprototype ";
+      name = "_";
+    }
+  else
     {
-      name = XSTR (callee, 0);
-      name = nvptx_name_replacement (name);
       s << "\n// BEGIN GLOBAL FUNCTION DECL: " << name << "\n";
+      s << "\t.extern .func ";
     }
-  s << (callprototype ? "\t.callprototype\t" : "\t.extern .func ");
 
   if (result != NULL_RTX)
-    {
-      s << "(.param";
-      s << nvptx_ptx_type_from_mode (arg_promotion (GET_MODE (result)),
-				     false);
-      s << " ";
-      if (callprototype)
-	s << "_";
-      else
-	s << "%out_retval";
-      s << ")";
-    }
+    s << "(.param"
+      << nvptx_ptx_type_from_mode (arg_promotion (GET_MODE (result)), false)
+      << " %rval) ";
 
   s << name;
 
+  const char *sep = " (";
   int arg_end = XVECLEN (pat, 0);
-      
-  if (1 < arg_end)
+  for (int i = 1; i < arg_end; i++)
     {
-      const char *comma = "";
-      s << " (";
-      for (int i = 1; i < arg_end; i++)
-	{
-	  rtx t = XEXP (XVECEXP (pat, 0, i), 0);
-	  machine_mode mode = GET_MODE (t);
-	  machine_mode split = maybe_split_mode (mode);
-	  int count = 1;
-
-	  if (split != VOIDmode)
-	    {
-	      mode = split;
-	      count = 2;
-	    }
-
-	  while (count--)
-	    {
-	      s << comma << ".param";
-	      s << nvptx_ptx_type_from_mode (mode, false);
-	      s << " ";
-	      if (callprototype)
-		s << "_";
-	      else
-		s << "%arg" << i - 1;
-	      if (mode == QImode || mode == HImode)
-		s << "[1]";
-	      comma = ", ";
-	    }
-	}
-      s << ")";
+      /* We don't have to deal with mode splitting here, as that was
+	 already done when generating the call sequence.  */
+      machine_mode mode = GET_MODE (XEXP (XVECEXP (pat, 0, i), 0));
+
+      s << sep
+	<< ".param"
+	<< nvptx_ptx_type_from_mode (mode, false)
+	<< " %arg"
+	<< i;
+      if (mode == QImode || mode == HImode)
+	s << "[1]";
+      sep = ", ";
     }
+  if (arg_end != 1)
+    s << ")";
   s << ";\n";
 }
 
@@ -905,10 +882,7 @@  nvptx_expand_call (rtx retval, rtx addre
       && stdarg_p (cfun->machine->funtype))
     {
       varargs = gen_reg_rtx (Pmode);
-      if (Pmode == DImode)
-	emit_move_insn (varargs, stack_pointer_rtx);
-      else
-	emit_move_insn (varargs, stack_pointer_rtx);
+      emit_move_insn (varargs, stack_pointer_rtx);
       cfun->machine->has_call_with_varargs = true;
     }
   vec = rtvec_alloc (nargs + 1 + (varargs ? 1 : 0));
@@ -951,7 +925,11 @@  nvptx_expand_call (rtx retval, rtx addre
       if (*slot == NULL)
 	{
 	  *slot = callee;
-	  write_func_decl_from_insn (func_decls, retval, pat, callee);
+
+	  const char *name = XSTR (callee, 0);
+	  if (decl_type)
+	    name = nvptx_name_replacement (name);
+	  write_func_decl_from_insn (func_decls, name, retval, pat);
 	}
     }
 
@@ -1798,7 +1776,7 @@  nvptx_assemble_undefined_decl (FILE *fil
 const char *
 nvptx_output_call_insn (rtx_insn *insn, rtx result, rtx callee)
 {
-  char buf[256];
+  char buf[16];
   static int labelno;
   bool needs_tgt = register_operand (callee, Pmode);
   rtx pat = PATTERN (insn);
@@ -1825,36 +1803,22 @@  nvptx_output_call_insn (rtx_insn *insn,
       labelno++;
       ASM_OUTPUT_LABEL (asm_out_file, buf);
       std::stringstream s;
-      write_func_decl_from_insn (s, result, pat, callee);
+      write_func_decl_from_insn (s, NULL, result, pat);
       fputs (s.str().c_str(), asm_out_file);
     }
 
-  for (int i = 1, argno = 0; i < arg_end; i++)
+  for (int argno = 1; argno < arg_end; argno++)
     {
-      rtx t = XEXP (XVECEXP (pat, 0, i), 0);
+      rtx t = XEXP (XVECEXP (pat, 0, argno), 0);
       machine_mode mode = GET_MODE (t);
-      machine_mode split = maybe_split_mode (mode);
-      int count = 1;
-      
-      if (split != VOIDmode)
-	{
-	  mode = split;
-	  count = 2;
-	}
 
-      for (int n = 0; n != count; n++)
-	{
-	  fprintf (asm_out_file, "\t\t.param%s %%out_arg%d%s;\n",
-		   nvptx_ptx_type_from_mode (mode, false), argno,
-		   mode == QImode || mode == HImode ? "[1]" : "");
-	  fprintf (asm_out_file, "\t\tst.param%s [%%out_arg%d], %%r%d",
-		   nvptx_ptx_type_from_mode (mode, false), argno,
-		   REGNO (t));
-	  if (split != VOIDmode)
-	    fprintf (asm_out_file, "$%d", n);
-	  fprintf (asm_out_file, ";\n");
-	  argno++;
-	}
+      /* Mode splitting has already been done.  */
+      fprintf (asm_out_file, "\t\t.param%s %%out_arg%d%s;\n",
+	       nvptx_ptx_type_from_mode (mode, false), argno,
+	       mode == QImode || mode == HImode ? "[1]" : "");
+      fprintf (asm_out_file, "\t\tst.param%s [%%out_arg%d], %%r%d;\n",
+	       nvptx_ptx_type_from_mode (mode, false), argno,
+	       REGNO (t));
     }
 
   fprintf (asm_out_file, "\t\tcall ");
@@ -1870,31 +1834,20 @@  nvptx_output_call_insn (rtx_insn *insn,
   else
     output_address (VOIDmode, callee);
 
-  if (arg_end > 1 || (decl && DECL_STATIC_CHAIN (decl)))
+  const char *open = "(";
+  for (int argno = 1; argno < arg_end; argno++)
     {
-      const char *comma = "";
-      
-      fprintf (asm_out_file, ", (");
-      for (int i = 1, argno = 0; i < arg_end; i++)
-	{
-	  rtx t = XEXP (XVECEXP (pat, 0, i), 0);
-	  machine_mode mode = GET_MODE (t);
-	  machine_mode split = maybe_split_mode (mode);
-
-	  if (split != VOIDmode)
-	    {
-	      fprintf (asm_out_file, "%s%%out_arg%d", comma, argno++);
-	      comma = ", ";
-	    }
-	  fprintf (asm_out_file, "%s%%out_arg%d", comma, argno++);
-	  comma = ", ";
-	}
-      if (decl && DECL_STATIC_CHAIN (decl))
-	fprintf (asm_out_file, "%s%s", comma,
-		 reg_names [OUTGOING_STATIC_CHAIN_REGNUM]);
-
-      fprintf (asm_out_file, ")");
+      fprintf (asm_out_file, ", %s%%out_arg%d", open, argno);
+      open = "";
+    }
+  if (decl && DECL_STATIC_CHAIN (decl))
+    {
+      fprintf (asm_out_file, ", %s%s", open,
+	       reg_names [OUTGOING_STATIC_CHAIN_REGNUM]);
+      open = "";
     }
+  if (!open[0])
+    fprintf (asm_out_file, ")");
 
   if (needs_tgt)
     {
@@ -1902,10 +1855,8 @@  nvptx_output_call_insn (rtx_insn *insn,
       assemble_name (asm_out_file, buf);
     }
   fprintf (asm_out_file, ";\n");
-  if (result != NULL_RTX)
-    return "\tld.param%t0\t%0, [%%retval_in];\n\t}";
 
-  return "}";
+  return result != NULL_RTX ? "\tld.param%t0\t%0, [%%retval_in];\n\t}" : "}";
 }
 
 /* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P.  */
Index: testsuite/gcc.target/nvptx/proto-1.c
===================================================================
--- testsuite/gcc.target/nvptx/proto-1.c	(revision 230963)
+++ testsuite/gcc.target/nvptx/proto-1.c	(working copy)
@@ -6,8 +6,8 @@  int f(void)
 
   /* Check that without an explicit prototype, we deduce from call site the
      signature for the (mandatory in PTX) prototype.  */
-  /* extern int acc_on_device_(int *); */
+  /* extern int foo (int *); */
   /* { dg-final { scan-assembler-not "\\\.callprototype" } } */
-  /* { dg-final { scan-assembler "\\\.extern \\\.func \\\(\[^,\n\r\]+\\\)acc_on_device_ \\\(\[^,\n\r\]+\\\);" } } */
-  return !acc_on_device_(&dev);
+  /* { dg-final { scan-assembler "\\\.extern \\\.func \\\(\[^,\n\r\]+\\\) foo \\\(\[^,\n\r\]+\\\);" } } */
+  return !foo(&dev);
 }