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-19  Richard Sandiford  <richard.sandif...@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.

Index: gcc/calls.h
===================================================================
--- gcc/calls.h 2019-08-19 15:59:09.801778220 +0100
+++ gcc/calls.h 2019-08-19 15:59:21.817691272 +0100
@@ -34,21 +34,25 @@ #define GCC_CALLS_H
 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 @@ #define GCC_CALLS_H
      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: gcc/calls.c
===================================================================
--- gcc/calls.c 2019-08-19 15:59:18.145717843 +0100
+++ gcc/calls.c 2019-08-19 15:59:21.817691272 +0100
@@ -946,6 +946,7 @@ apply_pass_by_reference_rules (CUMULATIV
     {
       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
                                              "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, r
                                             call_fusage);
 
          arg.mode = Pmode;
+         arg.pass_by_reference = true;
          val = force_operand (XEXP (slot, 0), NULL_RTX);
        }
 
Index: gcc/function.c
===================================================================
--- gcc/function.c      2019-08-19 15:59:14.297745685 +0100
+++ gcc/function.c      2019-08-19 15:59:21.821691241 +0100
@@ -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 assi
   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, s
     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,
@@ -2812,7 +2810,7 @@ assign_parm_adjust_stack_rtl (struct ass
      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;
 
@@ -3125,7 +3123,7 @@ assign_parm_setup_reg (struct assign_par
 
   /* 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);
@@ -3295,7 +3293,7 @@ assign_parm_setup_reg (struct assign_par
 
   /* 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.  */
@@ -3615,7 +3613,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)),
@@ -3629,7 +3627,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);
@@ -3840,7 +3838,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);

Reply via email to