summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/calls.c16
-rw-r--r--gcc/calls.h2
-rw-r--r--gcc/config/c6x/c6x.c16
-rw-r--r--gcc/config/rs6000/rs6000-call.c9
-rw-r--r--gcc/config/s390/s390.c16
-rw-r--r--gcc/function.c6
-rw-r--r--gcc/var-tracking.c22
8 files changed, 47 insertions, 50 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b5a198c95dc..8a68093c64a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,15 @@
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
of a mode and a type.
* doc/tm.texi: Regenerate.
diff --git a/gcc/calls.c b/gcc/calls.c
index 1f691e84dfe..6f573f3b26e 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -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. */
diff --git a/gcc/calls.h b/gcc/calls.h
index 5e8c576424a..01ab3905a3a 100644
--- a/gcc/calls.h
+++ b/gcc/calls.h
@@ -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]);
diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c
index 37da9a419db..8477d35e1e7 100644
--- a/gcc/config/c6x/c6x.c
+++ b/gcc/config/c6x/c6x.c
@@ -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);
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index fb87bb2f2cb..7280a4ed9c8 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -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;
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 3ad4a185e20..fa17d7d5d08 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -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);
diff --git a/gcc/function.c b/gcc/function.c
index 46ed75c77be..265bcd19f50 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -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;
}
}
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index 8b1d4476e22..af18528b6d7 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -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))