Use function_arg_info for TARGET_MUST_PASS_IN_STACK
authorRichard Sandiford <richard.sandiford@arm.com>
Tue, 20 Aug 2019 08:53:39 +0000 (08:53 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 20 Aug 2019 08:53:39 +0000 (08:53 +0000)
The hook is passed the promoted mode instead of the original type mode.

The expr.h reference in the documentation is no longer correct, but
pointing to calls.h or calls.c doesn't help much either.  I just left
this as-is since it's not related to the point of the series.

After previous changes, most places already pass arg.mode and arg.type.
Only i386 and mcore needed to construct a new one out of nothing.
rs6000 needs to construct one slightly earlier than before.

2019-08-20  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
* target.def (must_pass_in_stack): Take a function_arg_info instead
of a mode and a type.
* doc/tm.texi: Regenerate.
* calls.h (must_pass_in_stack_var_size): Take a function_arg_info
instead of a mode and a type.
(must_pass_in_stack_var_size_or_pad): Likewise.
* calls.c (must_pass_in_stack_var_size): Likewise.
(must_pass_in_stack_var_size_or_pad): Likewise.
(initialize_argument_information): Update call to
targetm.calls.must_pass_in_stack.
(must_pass_va_arg_on_stack): Likewise.
* function.c (assign_parm_find_entry_rtl): Likewise.
* targhooks.c (hook_pass_by_reference_must_pass_in_stack): Likewise.
* config/alpha/alpha.c (alpha_function_arg): Likewise.
(alpha_function_arg_advance): Likewise.
* config/cr16/cr16.c (cr16_function_arg): Likewise.
(cr16_function_arg_advance): Likewise.
* config/cris/cris.c (cris_pass_by_reference): Likewise.
(cris_arg_partial_bytes): Likewise.
* config/iq2000/iq2000.c (iq2000_pass_by_reference): Likewise.
* config/lm32/lm32.c (lm32_function_arg): Likewise.
* config/mcore/mcore.c (mcore_num_arg_regs): Likewise.
(mcore_function_arg, mcore_arg_partial_bytes): Likewise.
* config/mips/mips.c (mips_pass_by_reference): Likewise.
* config/mmix/mmix.c (mmix_function_arg_advance): Likewise.
(mmix_function_arg_1, mmix_pass_by_reference): Likewise.
* config/sh/sh.c (sh_pass_by_reference): Likewise.
* config/stormy16/stormy16.c (xstormy16_function_arg): Likewise.
* config/xtensa/xtensa.c (xtensa_function_arg_advance): Likewise.
* config/arm/arm.c (arm_must_pass_in_stack): Take a function_arg_info
instead of a mode and a type.
* config/fr30/fr30.c (fr30_must_pass_in_stack): Likewise.
(fr30_num_arg_regs): Likewise.
(fr30_setup_incoming_varargs): Update calls accordingly.
(fr30_arg_partial_bytes, fr30_function_arg): Likewise.
(fr30_function_arg_advance): Likewise.
* config/frv/frv.c (frv_must_pass_in_stack): Take a function_arg_info
instead of a mode and a type.
* config/gcn/gcn.c (num_arg_regs): Likewise.
(gcn_function_arg, gcn_function_arg_advance): Update calls to
num_arg_regs and targetm.calls.must_pass_in_stack.
(gcn_arg_partial_bytes): Likewise.
* config/i386/i386.c (ix86_must_pass_in_stack): Take a
function_arg_info instead of a mode and a type.
(classify_argument): Update call accordingly.
* config/nds32/nds32.c (nds32_must_pass_in_stack): Take a
function_arg_info instead of a mode and a type.
* config/rs6000/rs6000-internal.h (rs6000_must_pass_in_stack):
Likewise.
* config/rs6000/rs6000-call.c (rs6000_must_pass_in_stack): Likewise.
(rs6000_parm_needs_stack): Update call accordingly.
(setup_incoming_varargs): Likewise.

From-SVN: r274703

26 files changed:
gcc/ChangeLog
gcc/calls.c
gcc/calls.h
gcc/config/alpha/alpha.c
gcc/config/arm/arm.c
gcc/config/cr16/cr16.c
gcc/config/cris/cris.c
gcc/config/fr30/fr30.c
gcc/config/frv/frv.c
gcc/config/gcn/gcn.c
gcc/config/i386/i386.c
gcc/config/iq2000/iq2000.c
gcc/config/lm32/lm32.c
gcc/config/mcore/mcore.c
gcc/config/mips/mips.c
gcc/config/mmix/mmix.c
gcc/config/nds32/nds32.c
gcc/config/rs6000/rs6000-call.c
gcc/config/rs6000/rs6000-internal.h
gcc/config/sh/sh.c
gcc/config/stormy16/stormy16.c
gcc/config/xtensa/xtensa.c
gcc/doc/tm.texi
gcc/function.c
gcc/target.def
gcc/targhooks.c

index e57cc99779bef93d55f482693bd67923f74a18eb..b5a198c95dc3d67d1dab5aaad2ab00d6942b841c 100644 (file)
@@ -1,3 +1,58 @@
+2019-08-20  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * target.def (must_pass_in_stack): Take a function_arg_info instead
+       of a mode and a type.
+       * doc/tm.texi: Regenerate.
+       * calls.h (must_pass_in_stack_var_size): Take a function_arg_info
+       instead of a mode and a type.
+       (must_pass_in_stack_var_size_or_pad): Likewise.
+       * calls.c (must_pass_in_stack_var_size): Likewise.
+       (must_pass_in_stack_var_size_or_pad): Likewise.
+       (initialize_argument_information): Update call to
+       targetm.calls.must_pass_in_stack.
+       (must_pass_va_arg_on_stack): Likewise.
+       * function.c (assign_parm_find_entry_rtl): Likewise.
+       * targhooks.c (hook_pass_by_reference_must_pass_in_stack): Likewise.
+       * config/alpha/alpha.c (alpha_function_arg): Likewise.
+       (alpha_function_arg_advance): Likewise.
+       * config/cr16/cr16.c (cr16_function_arg): Likewise.
+       (cr16_function_arg_advance): Likewise.
+       * config/cris/cris.c (cris_pass_by_reference): Likewise.
+       (cris_arg_partial_bytes): Likewise.
+       * config/iq2000/iq2000.c (iq2000_pass_by_reference): Likewise.
+       * config/lm32/lm32.c (lm32_function_arg): Likewise.
+       * config/mcore/mcore.c (mcore_num_arg_regs): Likewise.
+       (mcore_function_arg, mcore_arg_partial_bytes): Likewise.
+       * config/mips/mips.c (mips_pass_by_reference): Likewise.
+       * config/mmix/mmix.c (mmix_function_arg_advance): Likewise.
+       (mmix_function_arg_1, mmix_pass_by_reference): Likewise.
+       * config/sh/sh.c (sh_pass_by_reference): Likewise.
+       * config/stormy16/stormy16.c (xstormy16_function_arg): Likewise.
+       * config/xtensa/xtensa.c (xtensa_function_arg_advance): Likewise.
+       * config/arm/arm.c (arm_must_pass_in_stack): Take a function_arg_info
+       instead of a mode and a type.
+       * config/fr30/fr30.c (fr30_must_pass_in_stack): Likewise.
+       (fr30_num_arg_regs): Likewise.
+       (fr30_setup_incoming_varargs): Update calls accordingly.
+       (fr30_arg_partial_bytes, fr30_function_arg): Likewise.
+       (fr30_function_arg_advance): Likewise.
+       * config/frv/frv.c (frv_must_pass_in_stack): Take a function_arg_info
+       instead of a mode and a type.
+       * config/gcn/gcn.c (num_arg_regs): Likewise.
+       (gcn_function_arg, gcn_function_arg_advance): Update calls to
+       num_arg_regs and targetm.calls.must_pass_in_stack.
+       (gcn_arg_partial_bytes): Likewise.
+       * config/i386/i386.c (ix86_must_pass_in_stack): Take a
+       function_arg_info instead of a mode and a type.
+       (classify_argument): Update call accordingly.
+       * config/nds32/nds32.c (nds32_must_pass_in_stack): Take a
+       function_arg_info instead of a mode and a type.
+       * config/rs6000/rs6000-internal.h (rs6000_must_pass_in_stack):
+       Likewise.
+       * config/rs6000/rs6000-call.c (rs6000_must_pass_in_stack): Likewise.
+       (rs6000_parm_needs_stack): Update call accordingly.
+       (setup_incoming_varargs): Likewise.
+
 2019-08-20  Richard Sandiford  <richard.sandiford@arm.com>
 
        * target.def (callee_copies): Take a function_arg_info instead
index 6be8acd38e346df8d154a4278892e53a66288551..1f691e84dfeba89ca54a51363440b53814ea862e 100644 (file)
@@ -2139,7 +2139,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
       if (args[i].reg)
        args[i].partial = targetm.calls.arg_partial_bytes (args_so_far, arg);
 
-      args[i].pass_on_stack = targetm.calls.must_pass_in_stack (mode, type);
+      args[i].pass_on_stack = targetm.calls.must_pass_in_stack (arg);
 
       /* If FUNCTION_ARG returned a (parallel [(expr_list (nil) ...) ...]),
         it means that we are to pass this arg in the register(s) designated
@@ -5839,22 +5839,21 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags,
   return sibcall_failure;
 }
 
-/* Nonzero if we do not know how to pass TYPE solely in registers.  */
+/* Nonzero if we do not know how to pass ARG solely in registers.  */
 
 bool
-must_pass_in_stack_var_size (machine_mode mode ATTRIBUTE_UNUSED,
-                            const_tree type)
+must_pass_in_stack_var_size (const function_arg_info &arg)
 {
-  if (!type)
+  if (!arg.type)
     return false;
 
   /* If the type has variable size...  */
-  if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+  if (TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST)
     return true;
 
   /* If the type is marked as addressable (it is required
      to be constructed into the stack)...  */
-  if (TREE_ADDRESSABLE (type))
+  if (TREE_ADDRESSABLE (arg.type))
     return true;
 
   return false;
@@ -5865,28 +5864,28 @@ must_pass_in_stack_var_size (machine_mode mode ATTRIBUTE_UNUSED,
 /* ??? Should be able to merge these two by examining BLOCK_REG_PADDING.  */
 
 bool
-must_pass_in_stack_var_size_or_pad (machine_mode mode, const_tree type)
+must_pass_in_stack_var_size_or_pad (const function_arg_info &arg)
 {
-  if (!type)
+  if (!arg.type)
     return false;
 
   /* If the type has variable size...  */
-  if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+  if (TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST)
     return true;
 
   /* If the type is marked as addressable (it is required
      to be constructed into the stack)...  */
-  if (TREE_ADDRESSABLE (type))
+  if (TREE_ADDRESSABLE (arg.type))
     return true;
 
-  if (TYPE_EMPTY_P (type))
+  if (TYPE_EMPTY_P (arg.type))
     return false;
 
   /* If the padding and mode of the type is such that a copy into
      a register would put it into the wrong part of the register.  */
-  if (mode == BLKmode
-      && int_size_in_bytes (type) % (PARM_BOUNDARY / BITS_PER_UNIT)
-      && (targetm.calls.function_arg_padding (mode, type)
+  if (arg.mode == BLKmode
+      && int_size_in_bytes (arg.type) % (PARM_BOUNDARY / BITS_PER_UNIT)
+      && (targetm.calls.function_arg_padding (arg.mode, arg.type)
          == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)))
     return true;
 
@@ -5899,7 +5898,8 @@ must_pass_in_stack_var_size_or_pad (machine_mode mode, const_tree type)
 bool
 must_pass_va_arg_in_stack (tree type)
 {
-  return targetm.calls.must_pass_in_stack (TYPE_MODE (type), type);
+  function_arg_info arg (type, /*named=*/false);
+  return targetm.calls.must_pass_in_stack (arg);
 }
 
 /* Tell the garbage collector about GTY markers in this source file.  */
index 709a0769b768a07fd2eb97a8fb75a38f1e779f75..5e8c576424abb2797830f248d9eab0805c6b168b 100644 (file)
@@ -108,8 +108,8 @@ extern int setjmp_call_p (const_tree);
 extern bool gimple_maybe_alloca_call_p (const gimple *);
 extern bool gimple_alloca_call_p (const gimple *);
 extern bool alloca_call_p (const_tree);
-extern bool must_pass_in_stack_var_size (machine_mode, const_tree);
-extern bool must_pass_in_stack_var_size_or_pad (machine_mode, const_tree);
+extern bool must_pass_in_stack_var_size (const function_arg_info &);
+extern bool must_pass_in_stack_var_size_or_pad (const function_arg_info &);
 extern bool must_pass_va_arg_in_stack (tree);
 extern rtx prepare_call_address (tree, rtx, rtx, rtx *, int, int);
 extern bool shift_return_value (machine_mode, bool, rtx);
index 477c24e229832a016a8fa0413aeb35330699a9d5..fd6b5a82274068945ebcece3c18061056e8a1496 100644 (file)
@@ -5585,7 +5585,7 @@ alpha_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
 
       num_args = cum->num_args;
       if (num_args >= 6
-         || targetm.calls.must_pass_in_stack (arg.mode, arg.type))
+         || targetm.calls.must_pass_in_stack (arg))
        return NULL_RTX;
     }
 #elif TARGET_ABI_OSF
@@ -5596,7 +5596,7 @@ alpha_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
 
       if (arg.end_marker_p ())
        basereg = 16;
-      else if (targetm.calls.must_pass_in_stack (arg.mode, arg.type))
+      else if (targetm.calls.must_pass_in_stack (arg))
        return NULL_RTX;
     }
 #else
@@ -5613,7 +5613,7 @@ alpha_function_arg_advance (cumulative_args_t cum_v,
                            const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
-  bool onstack = targetm.calls.must_pass_in_stack (arg.mode, arg.type);
+  bool onstack = targetm.calls.must_pass_in_stack (arg);
   int increment = onstack ? 6 : ALPHA_ARG_SIZE (arg.mode, arg.type);
 
 #if TARGET_ABI_OSF
index 74e7c54524e66a30fe4d1df9f547787f37886e40..3343a7e4639248046fe3b4f8fed2a45d2d3f8388 100644 (file)
@@ -219,7 +219,7 @@ static bool arm_promote_prototypes (const_tree);
 static bool arm_default_short_enums (void);
 static bool arm_align_anon_bitfield (void);
 static bool arm_return_in_msb (const_tree);
-static bool arm_must_pass_in_stack (machine_mode, const_tree);
+static bool arm_must_pass_in_stack (const function_arg_info &);
 static bool arm_return_in_memory (const_tree, const_tree);
 #if ARM_UNWIND_INFO
 static void arm_unwind_emit (FILE *, rtx_insn *);
@@ -15382,12 +15382,12 @@ arm_reload_out_hi (rtx *operands)
    (padded to the size of a word) should be passed in a register.  */
 
 static bool
-arm_must_pass_in_stack (machine_mode mode, const_tree type)
+arm_must_pass_in_stack (const function_arg_info &arg)
 {
   if (TARGET_AAPCS_BASED)
-    return must_pass_in_stack_var_size (mode, type);
+    return must_pass_in_stack_var_size (arg);
   else
-    return must_pass_in_stack_var_size_or_pad (mode, type);
+    return must_pass_in_stack_var_size_or_pad (arg);
 }
 
 
index dc4cb9184826232fa43235e788e49742030a82dd..c95d5d19a9c63692cc3fe4ecd4524fab76907f8f 100644 (file)
@@ -606,7 +606,7 @@ cr16_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
   if (arg.end_marker_p ())
     return NULL_RTX;
 
-  if (targetm.calls.must_pass_in_stack (arg.mode, arg.type) || (cum->ints < 0))
+  if (targetm.calls.must_pass_in_stack (arg) || (cum->ints < 0))
     return NULL_RTX;
 
   if (arg.mode == BLKmode)
@@ -672,7 +672,7 @@ cr16_function_arg_advance (cumulative_args_t cum_v,
   if (!cum->last_parm_in_reg)
     return;
 
-  if (targetm.calls.must_pass_in_stack (arg.mode, arg.type) || (cum->ints < 0))
+  if (targetm.calls.must_pass_in_stack (arg) || (cum->ints < 0))
     return;
 
   if ((arg.mode == SImode) || (arg.mode == HImode)
index f238853ba3a3d9da87de87d585d9b9192ae541ed..fff641e9f84ef1cac3a703ead5b06b3031362f30 100644 (file)
@@ -4046,7 +4046,7 @@ cris_setup_incoming_varargs (cumulative_args_t ca_v,
 static bool
 cris_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
 {
-  return (targetm.calls.must_pass_in_stack (arg.mode, arg.type)
+  return (targetm.calls.must_pass_in_stack (arg)
          || CRIS_FUNCTION_ARG_SIZE (arg.mode, arg.type) > 8);
 }
 
@@ -4111,7 +4111,7 @@ static int
 cris_arg_partial_bytes (cumulative_args_t ca, const function_arg_info &arg)
 {
   if (get_cumulative_args (ca)->regs == CRIS_MAX_ARGS_IN_REGS - 1
-      && !targetm.calls.must_pass_in_stack (arg.mode, arg.type)
+      && !targetm.calls.must_pass_in_stack (arg)
       && CRIS_FUNCTION_ARG_SIZE (arg.mode, arg.type) > 4
       && CRIS_FUNCTION_ARG_SIZE (arg.mode, arg.type) <= 8)
     return UNITS_PER_WORD;
index 7f1eae17d0043ca10562b826e07524533b4b1342..675198fe5de2b0b376fa3deb2e6b4da12e59230e 100644 (file)
@@ -116,7 +116,7 @@ static struct fr30_frame_info       zero_frame_info;
 static void fr30_setup_incoming_varargs (cumulative_args_t,
                                         const function_arg_info &,
                                         int *, int);
-static bool fr30_must_pass_in_stack (machine_mode, const_tree);
+static bool fr30_must_pass_in_stack (const function_arg_info &);
 static int fr30_arg_partial_bytes (cumulative_args_t,
                                   const function_arg_info &);
 static rtx fr30_function_arg (cumulative_args_t, const function_arg_info &);
@@ -129,7 +129,7 @@ static bool fr30_function_value_regno_p (const unsigned int);
 static bool fr30_can_eliminate (const int, const int);
 static void fr30_asm_trampoline_template (FILE *);
 static void fr30_trampoline_init (rtx, tree, rtx);
-static int fr30_num_arg_regs (machine_mode, const_tree);
+static int fr30_num_arg_regs (const function_arg_info &);
 
 #define FRAME_POINTER_MASK     (1 << (FRAME_POINTER_REGNUM))
 #define RETURN_POINTER_MASK    (1 << (RETURN_POINTER_REGNUM))
@@ -480,7 +480,7 @@ fr30_setup_incoming_varargs (cumulative_args_t arg_regs_used_so_far_v,
     /* If TARGET_STRICT_ARGUMENT_NAMING returns true, then the last named
        arg must not be treated as an anonymous arg.  */
     /* ??? This is a pointer increment, which makes no sense.  */
-    arg_regs_used_so_far += fr30_num_arg_regs (arg.mode, arg.type);
+    arg_regs_used_so_far += fr30_num_arg_regs (arg);
 
   size = FR30_NUM_ARG_REGS - (* arg_regs_used_so_far);
 
@@ -743,30 +743,20 @@ fr30_function_value_regno_p (const unsigned int regno)
    in registers.  */
 
 static bool
-fr30_must_pass_in_stack (machine_mode mode, const_tree type)
+fr30_must_pass_in_stack (const function_arg_info &arg)
 {
-  if (mode == BLKmode)
-    return true;
-  if (type == NULL)
-    return false;
-  return AGGREGATE_TYPE_P (type);
+  return arg.mode == BLKmode || arg.aggregate_type_p ();
 }
 
-/* Compute the number of word sized registers needed to hold a
-   function argument of mode INT_MODE and tree type TYPE.  */
+/* Compute the number of word sized registers needed to hold function
+   argument ARG.  */
 static int
-fr30_num_arg_regs (machine_mode mode, const_tree type)
+fr30_num_arg_regs (const function_arg_info &arg)
 {
-  int size;
-
-  if (targetm.calls.must_pass_in_stack (mode, type))
+  if (targetm.calls.must_pass_in_stack (arg))
     return 0;
 
-  if (type && mode == BLKmode)
-    size = int_size_in_bytes (type);
-  else
-    size = GET_MODE_SIZE (mode);
-
+  int size = arg.promoted_size_in_bytes ();
   return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
 }
 
@@ -792,7 +782,7 @@ fr30_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
      are needed because the parameter must be passed on the stack)
      then return zero, as this parameter does not require partial
      register, partial stack stack space.  */
-  if (*cum + fr30_num_arg_regs (arg.mode, arg.type) <= FR30_NUM_ARG_REGS)
+  if (*cum + fr30_num_arg_regs (arg) <= FR30_NUM_ARG_REGS)
     return 0;
   
   return (FR30_NUM_ARG_REGS - *cum) * UNITS_PER_WORD;
@@ -804,7 +794,7 @@ fr30_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
   if (!arg.named
-      || fr30_must_pass_in_stack (arg.mode, arg.type)
+      || fr30_must_pass_in_stack (arg)
       || *cum >= FR30_NUM_ARG_REGS)
     return NULL_RTX;
   else
@@ -817,7 +807,7 @@ fr30_function_arg_advance (cumulative_args_t cum,
                           const function_arg_info &arg)
 {
   if (arg.named)
-    *get_cumulative_args (cum) += fr30_num_arg_regs (arg.mode, arg.type);
+    *get_cumulative_args (cum) += fr30_num_arg_regs (arg);
 }
 
 /*}}}*/
index 5d319c0bfafd583b9137062ddf284c236a882778..c1b3c9e6d600b8ab1b06c5045cb975177cf5360a 100644 (file)
@@ -379,7 +379,7 @@ static void frv_output_const_unspec         (FILE *,
                                                 const struct frv_unspec *);
 static bool frv_function_ok_for_sibcall                (tree, tree);
 static rtx frv_struct_value_rtx                        (tree, int);
-static bool frv_must_pass_in_stack (machine_mode mode, const_tree type);
+static bool frv_must_pass_in_stack (const function_arg_info &);
 static int frv_arg_partial_bytes (cumulative_args_t,
                                  const function_arg_info &);
 static rtx frv_function_arg (cumulative_args_t, const function_arg_info &);
@@ -3077,13 +3077,9 @@ frv_init_cumulative_args (CUMULATIVE_ARGS *cum,
    in registers.  */
 
 static bool
-frv_must_pass_in_stack (machine_mode mode, const_tree type)
+frv_must_pass_in_stack (const function_arg_info &arg)
 {
-  if (mode == BLKmode)
-    return true;
-  if (type == NULL)
-    return false;
-  return AGGREGATE_TYPE_P (type);
+  return arg.mode == BLKmode || arg.aggregate_type_p ();
 }
 
 /* If defined, a C expression that gives the alignment boundary, in bits, of an
index c919d31f69699244062d214bc1c1273fc86e0073..8645eccf9547a7c3b453922e34fcce91c9bc8fa0 100644 (file)
@@ -2200,22 +2200,16 @@ gcn_function_value_regno_p (const unsigned int n)
   return n == RETURN_VALUE_REG;
 }
 
-/* Calculate the number of registers required to hold function argument
-   of MODE and TYPE.  */
+/* Calculate the number of registers required to hold function argument
+   ARG.  */
 
 static int
-num_arg_regs (machine_mode mode, const_tree type)
+num_arg_regs (const function_arg_info &arg)
 {
-  int size;
-
-  if (targetm.calls.must_pass_in_stack (mode, type))
+  if (targetm.calls.must_pass_in_stack (arg))
     return 0;
 
-  if (type && mode == BLKmode)
-    size = int_size_in_bytes (type);
-  else
-    size = GET_MODE_SIZE (mode);
-
+  int size = arg.promoted_size_in_bytes ();
   return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
 }
 
@@ -2263,11 +2257,11 @@ gcn_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
       if (!arg.named || arg.end_marker_p ())
        return 0;
 
-      if (targetm.calls.must_pass_in_stack (arg.mode, arg.type))
+      if (targetm.calls.must_pass_in_stack (arg))
        return 0;
 
       int reg_num = FIRST_PARM_REG + cum->num;
-      int num_regs = num_arg_regs (arg.mode, arg.type);
+      int num_regs = num_arg_regs (arg);
       if (num_regs > 0)
        while (reg_num % num_regs != 0)
          reg_num++;
@@ -2323,7 +2317,7 @@ gcn_function_arg_advance (cumulative_args_t cum_v,
       if (!arg.named)
        return;
 
-      int num_regs = num_arg_regs (arg.mode, arg.type);
+      int num_regs = num_arg_regs (arg);
       if (num_regs > 0)
        while ((FIRST_PARM_REG + cum->num) % num_regs != 0)
          cum->num++;
@@ -2355,14 +2349,14 @@ gcn_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
   if (!arg.named)
     return 0;
 
-  if (targetm.calls.must_pass_in_stack (arg.mode, arg.type))
+  if (targetm.calls.must_pass_in_stack (arg))
     return 0;
 
   if (cum->num >= NUM_PARM_REGS)
     return 0;
 
   /* If the argument fits entirely in registers, return 0.  */
-  if (cum->num + num_arg_regs (arg.mode, arg.type) <= NUM_PARM_REGS)
+  if (cum->num + num_arg_regs (arg) <= NUM_PARM_REGS)
     return 0;
 
   return (NUM_PARM_REGS - cum->num) * UNITS_PER_WORD;
index f036d56731caaf422c531c50ea77e3b029dd9e7c..49ab50ea41bfc008e7282915c7a248584dc0711d 100644 (file)
@@ -1455,19 +1455,19 @@ ix86_function_arg_regno_p (int regno)
   return false;
 }
 
-/* Return if we do not know how to pass TYPE solely in registers.  */
+/* Return if we do not know how to pass ARG solely in registers.  */
 
 static bool
-ix86_must_pass_in_stack (machine_mode mode, const_tree type)
+ix86_must_pass_in_stack (const function_arg_info &arg)
 {
-  if (must_pass_in_stack_var_size_or_pad (mode, type))
+  if (must_pass_in_stack_var_size_or_pad (arg))
     return true;
 
   /* For 32-bit, we want TImode aggregates to go on the stack.  But watch out!
      The layout_type routine is crafty and tries to trick us into passing
      currently unsupported vector types on the stack by using TImode.  */
-  return (!TARGET_64BIT && mode == TImode
-         && type && TREE_CODE (type) != VECTOR_TYPE);
+  return (!TARGET_64BIT && arg.mode == TImode
+         && arg.type && TREE_CODE (arg.type) != VECTOR_TYPE);
 }
 
 /* It returns the size, in bytes, of the area reserved for arguments passed
@@ -2062,9 +2062,13 @@ classify_argument (machine_mode mode, const_tree type,
   if (bytes < 0)
     return 0;
 
-  if (mode != VOIDmode
-      && targetm.calls.must_pass_in_stack (mode, type))
-    return 0;
+  if (mode != VOIDmode)
+    {
+      /* The value of "named" doesn't matter.  */
+      function_arg_info arg (const_cast<tree> (type), mode, /*named=*/true);
+      if (targetm.calls.must_pass_in_stack (arg))
+       return 0;
+    }
 
   if (type && AGGREGATE_TYPE_P (type))
     {
index 80c63812878e5025115d7056f4222f1ba5aa2b8b..59c5132bc061d74774582c0bfd63fe0027520aa3 100644 (file)
@@ -2300,7 +2300,7 @@ iq2000_pass_by_reference (cumulative_args_t cum_v,
   /* We must pass by reference if we would be both passing in registers
      and the stack.  This is because any subsequent partial arg would be
      handled incorrectly in this case.  */
-  if (cum && targetm.calls.must_pass_in_stack (arg.mode, arg.type))
+  if (cum && targetm.calls.must_pass_in_stack (arg))
      {
        /* Don't pass the actual CUM to FUNCTION_ARG, because we would
          get double copies of any offsets generated for small structs
index a393dffadecef4b69e110ff54b64e85af6a5a438..267ff274815cb0eadfa13222342496ca12ec40f9 100644 (file)
@@ -629,7 +629,7 @@ lm32_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
     /* Compute operand 2 of the call insn.  */
     return GEN_INT (0);
 
-  if (targetm.calls.must_pass_in_stack (arg.mode, arg.type))
+  if (targetm.calls.must_pass_in_stack (arg))
     return NULL_RTX;
 
   if (!arg.named
index 9feac9566d22c602235413ab1919ced7feb3647a..b259da506db2e91ad478ea8c1e4ca88a8a3716fe 100644 (file)
@@ -2713,7 +2713,8 @@ mcore_num_arg_regs (machine_mode mode, const_tree type)
 {
   int size;
 
-  if (targetm.calls.must_pass_in_stack (mode, type))
+  function_arg_info arg (const_cast<tree> (type), mode, /*named=*/true);
+  if (targetm.calls.must_pass_in_stack (arg))
     return 0;
 
   if (type && mode == BLKmode)
@@ -2803,7 +2804,7 @@ mcore_function_arg (cumulative_args_t cum, const function_arg_info &arg)
   if (!arg.named || arg.end_marker_p ())
     return 0;
 
-  if (targetm.calls.must_pass_in_stack (arg.mode, arg.type))
+  if (targetm.calls.must_pass_in_stack (arg))
     return 0;
 
   arg_reg = ROUND_REG (*get_cumulative_args (cum), arg.mode);
@@ -2848,7 +2849,7 @@ mcore_arg_partial_bytes (cumulative_args_t cum, const function_arg_info &arg)
   if (!arg.named)
     return 0;
 
-  if (targetm.calls.must_pass_in_stack (arg.mode, arg.type))
+  if (targetm.calls.must_pass_in_stack (arg))
     return 0;
       
   /* REG is not the *hardware* register number of the register that holds
index 37ebde577b7b9886332fc7c06b82e339bcf1916a..c24dc710b132914a37348cc666836f12a524596d 100644 (file)
@@ -6252,7 +6252,7 @@ mips_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
   else
     {
       /* If we have a variable-sized parameter, we have no choice.  */
-      return targetm.calls.must_pass_in_stack (arg.mode, arg.type);
+      return targetm.calls.must_pass_in_stack (arg);
     }
 }
 
index 7c12e74a73dc0edcd13f2a162c9353eae181d343..8ebb829506cfa78cb0f6e4f25725a02ff4a85973 100644 (file)
@@ -621,7 +621,7 @@ mmix_function_arg_advance (cumulative_args_t argsp_v,
   CUMULATIVE_ARGS *argsp = get_cumulative_args (argsp_v);
   int arg_size = MMIX_FUNCTION_ARG_SIZE (arg.mode, arg.type);
 
-  argsp->regs = ((targetm.calls.must_pass_in_stack (arg.mode, arg.type)
+  argsp->regs = ((targetm.calls.must_pass_in_stack (arg)
                  || (arg_size > 8
                      && !TARGET_LIBFUNC
                      && !argsp->lib))
@@ -647,7 +647,7 @@ mmix_function_arg_1 (const cumulative_args_t argsp_v,
       : NULL_RTX;
 
   return (argsp->regs < MMIX_MAX_ARGS_IN_REGS
-         && !targetm.calls.must_pass_in_stack (arg.mode, arg.type)
+         && !targetm.calls.must_pass_in_stack (arg)
          && (GET_MODE_BITSIZE (arg.mode) <= 64
              || argsp->lib
              || TARGET_LIBFUNC))
@@ -686,7 +686,7 @@ mmix_pass_by_reference (cumulative_args_t argsp_v,
 
   /* FIXME: Check: I'm not sure the must_pass_in_stack check is
      necessary.  */
-  if (targetm.calls.must_pass_in_stack (arg.mode, arg.type))
+  if (targetm.calls.must_pass_in_stack (arg))
     return true;
 
   if (MMIX_FUNCTION_ARG_SIZE (arg.mode, arg.type) > 8
index 3fd4cc8adebc1e23670cb35cd91bc12813d61a1b..3caae14e0e123fef37a4f71218cf881a85af07d7 100644 (file)
@@ -1951,16 +1951,16 @@ nds32_function_arg (cumulative_args_t ca, const function_arg_info &arg)
 }
 
 static bool
-nds32_must_pass_in_stack (machine_mode mode, const_tree type)
+nds32_must_pass_in_stack (const function_arg_info &arg)
 {
   /* Return true if a type must be passed in memory.
      If it is NOT using hard float abi, small aggregates can be
      passed in a register even we are calling a variadic function.
      So there is no need to take padding into consideration.  */
   if (TARGET_HARD_FLOAT)
-    return must_pass_in_stack_var_size_or_pad (mode, type);
+    return must_pass_in_stack_var_size_or_pad (arg);
   else
-    return must_pass_in_stack_var_size (mode, type);
+    return must_pass_in_stack_var_size (arg);
 }
 
 static int
index 548a7156114c0fbfa5ba944731687bff38187e3e..fb87bb2f2cbe18b93678547eee9274c2f03011ad 100644 (file)
@@ -816,12 +816,12 @@ rs6000_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
 /* Return true if TYPE must be passed on the stack and not in registers.  */
 
 bool
-rs6000_must_pass_in_stack (machine_mode mode, const_tree type)
+rs6000_must_pass_in_stack (const function_arg_info &arg)
 {
   if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2 || TARGET_64BIT)
-    return must_pass_in_stack_var_size (mode, type);
+    return must_pass_in_stack_var_size (arg);
   else
-    return must_pass_in_stack_var_size_or_pad (mode, type);
+    return must_pass_in_stack_var_size_or_pad (arg);
 }
 
 static inline bool
@@ -2202,11 +2202,11 @@ rs6000_parm_needs_stack (cumulative_args_t args_so_far, tree type)
   mode = promote_mode (type, TYPE_MODE (type), &unsignedp);
 
   /* If we must pass in stack, we need a stack.  */
-  if (rs6000_must_pass_in_stack (mode, type))
+  function_arg_info arg (type, mode, /*named=*/true);
+  if (rs6000_must_pass_in_stack (arg))
     return true;
 
   /* If there is no incoming register, we need a stack.  */
-  function_arg_info arg (type, mode, /*named=*/true);
   entry_parm = rs6000_function_arg (args_so_far, arg);
   if (entry_parm == NULL)
     return true;
@@ -2457,7 +2457,7 @@ setup_incoming_varargs (cumulative_args_t cum,
       first_reg_offset = next_cum.words;
       save_area = crtl->args.internal_arg_pointer;
 
-      if (targetm.calls.must_pass_in_stack (arg.mode, arg.type))
+      if (targetm.calls.must_pass_in_stack (arg))
        first_reg_offset += rs6000_arg_size (TYPE_MODE (arg.type), arg.type);
     }
 
index cdd9327b4ef501bce0c7e5524451467cec874893..baccfb3f8872a141abc8764841b08375fb721906 100644 (file)
@@ -156,7 +156,7 @@ extern void setup_incoming_varargs (cumulative_args_t,
                                    const function_arg_info &, int *, int);
 extern unsigned int rs6000_function_arg_boundary (machine_mode mode,
                                                  const_tree type);
-extern bool rs6000_must_pass_in_stack (machine_mode mode, const_tree type);
+extern bool rs6000_must_pass_in_stack (const function_arg_info &);
 extern int rs6000_arg_partial_bytes (cumulative_args_t,
                                     const function_arg_info &);
 extern void rs6000_function_arg_advance (cumulative_args_t,
index da912ca9abdcb296744d08104df4c1e336d7b56f..3b22d960b619a5d1a4da59eac95d13e859d2b861 100644 (file)
@@ -7901,7 +7901,7 @@ sh_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
-  if (targetm.calls.must_pass_in_stack (arg.mode, arg.type))
+  if (targetm.calls.must_pass_in_stack (arg))
     return true;
 
   /* ??? std_gimplify_va_arg_expr passes NULL for cum.  That function
index 7ccfbda7aad8e55a7b5ea630db2ccb9ce12ecc03..23f546a0203007acab5910ca3c1416853c951573 100644 (file)
@@ -1239,7 +1239,7 @@ xstormy16_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
 
   if (arg.end_marker_p ())
     return const0_rtx;
-  if (targetm.calls.must_pass_in_stack (arg.mode, arg.type)
+  if (targetm.calls.must_pass_in_stack (arg)
       || (*cum + XSTORMY16_WORD_SIZE (arg.type, arg.mode)
          > NUM_ARGUMENT_REGISTERS))
     return NULL_RTX;
index a277633e6efefe310f6d50057aa0616c7237735c..98f30c5cc21c91add2b246cfae1f850a7b3bda7c 100644 (file)
@@ -2118,7 +2118,7 @@ xtensa_function_arg_advance (cumulative_args_t cum,
           / UNITS_PER_WORD);
 
   if (*arg_words < max
-      && (targetm.calls.must_pass_in_stack (arg.mode, arg.type)
+      && (targetm.calls.must_pass_in_stack (arg)
          || *arg_words + words > max))
     *arg_words = max;
 
index 99dbfb8d0fb26942eab74ab8c67c7616f7dec477..55069088b52e8d6a5e123e9bdcee5c82334ae0a0 100644 (file)
@@ -4012,8 +4012,8 @@ defined, the argument will be computed in the stack and then loaded into
 a register.
 @end deftypefn
 
-@deftypefn {Target Hook} bool TARGET_MUST_PASS_IN_STACK (machine_mode @var{mode}, const_tree @var{type})
-This target hook should return @code{true} if we should not pass @var{type}
+@deftypefn {Target Hook} bool TARGET_MUST_PASS_IN_STACK (const function_arg_info @var{&arg})
+This target hook should return @code{true} if we should not pass @var{arg}
 solely in registers.  The file @file{expr.h} defines a
 definition that is usually appropriate, refer to @file{expr.h} for additional
 documentation.
index 1d7687aebce4f588881790c84e46e8bab29028ac..46ed75c77be92af937e672dd29a85f8d1b704106 100644 (file)
@@ -2552,8 +2552,7 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all,
 
   /* If this parameter was passed both in registers and in the stack, use
      the copy on the stack.  */
-  if (targetm.calls.must_pass_in_stack (data->promoted_mode,
-                                       data->passed_type))
+  if (targetm.calls.must_pass_in_stack (arg))
     entry_parm = 0;
 
   if (entry_parm)
index 4f8acfd2276a097390261fa76806dc08768b6587..b2332d8215c25fc0c159b0a9cc1f08966105a363 100644 (file)
@@ -4630,11 +4630,11 @@ false.",
    Need audit to verify that this is the case.  */
 DEFHOOK
 (must_pass_in_stack,
- "This target hook should return @code{true} if we should not pass @var{type}\n\
+ "This target hook should return @code{true} if we should not pass @var{arg}\n\
 solely in registers.  The file @file{expr.h} defines a\n\
 definition that is usually appropriate, refer to @file{expr.h} for additional\n\
 documentation.",
- bool, (machine_mode mode, const_tree type),
+ bool, (const function_arg_info &arg),
  must_pass_in_stack_var_size_or_pad)
 
 /* Return true if type TYPE, mode MODE, which is passed by reference,
index 5a0ed2f72de5086ad67d1659f114bed1836510c4..1d12ec547047df1d71b57dcb27dcd467d7989cc6 100644 (file)
@@ -323,7 +323,7 @@ bool
 hook_pass_by_reference_must_pass_in_stack (cumulative_args_t,
                                           const function_arg_info &arg)
 {
-  return targetm.calls.must_pass_in_stack (arg.mode, arg.type);
+  return targetm.calls.must_pass_in_stack (arg);
 }
 
 /* Return true if a parameter follows callee copies conventions.  This