nvptx.c (nvptx_function_arg, [...]): Move earlier.
authorNathan Sidwell <nathan@acm.org>
Thu, 10 Dec 2015 20:13:14 +0000 (20:13 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 10 Dec 2015 20:13:14 +0000 (20:13 +0000)
* config/nvptx/nvptx.c (nvptx_function_arg,
nvptx_function_incoming_arg, nvptx_function_arg_advance,
nvptx_strict_argument_naming, nvptx_function_arg_boundary,
nvptx_libcall_value, nvptx_function_value,
nvptx_function_value_regno_p, nvptx_pass_by_reference,
nvptx_return_in_memory, nvptx_promote_function_mode,
nvptx_static_chain): Move earlier.
(write_one_arg): Break out as helper fn for ...
(write_arg): ... this new function.  Adjust all callers.

From-SVN: r231543

gcc/ChangeLog
gcc/config/nvptx/nvptx.c

index 056b7abcb005e063e6ac11f33146202da827f03d..27ccfc8cf72fea099f1729449a77a3393bae8a40 100644 (file)
@@ -1,3 +1,15 @@
+2015-12-10  Nathan Sidwell  <nathan@acm.org>
+
+       * config/nvptx/nvptx.c (nvptx_function_arg,
+       nvptx_function_incoming_arg, nvptx_function_arg_advance,
+       nvptx_strict_argument_naming, nvptx_function_arg_boundary,
+       nvptx_libcall_value, nvptx_function_value,
+       nvptx_function_value_regno_p, nvptx_pass_by_reference,
+       nvptx_return_in_memory, nvptx_promote_function_mode,
+       nvptx_static_chain): Move earlier.
+       (write_one_arg): Break out as helper fn for ...
+       (write_arg): ... this new function.  Adjust all callers.
+
 2015-12-10  Jan Hubicka  <hubicka@ucw.cz>
 
        * lto-streamer-out.c (wrap_refs): Only wrap public decls.
index d9ccb81a0452b4416cc2a71cb8441ce65417ddc5..5bd2662574e4d97bd89d45efdc160a3d52ea4058 100644 (file)
@@ -389,69 +389,270 @@ arg_promotion (machine_mode mode)
   return mode;
 }
 
-/* Process function parameter TYPE, either emitting in a prototype
-   argument, or as a copy a in a function prologue.  ARGNO is the
-   index of this argument in the PTX function.  FOR_REG is negative,
-   if we're emitting the PTX prototype.  It is zero if we're copying
-   to an argument register and it is greater than zero if we're
-   copying to a specific hard register.  PROTOTYPED is true, if this
-   is a prototyped function, rather than an old-style C declaration.
+/* Implement TARGET_FUNCTION_ARG.  */
 
-   The behaviour here must match the regular GCC function parameter
-   marshalling machinery.  */
+static rtx
+nvptx_function_arg (cumulative_args_t, machine_mode mode,
+                   const_tree, bool named)
+{
+  if (mode == VOIDmode)
+    return NULL_RTX;
 
-static int
-write_one_arg (std::stringstream &s, int for_reg, int argno,
-              tree type, bool prototyped)
+  if (named)
+    return gen_reg_rtx (mode);
+  return NULL_RTX;
+}
+
+/* Implement TARGET_FUNCTION_INCOMING_ARG.  */
+
+static rtx
+nvptx_function_incoming_arg (cumulative_args_t cum_v, machine_mode mode,
+                            const_tree, bool named)
 {
-  machine_mode mode = TYPE_MODE (type);
+  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
+  if (mode == VOIDmode)
+    return NULL_RTX;
 
-  if (!PASS_IN_REG_P (mode, type))
-    mode = Pmode;
+  if (!named)
+    return NULL_RTX;
 
-  machine_mode split = maybe_split_mode (mode);
-  if (split != VOIDmode)
+  /* No need to deal with split modes here, the only case that can
+     happen is complex modes and those are dealt with by
+     TARGET_SPLIT_COMPLEX_ARG.  */
+  return gen_rtx_UNSPEC (mode,
+                        gen_rtvec (1, GEN_INT (cum->count)),
+                        UNSPEC_ARG_REG);
+}
+
+/* Implement TARGET_FUNCTION_ARG_ADVANCE.  */
+
+static void
+nvptx_function_arg_advance (cumulative_args_t cum_v,
+                           machine_mode ARG_UNUSED (mode),
+                           const_tree ARG_UNUSED (type),
+                           bool ARG_UNUSED (named))
+{
+  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
+  cum->count++;
+}
+
+/* Handle the TARGET_STRICT_ARGUMENT_NAMING target hook.
+
+   For nvptx, we know how to handle functions declared as stdarg: by
+   passing an extra pointer to the unnamed arguments.  However, the
+   Fortran frontend can produce a different situation, where a
+   function pointer is declared with no arguments, but the actual
+   function and calls to it take more arguments.  In that case, we
+   want to ensure the call matches the definition of the function.  */
+
+static bool
+nvptx_strict_argument_naming (cumulative_args_t cum_v)
+{
+  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
+  return cum->fntype == NULL_TREE || stdarg_p (cum->fntype);
+}
+
+/* Implement TARGET_FUNCTION_ARG_BOUNDARY.  */
+
+static unsigned int
+nvptx_function_arg_boundary (machine_mode mode, const_tree type)
+{
+  unsigned int boundary = type ? TYPE_ALIGN (type) : GET_MODE_BITSIZE (mode);
+
+  if (boundary > BITS_PER_WORD)
+    return 2 * BITS_PER_WORD;
+
+  if (mode == BLKmode)
     {
-      mode = split;
-      argno = write_one_arg (s, for_reg, argno,
-                            TREE_TYPE (type), prototyped);
+      HOST_WIDE_INT size = int_size_in_bytes (type);
+      if (size > 4)
+        return 2 * BITS_PER_WORD;
+      if (boundary < BITS_PER_WORD)
+        {
+          if (size >= 3)
+            return BITS_PER_WORD;
+          if (size >= 2)
+            return 2 * BITS_PER_UNIT;
+        }
     }
+  return boundary;
+}
 
-  if (!prototyped && !AGGREGATE_TYPE_P (type))
+/* Implement TARGET_LIBCALL_VALUE.  */
+
+static rtx
+nvptx_libcall_value (machine_mode mode, const_rtx)
+{
+  if (cfun->machine->start_call == NULL_RTX)
+    /* Pretend to return in a hard reg for early uses before pseudos can be
+       generated.  */
+    return gen_rtx_REG (mode, NVPTX_RETURN_REGNUM);
+  return gen_reg_rtx (mode);
+}
+
+/* TARGET_FUNCTION_VALUE implementation.  Returns an RTX representing the place
+   where function FUNC returns or receives a value of data type TYPE.  */
+
+static rtx
+nvptx_function_value (const_tree type, const_tree func ATTRIBUTE_UNUSED,
+                     bool outgoing)
+{
+  int unsignedp = TYPE_UNSIGNED (type);
+  machine_mode orig_mode = TYPE_MODE (type);
+  machine_mode mode = promote_function_mode (type, orig_mode,
+                                            &unsignedp, NULL_TREE, 1);
+  if (outgoing)
+    return gen_rtx_REG (mode, NVPTX_RETURN_REGNUM);
+  if (cfun->machine->start_call == NULL_RTX)
+    /* Pretend to return in a hard reg for early uses before pseudos can be
+       generated.  */
+    return gen_rtx_REG (mode, NVPTX_RETURN_REGNUM);
+  return gen_reg_rtx (mode);
+}
+
+/* Implement TARGET_FUNCTION_VALUE_REGNO_P.  */
+
+static bool
+nvptx_function_value_regno_p (const unsigned int regno)
+{
+  return regno == NVPTX_RETURN_REGNUM;
+}
+
+/* Types with a mode other than those supported by the machine are passed by
+   reference in memory.  */
+
+static bool
+nvptx_pass_by_reference (cumulative_args_t, machine_mode mode,
+                        const_tree type, bool)
+{
+  return !PASS_IN_REG_P (mode, type);
+}
+
+/* Implement TARGET_RETURN_IN_MEMORY.  */
+
+static bool
+nvptx_return_in_memory (const_tree type, const_tree)
+{
+  machine_mode mode = TYPE_MODE (type);
+  if (!RETURN_IN_REG_P (mode))
+    return true;
+  return false;
+}
+
+/* Implement TARGET_PROMOTE_FUNCTION_MODE.  */
+
+static machine_mode
+nvptx_promote_function_mode (const_tree type, machine_mode mode,
+                            int *punsignedp,
+                            const_tree funtype, int for_return)
+{
+  if (type == NULL_TREE)
+    return mode;
+  if (for_return)
+    return promote_mode (type, mode, punsignedp);
+  /* For K&R-style functions, try to match the language promotion rules to
+     minimize type mismatches at assembly time.  */
+  if (TYPE_ARG_TYPES (funtype) == NULL_TREE
+      && type != NULL_TREE
+      && !AGGREGATE_TYPE_P (type))
     {
       if (mode == SFmode)
        mode = DFmode;
       mode = arg_promotion (mode);
     }
 
+  return mode;
+}
+
+/* Implement TARGET_STATIC_CHAIN.  */
+
+static rtx
+nvptx_static_chain (const_tree fndecl, bool incoming_p)
+{
+  if (!DECL_STATIC_CHAIN (fndecl))
+    return NULL;
+
+  if (incoming_p)
+    return gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
+  else
+    return gen_rtx_REG (Pmode, OUTGOING_STATIC_CHAIN_REGNUM);
+}
+
+/* Helper for write_arg.  Emit a single PTX argument of MODE, either
+   in a prototype, or as copy in a function prologue.  ARGNO is the
+   index of this argument in the PTX function.  FOR_REG is negative,
+   if we're emitting the PTX prototype.  It is zero if we're copying
+   to an argument register and it is greater than zero if we're
+   copying to a specific hard register.  */
+
+static int
+write_one_arg (std::stringstream &s, int for_reg, int argno, machine_mode mode)
+{
+  const char *ptx_type = nvptx_ptx_type_from_mode (mode, false);
+
   if (for_reg < 0)
     {
       /* Writing PTX prototype.  */
       s << (argno ? ", " : " (");
-      s << ".param" << nvptx_ptx_type_from_mode (mode, false)
-       << " %in_ar" << argno;
+      s << ".param" << ptx_type << " %in_ar" << argno;
       if (mode == QImode || mode == HImode)
        s << "[1]";
     }
   else
     {
-      mode = arg_promotion (mode);
-      s << "\t.reg" << nvptx_ptx_type_from_mode (mode, false) << " ";
+      s << "\t.reg" << ptx_type << " ";
       if (for_reg)
        s << reg_names[for_reg];
       else
        s << "%ar" << argno;
       s << ";\n";
-      s << "\tld.param" << nvptx_ptx_type_from_mode (mode, false) << " ";
+      s << "\tld.param" << ptx_type << " ";
       if (for_reg)
        s << reg_names[for_reg];
       else
        s << "%ar" << argno;
-      s<< ", [%in_ar" << argno << "];\n";
+      s << ", [%in_ar" << argno << "];\n";
     }
   return argno + 1;
 }
 
+/* Process function parameter TYPE to emit one or more PTX
+   arguments.  PROTOTYPED is true, if this is a prototyped function,
+   rather than an old-style C declaration.
+
+   The promotion behaviour here must match the regular GCC function
+   parameter marshalling machinery.  */
+
+static int
+write_arg (std::stringstream &s, int for_reg, int argno,
+          tree type, bool prototyped)
+{
+  machine_mode mode = TYPE_MODE (type);
+
+  if (mode == VOIDmode)
+    return argno;
+
+  if (!PASS_IN_REG_P (mode, type))
+    mode = Pmode;
+
+  machine_mode split = maybe_split_mode (mode);
+  if (split != VOIDmode)
+    mode = split;
+
+  if (!prototyped && !AGGREGATE_TYPE_P (type))
+    {
+      if (mode == SFmode)
+       mode = DFmode;
+      mode = arg_promotion (mode);
+    }
+  else if (for_reg >= 0)
+    mode = arg_promotion (mode);
+
+  if (split != VOIDmode)
+    argno = write_one_arg (s, for_reg, argno, mode);
+  return write_one_arg (s, for_reg, argno, mode);
+}
+
 static bool
 write_return (std::stringstream &s, bool for_proto, tree type,
              machine_mode ret_mode)
@@ -555,7 +756,7 @@ write_fn_proto (std::stringstream &s, bool is_defn,
 
   /* Emit argument list.  */
   if (return_in_mem)
-    argno = write_one_arg (s, -1, argno, ptr_type_node, true);
+    argno = write_arg (s, -1, argno, ptr_type_node, true);
 
   /* We get:
      NULL in TYPE_ARG_TYPES, for old-style functions
@@ -574,20 +775,19 @@ write_fn_proto (std::stringstream &s, bool is_defn,
     {
       tree type = prototyped ? TREE_VALUE (args) : TREE_TYPE (args);
 
-      if (type != void_type_node)
-       argno = write_one_arg (s, -1, argno, type, prototyped);
+      argno = write_arg (s, -1, argno, type, prototyped);
     }
 
   if (stdarg_p (fntype))
-    argno = write_one_arg (s, -1, argno, ptr_type_node, true);
+    argno = write_arg (s, -1, argno, ptr_type_node, true);
 
   if (DECL_STATIC_CHAIN (decl))
-    argno = write_one_arg (s, -1, argno, ptr_type_node, true);
+    argno = write_arg (s, -1, argno, ptr_type_node, true);
 
   if (!argno && strcmp (name, "main") == 0)
     {
-      argno = write_one_arg (s, -1, argno, integer_type_node, true);
-      argno = write_one_arg (s, -1, argno, ptr_type_node, true);
+      argno = write_arg (s, -1, argno, integer_type_node, true);
+      argno = write_arg (s, -1, argno, ptr_type_node, true);
     }
 
   if (argno)
@@ -743,7 +943,7 @@ nvptx_declare_function_name (FILE *file, const char *name, const_tree decl)
   bool return_in_mem = write_return (s, false, result_type,
                                     (machine_mode)cfun->machine->ret_reg_mode);
   if (return_in_mem)
-    argno = write_one_arg (s, 0, argno, ptr_type_node, true);
+    argno = write_arg (s, 0, argno, ptr_type_node, true);
   
   /* Declare and initialize incoming arguments.  */
   tree args = TYPE_ARG_TYPES (fntype);
@@ -758,15 +958,14 @@ nvptx_declare_function_name (FILE *file, const char *name, const_tree decl)
     {
       tree type = prototyped ? TREE_VALUE (args) : TREE_TYPE (args);
 
-      if (type != void_type_node)
-       argno = write_one_arg (s, 0, argno, type, prototyped);
+      argno = write_arg (s, 0, argno, type, prototyped);
     }
 
   if (stdarg_p (fntype))
-    argno = write_one_arg (s, ARG_POINTER_REGNUM, argno, ptr_type_node, true);
+    argno = write_arg (s, ARG_POINTER_REGNUM, argno, ptr_type_node, true);
 
   if (DECL_STATIC_CHAIN (decl))
-    argno = write_one_arg (s, STATIC_CHAIN_REGNUM, argno, ptr_type_node, true);
+    argno = write_arg (s, STATIC_CHAIN_REGNUM, argno, ptr_type_node, true);
 
   fprintf (file, "%s", s.str().c_str());
 
@@ -1001,196 +1200,6 @@ nvptx_expand_call (rtx retval, rtx address)
   if (tmp_retval != retval)
     emit_move_insn (retval, tmp_retval);
 }
-
-/* Implement TARGET_FUNCTION_ARG.  */
-
-static rtx
-nvptx_function_arg (cumulative_args_t, machine_mode mode,
-                   const_tree, bool named)
-{
-  if (mode == VOIDmode)
-    return NULL_RTX;
-
-  if (named)
-    return gen_reg_rtx (mode);
-  return NULL_RTX;
-}
-
-/* Implement TARGET_FUNCTION_INCOMING_ARG.  */
-
-static rtx
-nvptx_function_incoming_arg (cumulative_args_t cum_v, machine_mode mode,
-                            const_tree, bool named)
-{
-  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
-  if (mode == VOIDmode)
-    return NULL_RTX;
-
-  if (!named)
-    return NULL_RTX;
-
-  /* No need to deal with split modes here, the only case that can
-     happen is complex modes and those are dealt with by
-     TARGET_SPLIT_COMPLEX_ARG.  */
-  return gen_rtx_UNSPEC (mode,
-                        gen_rtvec (1, GEN_INT (cum->count)),
-                        UNSPEC_ARG_REG);
-}
-
-/* Implement TARGET_FUNCTION_ARG_ADVANCE.  */
-
-static void
-nvptx_function_arg_advance (cumulative_args_t cum_v,
-                           machine_mode ARG_UNUSED (mode),
-                           const_tree ARG_UNUSED (type),
-                           bool ARG_UNUSED (named))
-{
-  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
-  cum->count++;
-}
-
-/* Handle the TARGET_STRICT_ARGUMENT_NAMING target hook.
-
-   For nvptx, we know how to handle functions declared as stdarg: by
-   passing an extra pointer to the unnamed arguments.  However, the
-   Fortran frontend can produce a different situation, where a
-   function pointer is declared with no arguments, but the actual
-   function and calls to it take more arguments.  In that case, we
-   want to ensure the call matches the definition of the function.  */
-
-static bool
-nvptx_strict_argument_naming (cumulative_args_t cum_v)
-{
-  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
-  return cum->fntype == NULL_TREE || stdarg_p (cum->fntype);
-}
-
-/* Implement TARGET_FUNCTION_ARG_BOUNDARY.  */
-
-static unsigned int
-nvptx_function_arg_boundary (machine_mode mode, const_tree type)
-{
-  unsigned int boundary = type ? TYPE_ALIGN (type) : GET_MODE_BITSIZE (mode);
-
-  if (boundary > BITS_PER_WORD)
-    return 2 * BITS_PER_WORD;
-
-  if (mode == BLKmode)
-    {
-      HOST_WIDE_INT size = int_size_in_bytes (type);
-      if (size > 4)
-        return 2 * BITS_PER_WORD;
-      if (boundary < BITS_PER_WORD)
-        {
-          if (size >= 3)
-            return BITS_PER_WORD;
-          if (size >= 2)
-            return 2 * BITS_PER_UNIT;
-        }
-    }
-  return boundary;
-}
-
-/* TARGET_FUNCTION_VALUE implementation.  Returns an RTX representing the place
-   where function FUNC returns or receives a value of data type TYPE.  */
-
-static rtx
-nvptx_function_value (const_tree type, const_tree func ATTRIBUTE_UNUSED,
-                     bool outgoing)
-{
-  int unsignedp = TYPE_UNSIGNED (type);
-  machine_mode orig_mode = TYPE_MODE (type);
-  machine_mode mode = promote_function_mode (type, orig_mode,
-                                            &unsignedp, NULL_TREE, 1);
-  if (outgoing)
-    return gen_rtx_REG (mode, NVPTX_RETURN_REGNUM);
-  if (cfun->machine->start_call == NULL_RTX)
-    /* Pretend to return in a hard reg for early uses before pseudos can be
-       generated.  */
-    return gen_rtx_REG (mode, NVPTX_RETURN_REGNUM);
-  return gen_reg_rtx (mode);
-}
-
-/* Implement TARGET_LIBCALL_VALUE.  */
-
-static rtx
-nvptx_libcall_value (machine_mode mode, const_rtx)
-{
-  if (cfun->machine->start_call == NULL_RTX)
-    /* Pretend to return in a hard reg for early uses before pseudos can be
-       generated.  */
-    return gen_rtx_REG (mode, NVPTX_RETURN_REGNUM);
-  return gen_reg_rtx (mode);
-}
-
-/* Implement TARGET_FUNCTION_VALUE_REGNO_P.  */
-
-static bool
-nvptx_function_value_regno_p (const unsigned int regno)
-{
-  return regno == NVPTX_RETURN_REGNUM;
-}
-
-/* Types with a mode other than those supported by the machine are passed by
-   reference in memory.  */
-
-static bool
-nvptx_pass_by_reference (cumulative_args_t, machine_mode mode,
-                        const_tree type, bool)
-{
-  return !PASS_IN_REG_P (mode, type);
-}
-
-/* Implement TARGET_RETURN_IN_MEMORY.  */
-
-static bool
-nvptx_return_in_memory (const_tree type, const_tree)
-{
-  machine_mode mode = TYPE_MODE (type);
-  if (!RETURN_IN_REG_P (mode))
-    return true;
-  return false;
-}
-
-/* Implement TARGET_PROMOTE_FUNCTION_MODE.  */
-
-static machine_mode
-nvptx_promote_function_mode (const_tree type, machine_mode mode,
-                            int *punsignedp,
-                            const_tree funtype, int for_return)
-{
-  if (type == NULL_TREE)
-    return mode;
-  if (for_return)
-    return promote_mode (type, mode, punsignedp);
-  /* For K&R-style functions, try to match the language promotion rules to
-     minimize type mismatches at assembly time.  */
-  if (TYPE_ARG_TYPES (funtype) == NULL_TREE
-      && type != NULL_TREE
-      && !AGGREGATE_TYPE_P (type))
-    {
-      if (mode == SFmode)
-       mode = DFmode;
-      mode = arg_promotion (mode);
-    }
-
-  return mode;
-}
-
-/* Implement TARGET_STATIC_CHAIN.  */
-
-static rtx
-nvptx_static_chain (const_tree fndecl, bool incoming_p)
-{
-  if (!DECL_STATIC_CHAIN (fndecl))
-    return NULL;
-
-  if (incoming_p)
-    return gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
-  else
-    return gen_rtx_REG (Pmode, OUTGOING_STATIC_CHAIN_REGNUM);
-}
-\f
 /* Emit a comparison COMPARE, and return the new test to be used in the
    jump.  */