Add a pass_by_reference flag to function_arg_info
authorRichard Sandiford <richard.sandiford@arm.com>
Tue, 20 Aug 2019 08:54:03 +0000 (08:54 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 20 Aug 2019 08:54:03 +0000 (08:54 +0000)
This patch adds a flag that tells targets whether an argument
has been converted to pass-by-reference form.  This replaces
assign_parm_data_one::passed_pointer in function.c.

The flag is set automatically for places that call
apply_pass_by_reference_rules.  Places that apply
pass-by-reference manually need to set it themselves.

(After previous changes, no targets apply pass-by-reference
manually.  They all go through apply_pass_by_reference_rules.)

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

gcc/
* calls.h (function_arg_info): Add a pass_by_reference field,
defaulting to false.
* calls.c (apply_pass_by_reference_rules): Set pass_by_reference
when applying pass-by-reference semantics.
(initialize_argument_information): Likewise.
(emit_library_call_value_1): Likewise.
* function.c (assign_parm_data_one): Remove passed_pointer field.
(assign_parm_find_data_types): Don't set it.
(assign_parm_find_stack_rtl, assign_parm_adjust_stack_rtl)
(assign_parm_setup_reg, assign_parms, gimplify_parameters): Use
arg.pass_by_reference instead of passed_pointer.

From-SVN: r274707

gcc/ChangeLog
gcc/calls.c
gcc/calls.h
gcc/function.c

index 2a6d8910bfbaecae6ec168a43866f51aa6b52818..dd9838f2678b9fc061ae35123f6cfd4a8b612441 100644 (file)
@@ -1,3 +1,17 @@
+2019-08-20  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * calls.h (function_arg_info): Add a pass_by_reference field,
+       defaulting to false.
+       * calls.c (apply_pass_by_reference_rules): Set pass_by_reference
+       when applying pass-by-reference semantics.
+       (initialize_argument_information): Likewise.
+       (emit_library_call_value_1): Likewise.
+       * function.c (assign_parm_data_one): Remove passed_pointer field.
+       (assign_parm_find_data_types): Don't set it.
+       (assign_parm_find_stack_rtl, assign_parm_adjust_stack_rtl)
+       (assign_parm_setup_reg, assign_parms, gimplify_parameters): Use
+       arg.pass_by_reference instead of passed_pointer.
+
 2019-08-20  Richard Sandiford  <richard.sandiford@arm.com>
 
        * calls.c (emit_library_call_value_1): Merge arg and orig_arg
index 454e5130391e9dbceffe44f0d82f9336f68ed5fa..6eefeec17d9455a0ccd9094f52b02466c17d4eda 100644 (file)
@@ -946,6 +946,7 @@ apply_pass_by_reference_rules (CUMULATIVE_ARGS *ca, function_arg_info &arg)
     {
       arg.type = build_pointer_type (arg.type);
       arg.mode = TYPE_MODE (arg.type);
+      arg.pass_by_reference = true;
       return true;
     }
   return false;
@@ -2125,6 +2126,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
                                              "argument must be passed"
                                              " by copying");
            }
+         arg.pass_by_reference = true;
        }
 
       unsignedp = TYPE_UNSIGNED (type);
@@ -4957,6 +4959,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
                                             call_fusage);
 
          arg.mode = Pmode;
+         arg.pass_by_reference = true;
          val = force_operand (XEXP (slot, 0), NULL_RTX);
        }
 
index 01ab3905a3ac0d6a4cf60375b6253212cf40e976..a782a7d3695acccb5c68c0925dcd532baa43292a 100644 (file)
@@ -34,21 +34,25 @@ along with GCC; see the file COPYING3.  If not see
 class function_arg_info
 {
 public:
-  function_arg_info () : type (NULL_TREE), mode (VOIDmode), named (false) {}
+  function_arg_info ()
+    : type (NULL_TREE), mode (VOIDmode), named (false),
+      pass_by_reference (false)
+  {}
 
   /* Initialize an argument of mode MODE, either before or after promotion.  */
   function_arg_info (machine_mode mode, bool named)
-    : type (NULL_TREE), mode (mode), named (named)
+    : type (NULL_TREE), mode (mode), named (named), pass_by_reference (false)
   {}
 
   /* Initialize an unpromoted argument of type TYPE.  */
   function_arg_info (tree type, bool named)
-    : type (type), mode (TYPE_MODE (type)), named (named)
+    : type (type), mode (TYPE_MODE (type)), named (named),
+      pass_by_reference (false)
   {}
 
   /* Initialize an argument with explicit properties.  */
   function_arg_info (tree type, machine_mode mode, bool named)
-    : type (type), mode (mode), named (named)
+    : type (type), mode (mode), named (named), pass_by_reference (false)
   {}
 
   /* Return true if the gimple-level type is an aggregate.  */
@@ -100,6 +104,10 @@ public:
      treated as an unnamed variadic argument (i.e. one passed through
      "...").  See also TARGET_STRICT_ARGUMENT_NAMING.  */
   unsigned int named : 1;
+
+  /* True if we have decided to pass the argument by reference, in which case
+     the function_arg_info describes a pointer to the original argument.  */
+  unsigned int pass_by_reference : 1;
 };
 
 extern int flags_from_decl_or_type (const_tree);
index d6d38b92a756915e9127ff82d349dcbbacf1f559..4bc4052fb2db332e58ea126f04db42bde143e0ea 100644 (file)
@@ -2271,7 +2271,6 @@ struct assign_parm_data_one
   machine_mode passed_mode;
   struct locate_and_pad_arg_data locate;
   int partial;
-  BOOL_BITFIELD passed_pointer : 1;
 };
 
 /* A subroutine of assign_parms.  Initialize ALL.  */
@@ -2453,7 +2452,6 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm,
   if (apply_pass_by_reference_rules (&all->args_so_far_v, data->arg))
     {
       data->nominal_type = data->arg.type;
-      data->passed_pointer = true;
       data->passed_mode = data->nominal_mode = data->arg.mode;
     }
 
@@ -2653,7 +2651,7 @@ assign_parm_find_stack_rtl (tree parm, struct assign_parm_data_one *data)
     stack_parm = gen_rtx_PLUS (Pmode, stack_parm, offset_rtx);
   stack_parm = gen_rtx_MEM (data->arg.mode, stack_parm);
 
-  if (!data->passed_pointer)
+  if (!data->arg.pass_by_reference)
     {
       set_mem_attributes (stack_parm, parm, 1);
       /* set_mem_attributes could set MEM_SIZE to the passed mode's size,
@@ -2827,7 +2825,7 @@ assign_parm_adjust_stack_rtl (struct assign_parm_data_one *data)
      pointers in their passed stack slots.  */
   else if (crtl->stack_protect_guard
           && (flag_stack_protect == 2
-              || data->passed_pointer
+              || data->arg.pass_by_reference
               || POINTER_TYPE_P (data->nominal_type)))
     stack_parm = NULL;
 
@@ -3140,7 +3138,7 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
 
   /* If this was an item that we received a pointer to,
      set rtl appropriately.  */
-  if (data->passed_pointer)
+  if (data->arg.pass_by_reference)
     {
       rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (data->arg.type)), parmreg);
       set_mem_attributes (rtl, parm, 1);
@@ -3310,7 +3308,7 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
 
   /* If we were passed a pointer but the actual value can safely live
      in a register, retrieve it and use it directly.  */
-  if (data->passed_pointer && TYPE_MODE (TREE_TYPE (parm)) != BLKmode)
+  if (data->arg.pass_by_reference && TYPE_MODE (TREE_TYPE (parm)) != BLKmode)
     {
       /* We can't use nominal_mode, because it will have been set to
         Pmode above.  We must use the actual mode of the parm.  */
@@ -3630,7 +3628,7 @@ assign_parms (tree fndecl)
          assign_parm_adjust_entry_rtl (&data);
        }
       /* Record permanently how this parm was passed.  */
-      if (data.passed_pointer)
+      if (data.arg.pass_by_reference)
        {
          rtx incoming_rtl
            = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (data.arg.type)),
@@ -3644,7 +3642,7 @@ assign_parms (tree fndecl)
 
       if (assign_parm_setup_block_p (&data))
        assign_parm_setup_block (&all, parm, &data);
-      else if (data.passed_pointer || use_register_for_decl (parm))
+      else if (data.arg.pass_by_reference || use_register_for_decl (parm))
        assign_parm_setup_reg (&all, parm, &data);
       else
        assign_parm_setup_stack (&all, parm, &data);
@@ -3855,7 +3853,7 @@ gimplify_parameters (gimple_seq *cleanup)
          gimplify_one_sizepos (&DECL_SIZE_UNIT (parm), &stmts);
        }
 
-      if (data.passed_pointer)
+      if (data.arg.pass_by_reference)
        {
          tree type = TREE_TYPE (data.arg.type);
          function_arg_info orig_arg (type, data.arg.named);