diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2a6d8910bfb..dd9838f2678 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2019-08-20 Richard Sandiford + + * 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 * calls.c (emit_library_call_value_1): Merge arg and orig_arg diff --git a/gcc/calls.c b/gcc/calls.c index 454e5130391..6eefeec17d9 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -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); } diff --git a/gcc/calls.h b/gcc/calls.h index 01ab3905a3a..a782a7d3695 100644 --- a/gcc/calls.h +++ b/gcc/calls.h @@ -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); diff --git a/gcc/function.c b/gcc/function.c index d6d38b92a75..4bc4052fb2d 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -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);