Add a apply_pass_by_reference_rules helper
authorRichard Sandiford <richard.sandiford@arm.com>
Tue, 20 Aug 2019 08:53:47 +0000 (08:53 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 20 Aug 2019 08:53:47 +0000 (08:53 +0000)
This patch adds a helper routine that applies pass-by-reference
semantics to an existing function_arg_info.

The c6x part means that c6x_function_arg and c6x_function_arg_advance
see the same "named" value as pass_by_reference did, rather than
pass_by_reference seeing "true" and the others seeing "false".
This doesn't matter because the c6x port doesn't care about namedness.

The rs6000.c patch removes an assignment to "type", but the only
later code to use it was the patched promote_mode line.

(The reason for patching these places despite the above is that
often target code gets used as a basis for new targets or changes
to existing ones.)

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

gcc/
* calls.h (apply_pass_by_reference_rules): Declare.
* calls.c (apply_pass_by_reference_rules): New function.
* config/c6x/c6x.c (c6x_call_saved_register_used): Use it.
* config/rs6000/rs6000-call.c (rs6000_parm_needs_stack): Likewise.
* config/s390/s390.c (s390_call_saved_register_used): Likewise.
* function.c (assign_parm_find_data_types): Likewise.
* var-tracking.c (prepare_call_arguments): Likewise.

From-SVN: r274704

gcc/ChangeLog
gcc/calls.c
gcc/calls.h
gcc/config/c6x/c6x.c
gcc/config/rs6000/rs6000-call.c
gcc/config/s390/s390.c
gcc/function.c
gcc/var-tracking.c

index b5a198c95dc3d67d1dab5aaad2ab00d6942b841c..8a68093c64a5ac78e0909ed1e48c5757e2c307ae 100644 (file)
@@ -1,3 +1,13 @@
+2019-08-20  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * calls.h (apply_pass_by_reference_rules): Declare.
+       * calls.c (apply_pass_by_reference_rules): New function.
+       * config/c6x/c6x.c (c6x_call_saved_register_used): Use it.
+       * config/rs6000/rs6000-call.c (rs6000_parm_needs_stack): Likewise.
+       * config/s390/s390.c (s390_call_saved_register_used): Likewise.
+       * function.c (assign_parm_find_data_types): Likewise.
+       * var-tracking.c (prepare_call_arguments): Likewise.
+
 2019-08-20  Richard Sandiford  <richard.sandiford@arm.com>
 
        * target.def (must_pass_in_stack): Take a function_arg_info instead
index 1f691e84dfeba89ca54a51363440b53814ea862e..6f573f3b26e29c11eff2efe8f05a1cb7406e6e80 100644 (file)
@@ -935,6 +935,22 @@ pass_va_arg_by_reference (tree type)
   return pass_by_reference (NULL, function_arg_info (type, /*named=*/false));
 }
 
+/* Decide whether ARG, which occurs in the state described by CA,
+   should be passed by reference.  Return true if so and update
+   ARG accordingly.  */
+
+bool
+apply_pass_by_reference_rules (CUMULATIVE_ARGS *ca, function_arg_info &arg)
+{
+  if (pass_by_reference (ca, arg))
+    {
+      arg.type = build_pointer_type (arg.type);
+      arg.mode = TYPE_MODE (arg.type);
+      return true;
+    }
+  return false;
+}
+
 /* Return true if ARG, which is passed by reference, should be callee
    copied instead of caller copied.  */
 
index 5e8c576424abb2797830f248d9eab0805c6b168b..01ab3905a3ac0d6a4cf60375b6253212cf40e976 100644 (file)
@@ -118,6 +118,8 @@ extern void fixup_tail_calls (void);
 
 extern bool pass_by_reference (CUMULATIVE_ARGS *, function_arg_info);
 extern bool pass_va_arg_by_reference (tree);
+extern bool apply_pass_by_reference_rules (CUMULATIVE_ARGS *,
+                                          function_arg_info &);
 extern bool reference_callee_copied (CUMULATIVE_ARGS *,
                                     const function_arg_info &);
 extern void maybe_warn_alloc_args_overflow (tree, tree, tree[2], int[2]);
index 37da9a419db0e69b004915c31796d7502393176f..8477d35e1e7d419e9b8bfde74d06b47b4f824910 100644 (file)
@@ -1088,8 +1088,6 @@ c6x_call_saved_register_used (tree call_expr)
   cumulative_args_t cum;
   HARD_REG_SET call_saved_regset;
   tree parameter;
-  machine_mode mode;
-  tree type;
   rtx parm_rtx;
   int i;
 
@@ -1107,19 +1105,9 @@ c6x_call_saved_register_used (tree call_expr)
       if (TREE_CODE (parameter) == ERROR_MARK)
        return true;
 
-      type = TREE_TYPE (parameter);
-      gcc_assert (type);
-
-      mode = TYPE_MODE (type);
-      gcc_assert (mode);
-
-      if (pass_by_reference (&cum_v, function_arg_info (type, /*named=*/true)))
-       {
-         mode = Pmode;
-         type = build_pointer_type (type);
-       }
+      function_arg_info arg (TREE_TYPE (parameter), /*named=*/true);
+      apply_pass_by_reference_rules (&cum_v, arg);
 
-       function_arg_info arg (type, mode, /*named=*/false);
        parm_rtx = c6x_function_arg (cum, arg);
 
        c6x_function_arg_advance (cum, arg);
index fb87bb2f2cbe18b93678547eee9274c2f03011ad..7280a4ed9c86fe6e38baae271d71189a28b6d44b 100644 (file)
@@ -2170,7 +2170,6 @@ rs6000_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
 static bool
 rs6000_parm_needs_stack (cumulative_args_t args_so_far, tree type)
 {
-  machine_mode mode;
   int unsignedp;
   rtx entry_parm;
 
@@ -2193,16 +2192,14 @@ rs6000_parm_needs_stack (cumulative_args_t args_so_far, tree type)
     type = TREE_TYPE (first_field (type));
 
   /* See if this arg was passed by invisible reference.  */
-  if (pass_by_reference (get_cumulative_args (args_so_far),
-                        function_arg_info (type, /*named=*/true)))
-    type = build_pointer_type (type);
+  function_arg_info arg (type, /*named=*/true);
+  apply_pass_by_reference_rules (get_cumulative_args (args_so_far), arg);
 
   /* Find mode as it is passed by the ABI.  */
   unsignedp = TYPE_UNSIGNED (type);
-  mode = promote_mode (type, TYPE_MODE (type), &unsignedp);
+  arg.mode = promote_mode (arg.type, arg.mode, &unsignedp);
 
   /* If we must pass in stack, we need a stack.  */
-  function_arg_info arg (type, mode, /*named=*/true);
   if (rs6000_must_pass_in_stack (arg))
     return true;
 
index 3ad4a185e20d986932b1ca512f4deab1a07f0ffb..fa17d7d5d083437a3b802cc7f6b03e16405d5c5d 100644 (file)
@@ -13309,8 +13309,6 @@ s390_call_saved_register_used (tree call_expr)
   CUMULATIVE_ARGS cum_v;
   cumulative_args_t cum;
   tree parameter;
-  machine_mode mode;
-  tree type;
   rtx parm_rtx;
   int reg, i;
 
@@ -13327,22 +13325,12 @@ s390_call_saved_register_used (tree call_expr)
       if (TREE_CODE (parameter) == ERROR_MARK)
        return true;
 
-      type = TREE_TYPE (parameter);
-      gcc_assert (type);
-
-      mode = TYPE_MODE (type);
-      gcc_assert (mode);
-
       /* We assume that in the target function all parameters are
         named.  This only has an impact on vector argument register
         usage none of which is call-saved.  */
-      if (pass_by_reference (&cum_v, function_arg_info (type, /*named=*/true)))
-       {
-         mode = Pmode;
-         type = build_pointer_type (type);
-       }
+      function_arg_info arg (TREE_TYPE (parameter), /*named=*/true);
+      apply_pass_by_reference_rules (&cum_v, arg);
 
-       function_arg_info arg (type, mode, /*named=*/true);
        parm_rtx = s390_function_arg (cum, arg);
 
        s390_function_arg_advance (cum, arg);
index 46ed75c77be92af937e672dd29a85f8d1b704106..265bcd19f509dcc1bf7b0f26f6b5daf9ca561292 100644 (file)
@@ -2456,11 +2456,11 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm,
   /* See if this arg was passed by invisible reference.  */
   {
     function_arg_info arg (passed_type, passed_mode, data->named_arg);
-    if (pass_by_reference (&all->args_so_far_v, arg))
+    if (apply_pass_by_reference_rules (&all->args_so_far_v, arg))
       {
-       passed_type = nominal_type = build_pointer_type (passed_type);
+       passed_type = nominal_type = arg.type;
        data->passed_pointer = true;
-       passed_mode = nominal_mode = TYPE_MODE (nominal_type);
+       passed_mode = nominal_mode = arg.mode;
       }
   }
 
index 8b1d4476e2281dbce59b89b1a391cb708f5dd9cc..af18528b6d78dc3777b5eb10f51723432752e57e 100644 (file)
@@ -6426,28 +6426,24 @@ prepare_call_arguments (basic_block bb, rtx_insn *insn)
          }
        if (t && t != void_list_node)
          {
-           tree argtype = TREE_VALUE (t);
            rtx reg;
-           function_arg_info orig_arg (argtype, /*named=*/true);
-           if (pass_by_reference (&args_so_far_v, orig_arg))
-             argtype = build_pointer_type (argtype);
-           machine_mode mode = TYPE_MODE (argtype);
-           function_arg_info arg (argtype, /*named=*/true);
+           function_arg_info arg (TREE_VALUE (t), /*named=*/true);
+           apply_pass_by_reference_rules (&args_so_far_v, arg);
            reg = targetm.calls.function_arg (args_so_far, arg);
-           if (TREE_CODE (argtype) == REFERENCE_TYPE
-               && INTEGRAL_TYPE_P (TREE_TYPE (argtype))
+           if (TREE_CODE (arg.type) == REFERENCE_TYPE
+               && INTEGRAL_TYPE_P (TREE_TYPE (arg.type))
                && reg
                && REG_P (reg)
-               && GET_MODE (reg) == mode
-               && (GET_MODE_CLASS (mode) == MODE_INT
-                   || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
+               && GET_MODE (reg) == arg.mode
+               && (GET_MODE_CLASS (arg.mode) == MODE_INT
+                   || GET_MODE_CLASS (arg.mode) == MODE_PARTIAL_INT)
                && REG_P (x)
                && REGNO (x) == REGNO (reg)
-               && GET_MODE (x) == mode
+               && GET_MODE (x) == arg.mode
                && item)
              {
                machine_mode indmode
-                 = TYPE_MODE (TREE_TYPE (argtype));
+                 = TYPE_MODE (TREE_TYPE (arg.type));
                rtx mem = gen_rtx_MEM (indmode, x);
                cselib_val *val = cselib_lookup (mem, indmode, 0, VOIDmode);
                if (val && cselib_preserved_value_p (val))