aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog51
-rw-r--r--gcc/calls.c8
-rw-r--r--gcc/config/arc/arc.c3
-rw-r--r--gcc/config/arc/arc.h9
-rw-r--r--gcc/config/frv/frv-protos.h4
-rw-r--r--gcc/config/frv/frv.c19
-rw-r--r--gcc/config/frv/frv.h11
-rw-r--r--gcc/config/iq2000/iq2000.c2
-rw-r--r--gcc/config/iq2000/iq2000.h2
-rw-r--r--gcc/config/m68hc11/m68hc11.c2
-rw-r--r--gcc/config/m68hc11/m68hc11.h11
-rw-r--r--gcc/config/mips/mips.c12
-rw-r--r--gcc/config/mips/mips.h3
-rw-r--r--gcc/config/mmix/mmix.c2
-rw-r--r--gcc/config/mmix/mmix.h2
-rw-r--r--gcc/config/mn10300/mn10300.c2
-rw-r--r--gcc/config/mn10300/mn10300.h2
-rw-r--r--gcc/config/pa/pa.c2
-rw-r--r--gcc/config/pa/pa.h2
-rw-r--r--gcc/config/sh/sh.c16
-rw-r--r--gcc/config/sh/sh.h6
-rw-r--r--gcc/config/v850/v850.c3
-rw-r--r--gcc/config/v850/v850.h2
-rw-r--r--gcc/doc/rtl.texi4
-rw-r--r--gcc/doc/tm.texi22
-rw-r--r--gcc/expr.h4
-rw-r--r--gcc/function.c17
-rw-r--r--gcc/function.h2
-rw-r--r--gcc/target-def.h9
-rw-r--r--gcc/target.h6
-rw-r--r--gcc/targhooks.c39
-rw-r--r--gcc/targhooks.h17
32 files changed, 176 insertions, 120 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3108964bfa2..c58585af6e9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,8 +1,53 @@
+2004-09-08 Richard Henderson <rth@redhat.com>
+
+ * function.c (reference_callee_copied): New.
+ (assign_parm_setup_reg): Use it.
+ * calls.c (initialize_argument_information): Likewise.
+ (emit_library_call_value_1): Likewise.
+ * function.h (reference_callee_copied): Declare.
+
+ * target.h (struct gcc_target): Add callee_copies.
+ * target-def.h (TARGET_CALLEE_COPIES): New.
+ (TARGET_PASS_BY_REFERENCE): Update default.
+ * expr.h (FUNCTION_ARG_CALLEE_COPIES): Remove.
+ * targhooks.c (hook_callee_copies_named): New.
+ (hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false): Rename from
+ hook_pass_by_reference_false.
+ (hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true): New.
+ * targhooks.h: Update decls.
+ * config/arc/arc.c (TARGET_CALLEE_COPIES): New.
+ * config/arc/arc.h (FUNCTION_ARG_CALLEE_COPIES): Remove.
+ * config/frv/frv-protos.h (frv_function_arg_callee_copies): Remove.
+ * config/frv/frv.c (frv_function_arg_callee_copies): Remove.
+ * config/frv/frv.h (FUNCTION_ARG_CALLEE_COPIES): Remove.
+ * config/iq2000/iq2000.c (TARGET_CALLEE_COPIES): New.
+ * config/iq2000/iq2000.h (FUNCTION_ARG_CALLEE_COPIES): Remove.
+ * config/m68hc11/m68hc11.c (TARGET_CALLEE_COPIES): New.
+ * config/m68hc11/m68hc11.h (FUNCTION_ARG_CALLEE_COPIES): Remove.
+ * config/mips/mips.c (TARGET_CALLEE_COPIES): New.
+ (mips_callee_copies): New.
+ * config/mips/mips.h (FUNCTION_ARG_CALLEE_COPIES): Remove.
+ * config/mmix/mmix.c (TARGET_CALLEE_COPIES): New.
+ * config/mmix/mmix.h (FUNCTION_ARG_CALLEE_COPIES): Remove.
+ * config/mn10300/mn10300.c (TARGET_CALLEE_COPIES): New.
+ * config/mn10300/mn10300.h (FUNCTION_ARG_CALLEE_COPIES): Remove.
+ * config/pa/pa.c (TARGET_CALLEE_COPIES): New.
+ * config/pa/pa.h (FUNCTION_ARG_CALLEE_COPIES): Remove.
+ * config/sh/sh.c (sh_callee_copies): New.
+ (TARGET_CALLEE_COPIES): New.
+ * config/sh/sh.h (FUNCTION_ARG_CALLEE_COPIES): Remove.
+ * config/v850/v850.c (TARGET_CALLEE_COPIES): New.
+ * config/v850/v850.h (FUNCTION_ARG_CALLEE_COPIES): Remove.
+ * doc/tm.texi (TARGET_CALLEE_COPIES): Replace documentation
+ for FUNCTION_ARG_CALLEE_COPIES.
+ * doc/rtl.texi (CALL_INSN_FUNCTION_USAGE): Update.
+
2004-09-08 Devang Patel <dpatel@apple.com>
- * tree-if-conv.c (find_phi_replacement_condition): Return true edge block.
- (replace_phi_with_cond_modify_expr): Select conditional expr args based on
- true edge basic block.
+ * tree-if-conv.c (find_phi_replacement_condition): Return true
+ edge block.
+ (replace_phi_with_cond_modify_expr): Select conditional expr args
+ based on true edge basic block.
2004-09-08 Jan Hubicka <jh@suse.cz>
diff --git a/gcc/calls.c b/gcc/calls.c
index eea4146e16b..09c24d7c27b 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -974,8 +974,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
tree base;
callee_copies
- = FUNCTION_ARG_CALLEE_COPIES (*args_so_far, TYPE_MODE (type),
- type, argpos < n_named_args);
+ = reference_callee_copied (args_so_far, TYPE_MODE (type),
+ type, argpos < n_named_args);
/* If we're compiling a thunk, pass through invisible references
instead of making a copy. */
@@ -3333,8 +3333,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
if (pass_by_reference (&args_so_far, mode, NULL_TREE, 1))
{
rtx slot;
- int must_copy = ! FUNCTION_ARG_CALLEE_COPIES (args_so_far, mode,
- NULL_TREE, 1);
+ int must_copy
+ = !reference_callee_copied (&args_so_far, mode, NULL_TREE, 1);
/* loop.c won't look at CALL_INSN_FUNCTION_USAGE of const/pure
functions, so we have to pretend this isn't such a function. */
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 9fc5ee2d185..90419f9fefd 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -142,6 +142,8 @@ static bool arc_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
#define TARGET_RETURN_IN_MEMORY arc_return_in_memory
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
+#undef TARGET_CALLEE_COPIES
+#define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
#undef TARGET_SETUP_INCOMING_VARARGS
#define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
@@ -2356,4 +2358,3 @@ arc_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
return size > 8;
}
-
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index eefac0ce212..6b94cd1e3a3 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -696,15 +696,6 @@ extern enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER];
registers. */
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
-/* A C expression that indicates when it is the called function's
- responsibility to make copies of arguments passed by reference.
- If the callee can determine that the argument won't be modified, it can
- avoid the copy. */
-/* ??? We'd love to be able to use NAMED here. Unfortunately, it doesn't
- include the last named argument so we keep track of the args ourselves. */
-
-#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 1
-
/* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE.
(TYPE is null for libcalls where that information may not be available.) */
diff --git a/gcc/config/frv/frv-protos.h b/gcc/config/frv/frv-protos.h
index a63669b36cc..611e8d6262f 100644
--- a/gcc/config/frv/frv-protos.h
+++ b/gcc/config/frv/frv-protos.h
@@ -84,10 +84,6 @@ extern int frv_function_arg_partial_nregs (CUMULATIVE_ARGS *,
enum machine_mode,
tree, int);
-extern int frv_function_arg_callee_copies (CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int);
-
extern void frv_expand_builtin_va_start (tree, rtx);
#endif /* TREE_CODE */
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index 7bd22f25af9..58d86a9b253 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -3144,25 +3144,6 @@ frv_function_arg_partial_nregs (CUMULATIVE_ARGS *cum,
}
-/* If defined, a C expression that indicates when it is the called function's
- responsibility to make a copy of arguments passed by invisible reference.
- Normally, the caller makes a copy and passes the address of the copy to the
- routine being called. When FUNCTION_ARG_CALLEE_COPIES is defined and is
- nonzero, the caller does not make a copy. Instead, it passes a pointer to
- the "live" value. The called function must not modify this value. If it
- can be determined that the value won't be modified, it need not make a copy;
- otherwise a copy must be made. */
-
-int
-frv_function_arg_callee_copies (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED,
- tree type ATTRIBUTE_UNUSED,
- int named ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
-
/* Return true if a register is ok to use as a base or index register. */
static FRV_INLINE int
diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h
index bb960e62d70..84e59cfa3a5 100644
--- a/gcc/config/frv/frv.h
+++ b/gcc/config/frv/frv.h
@@ -1903,17 +1903,6 @@ struct machine_function GTY(())
/* extern int frv_function_arg_partial_nregs (CUMULATIVE_ARGS, int, Tree, int); */
-/* If defined, a C expression that indicates when it is the called function's
- responsibility to make a copy of arguments passed by invisible reference.
- Normally, the caller makes a copy and passes the address of the copy to the
- routine being called. When FUNCTION_ARG_CALLEE_COPIES is defined and is
- nonzero, the caller does not make a copy. Instead, it passes a pointer to
- the "live" value. The called function must not modify this value. If it
- can be determined that the value won't be modified, it need not make a copy;
- otherwise a copy must be made. */
-#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \
- frv_function_arg_callee_copies (&CUM, MODE, TYPE, NAMED)
-
/* A C type for declaring a variable that is used as the first argument of
`FUNCTION_ARG' and other related values. For some target machines, the type
`int' suffices and can hold the number of bytes of argument so far.
diff --git a/gcc/config/iq2000/iq2000.c b/gcc/config/iq2000/iq2000.c
index ece7021b161..3f39ec557b7 100644
--- a/gcc/config/iq2000/iq2000.c
+++ b/gcc/config/iq2000/iq2000.c
@@ -199,6 +199,8 @@ static bool iq2000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
#define TARGET_RETURN_IN_MEMORY iq2000_return_in_memory
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE iq2000_pass_by_reference
+#undef TARGET_CALLEE_COPIES
+#define TARGET_CALLEE_COPIES hook_callee_copies_named
#undef TARGET_SETUP_INCOMING_VARARGS
#define TARGET_SETUP_INCOMING_VARARGS iq2000_setup_incoming_varargs
diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h
index f6f381089e2..09cca0f1658 100644
--- a/gcc/config/iq2000/iq2000.h
+++ b/gcc/config/iq2000/iq2000.h
@@ -441,8 +441,6 @@ enum reg_class
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
function_arg_partial_nregs (& CUM, MODE, TYPE, NAMED)
-#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) (NAMED)
-
#define MAX_ARGS_IN_REGISTERS 8
typedef struct iq2000_args
diff --git a/gcc/config/m68hc11/m68hc11.c b/gcc/config/m68hc11/m68hc11.c
index 99d9568339f..4d47a6275cf 100644
--- a/gcc/config/m68hc11/m68hc11.c
+++ b/gcc/config/m68hc11/m68hc11.c
@@ -272,6 +272,8 @@ static int nb_soft_regs;
#define TARGET_STRUCT_VALUE_RTX m68hc11_struct_value_rtx
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY m68hc11_return_in_memory
+#undef TARGET_CALLEE_COPIES
+#define TARGET_CALLEE_COPIES hook_callee_copies_named
#undef TARGET_STRIP_NAME_ENCODING
#define TARGET_STRIP_NAME_ENCODING m68hc11_strip_name_encoding
diff --git a/gcc/config/m68hc11/m68hc11.h b/gcc/config/m68hc11/m68hc11.h
index 9732219c298..497c53574d2 100644
--- a/gcc/config/m68hc11/m68hc11.h
+++ b/gcc/config/m68hc11/m68hc11.h
@@ -1049,17 +1049,6 @@ typedef struct m68hc11_args
#define PAD_VARARGS_DOWN \
(m68hc11_function_arg_padding (TYPE_MODE (type), type) == downward)
-/* A C expression that indicates when it is the called function's
- responsibility to make a copy of arguments passed by invisible
- reference. Normally, the caller makes a copy and passes the
- address of the copy to the routine being called. When
- FUNCTION_ARG_CALLEE_COPIES is defined and is nonzero, the caller
- does not make a copy. Instead, it passes a pointer to the "live"
- value. The called function must not modify this value. If it can
- be determined that the value won't be modified, it need not make a
- copy; otherwise a copy must be made. */
-#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) (NAMED)
-
/* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a
function whose data type is FNTYPE. For a library call, FNTYPE is 0. */
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index ea0eb7b41f3..b3be4bb418b 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -349,6 +349,8 @@ static tree mips_build_builtin_va_list (void);
static tree mips_gimplify_va_arg_expr (tree, tree, tree *, tree *);
static bool mips_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode mode,
tree, bool);
+static bool mips_callee_copies (CUMULATIVE_ARGS *, enum machine_mode mode,
+ tree, bool);
static bool mips_vector_mode_supported_p (enum machine_mode);
static rtx mips_prepare_builtin_arg (enum insn_code, unsigned int, tree *);
static rtx mips_prepare_builtin_target (enum insn_code, unsigned int, rtx);
@@ -785,6 +787,8 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE mips_pass_by_reference
+#undef TARGET_CALLEE_COPIES
+#define TARGET_CALLEE_COPIES mips_callee_copies
#undef TARGET_VECTOR_MODE_SUPPORTED_P
#define TARGET_VECTOR_MODE_SUPPORTED_P mips_vector_mode_supported_p
@@ -6808,6 +6812,14 @@ mips_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
}
}
+static bool
+mips_callee_copies (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type ATTRIBUTE_UNUSED, bool named)
+{
+ return mips_abi == ABI_EABI && named;
+}
+
/* Return the class of registers for which a mode change from FROM to TO
is invalid.
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index f9104bdff4d..3428ac9a4fe 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -2302,9 +2302,6 @@ typedef struct mips_args {
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
(mips_pad_reg_upward (MODE, TYPE) ? upward : downward)
-#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \
- (mips_abi == ABI_EABI && (NAMED))
-
/* True if using EABI and varargs can be passed in floating-point
registers. Under these conditions, we need a more complex form
of va_list, which tracks GPR, FPR and stack arguments separately. */
diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c
index 6c5a193b227..c08fa92e1d7 100644
--- a/gcc/config/mmix/mmix.c
+++ b/gcc/config/mmix/mmix.c
@@ -206,6 +206,8 @@ static bool mmix_pass_by_reference (const CUMULATIVE_ARGS *,
#define TARGET_SETUP_INCOMING_VARARGS mmix_setup_incoming_varargs
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE mmix_pass_by_reference
+#undef TARGET_CALLEE_COPIES
+#define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h
index 6894337b2ff..143c8de462e 100644
--- a/gcc/config/mmix/mmix.h
+++ b/gcc/config/mmix/mmix.h
@@ -720,8 +720,6 @@ enum reg_class
#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
mmix_function_arg (&(CUM), MODE, TYPE, NAMED, 1)
-#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 1
-
typedef struct { int regs; int lib; } CUMULATIVE_ARGS;
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c
index 7b805310e09..b0af9d91d27 100644
--- a/gcc/config/mn10300/mn10300.c
+++ b/gcc/config/mn10300/mn10300.c
@@ -97,6 +97,8 @@ static bool mn10300_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
#define TARGET_RETURN_IN_MEMORY mn10300_return_in_memory
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE mn10300_pass_by_reference
+#undef TARGET_CALLEE_COPIES
+#define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
#undef TARGET_EXPAND_BUILTIN_SAVEREGS
#define TARGET_EXPAND_BUILTIN_SAVEREGS mn10300_builtin_saveregs
diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h
index e77f9d26e44..df1a4b11444 100644
--- a/gcc/config/mn10300/mn10300.h
+++ b/gcc/config/mn10300/mn10300.h
@@ -610,8 +610,6 @@ struct cum_arg {int nbytes; };
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED)
-
-#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 1
/* Define how to find the value returned by a function.
VALTYPE is the data type of the value (as a tree).
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 401c642481e..7c875817b40 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -280,6 +280,8 @@ static size_t n_deferred_plabels = 0;
#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE pa_pass_by_reference
+#undef TARGET_CALLEE_COPIES
+#define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
#undef TARGET_EXPAND_BUILTIN_SAVEREGS
#define TARGET_EXPAND_BUILTIN_SAVEREGS hppa_builtin_saveregs
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 4a6f78cbc62..7e4e1fd9fcf 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -949,8 +949,6 @@ struct hppa_args {int words, nargs_prototype, incoming, indirect; };
: GET_MODE_SIZE(MODE) <= UNITS_PER_WORD) \
? PARM_BOUNDARY : MAX_PARM_BOUNDARY)
-#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 1
-
extern GTY(()) rtx hppa_compare_op0;
extern GTY(()) rtx hppa_compare_op1;
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 087bb7fd47f..b58293d8a35 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -283,6 +283,8 @@ static tree sh_build_builtin_va_list (void);
static tree sh_gimplify_va_arg_expr (tree, tree, tree *, tree *);
static bool sh_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool);
+static bool sh_callee_copies (CUMULATIVE_ARGS *, enum machine_mode,
+ tree, bool);
/* Initialize the GCC target structure. */
@@ -438,6 +440,8 @@ static bool sh_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE sh_pass_by_reference
+#undef TARGET_CALLEE_COPIES
+#define TARGET_CALLEE_COPIES sh_callee_copies
#undef TARGET_BUILD_BUILTIN_VA_LIST
#define TARGET_BUILD_BUILTIN_VA_LIST sh_build_builtin_va_list
@@ -6609,6 +6613,18 @@ sh_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_mode mode,
return false;
}
+static bool
+sh_callee_copies (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, bool named ATTRIBUTE_UNUSED)
+{
+ /* ??? How can it possibly be correct to return true only on the
+ caller side of the equation? Is there someplace else in the
+ sh backend that's magically producing the copies? */
+ return (cum->outgoing
+ && ((mode == BLKmode ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode))
+ % SH_MIN_ALIGN_FOR_CALLEE_COPY == 0));
+}
+
/* Define where to put the arguments to a function.
Value is zero to push the argument on the stack,
or a hard register in which to store the argument.
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 5f6cc48f1cc..61fd9ca6f37 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -2197,12 +2197,6 @@ struct sh_args {
boundaries, because they'll be loaded using quad loads. */
#define SH_MIN_ALIGN_FOR_CALLEE_COPY (8 * BITS_PER_UNIT)
-#define FUNCTION_ARG_CALLEE_COPIES(CUM,MODE,TYPE,NAMED) \
- ((CUM).outgoing \
- && (((MODE) == BLKmode ? TYPE_ALIGN (TYPE) \
- : GET_MODE_ALIGNMENT (MODE)) \
- % SH_MIN_ALIGN_FOR_CALLEE_COPY == 0))
-
/* The SH5 ABI requires floating-point arguments to be passed to
functions without a prototype in both an FP register and a regular
register or the stack. When passing the argument in both FP and
diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c
index 398fe7e1c3e..98c24c94ffe 100644
--- a/gcc/config/v850/v850.c
+++ b/gcc/config/v850/v850.c
@@ -131,6 +131,9 @@ static int v850_interrupt_p = FALSE;
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE v850_pass_by_reference
+#undef TARGET_CALLEE_COPIES
+#define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
+
#undef TARGET_SETUP_INCOMING_VARARGS
#define TARGET_SETUP_INCOMING_VARARGS v850_setup_incoming_varargs
diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h
index 5643a9df749..fe3a659c963 100644
--- a/gcc/config/v850/v850.h
+++ b/gcc/config/v850/v850.h
@@ -773,8 +773,6 @@ struct cum_arg { int nbytes; int anonymous_args; };
space allocated by the caller. */
#define OUTGOING_REG_PARM_STACK_SPACE
-#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 1
-
/* 1 if N is a possible register number for function argument passing. */
#define FUNCTION_ARG_REGNO_P(N) (N >= 6 && N <= 9)
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index a99ebd5449b..113dc147e79 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -2959,8 +2959,8 @@ clobbered by the called function.
A @code{MEM} generally points to a stack slots in which arguments passed
to the libcall by reference (@pxref{Register Arguments,
-FUNCTION_ARG_PASS_BY_REFERENCE}) are stored. If the argument is
-caller-copied (@pxref{Register Arguments, FUNCTION_ARG_CALLEE_COPIES}),
+TARGET_PASS_BY_REFERENCE}) are stored. If the argument is
+caller-copied (@pxref{Register Arguments, TARGET_CALLEE_COPIES}),
the stack slot will be mentioned in @code{CLOBBER} and @code{USE}
entries; if it's callee-copied, only a @code{USE} will appear, and the
@code{MEM} may point to addresses that are not stack slots. These
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 74d3b4df407..0734b2cebc5 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -3733,16 +3733,18 @@ The pointer is passed in whatever way is appropriate for passing a pointer
to that type.
@end deftypefn
-@defmac FUNCTION_ARG_CALLEE_COPIES (@var{cum}, @var{mode}, @var{type}, @var{named})
-If defined, a C expression that indicates when it is the called function's
-responsibility to make a copy of arguments passed by invisible reference.
-Normally, the caller makes a copy and passes the address of the copy to the
-routine being called. When @code{FUNCTION_ARG_CALLEE_COPIES} is defined and is
-nonzero, the caller does not make a copy. Instead, it passes a pointer to the
-``live'' value. The called function must not modify this value. If it can be
-determined that the value won't be modified, it need not make a copy;
-otherwise a copy must be made.
-@end defmac
+@deftypefn {Target Hook} bool TARGET_CALLEE_COPIES (CUMULATIVE_ARGS *@var{cum}, enum machine_mode @var{mode}, tree @var{type}, bool @var{named})
+The function argument described by the parameters to this hook is
+known to be passed by reference. The hook should return true if the
+function argument should be copied by the callee instead of copied
+by the caller.
+
+For any argument for which the hook returns true, if it can be
+determined that the argument is not modified, then a copy need
+not be generated.
+
+The default version of this hook always returns false.
+@end deftypefn
@defmac CUMULATIVE_ARGS
A C type for declaring a variable that is used as the first argument of
diff --git a/gcc/expr.h b/gcc/expr.h
index a3276299e49..2f693bb3daf 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -188,10 +188,6 @@ do { \
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
#endif
-#ifndef FUNCTION_ARG_CALLEE_COPIES
-#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) 0
-#endif
-
tree split_complex_types (tree);
tree split_complex_values (tree);
diff --git a/gcc/function.c b/gcc/function.c
index 589294ff7a8..34c5d65dbe8 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -1951,6 +1951,18 @@ pass_by_reference (CUMULATIVE_ARGS *ca, enum machine_mode mode,
return targetm.calls.pass_by_reference (ca, mode, type, named_arg);
}
+/* Return true if TYPE, which is passed by reference, should be callee
+ copied instead of caller copied. */
+
+bool
+reference_callee_copied (CUMULATIVE_ARGS *ca, enum machine_mode mode,
+ tree type, bool named_arg)
+{
+ if (type && TREE_ADDRESSABLE (type))
+ return false;
+ return targetm.calls.callee_copies (ca, mode, type, named_arg);
+}
+
/* Structures to communicate between the subroutines of assign_parms.
The first holds data persistent across all parameters, the second
is cleared out for each parameter. */
@@ -2766,9 +2778,8 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
{
tree type = TREE_TYPE (data->passed_type);
- if (FUNCTION_ARG_CALLEE_COPIES (all->args_so_far, TYPE_MODE (type),
- type, data->named_arg)
- && !TREE_ADDRESSABLE (type))
+ if (reference_callee_copied (&all->args_so_far, TYPE_MODE (type),
+ type, data->named_arg))
{
rtx copy;
diff --git a/gcc/function.h b/gcc/function.h
index 0c1ca1aba5f..e38b5294dbb 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -543,5 +543,7 @@ extern void do_warn_unused_parameter (tree);
extern bool pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool);
+extern bool reference_callee_copied (CUMULATIVE_ARGS *, enum machine_mode,
+ tree, bool);
#endif /* GCC_FUNCTION_H */
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 01837efd604..38042069122 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -383,12 +383,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define TARGET_SPLIT_COMPLEX_ARG NULL
#define TARGET_GIMPLIFY_VA_ARG_EXPR std_gimplify_va_arg_expr
-
-#define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_false
-
+#define TARGET_PASS_BY_REFERENCE hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false
#define TARGET_LATE_RTL_PROLOGUE_EPILOGUE false
-
#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size_or_pad
+#define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false
#define TARGET_CALLS { \
TARGET_PROMOTE_FUNCTION_ARGS, \
@@ -403,7 +401,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
TARGET_STRICT_ARGUMENT_NAMING, \
TARGET_PRETEND_OUTGOING_VARARGS_NAMED, \
TARGET_SPLIT_COMPLEX_ARG, \
- TARGET_MUST_PASS_IN_STACK \
+ TARGET_MUST_PASS_IN_STACK, \
+ TARGET_CALLEE_COPIES \
}
diff --git a/gcc/target.h b/gcc/target.h
index e91219cfd56..acb1814bcc3 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -502,6 +502,12 @@ struct gcc_target
/* ??? This predicate should be applied strictly after pass-by-reference.
Need audit to verify that this is the case. */
bool (* must_pass_in_stack) (enum machine_mode mode, tree t);
+
+ /* Return true if type TYPE, mode MODE, which is passed by reference,
+ should have the object copy generated by the callee rather than
+ the caller. It is never called for TYPE requiring constructors. */
+ bool (* callee_copies) (CUMULATIVE_ARGS *ca, enum machine_mode mode,
+ tree type, bool named);
} calls;
/* Functions specific to the C++ frontend. */
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 5ecb6d8370d..042c83efb4c 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -184,17 +184,6 @@ default_cxx_get_cookie_size (tree type)
return cookie_size;
}
-/* This version of the TARGET_PASS_BY_REFERENCE hook adds no conditions
- beyond those mandated by generic code. */
-
-bool
-hook_pass_by_reference_false (CUMULATIVE_ARGS *c ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED,
- bool named_arg ATTRIBUTE_UNUSED)
-{
- return false;
-}
-
/* Return true if a parameter must be passed by reference. This version
of the TARGET_PASS_BY_REFERENCE hook uses just MUST_PASS_IN_STACK. */
@@ -206,6 +195,16 @@ hook_pass_by_reference_must_pass_in_stack (CUMULATIVE_ARGS *c ATTRIBUTE_UNUSED,
return targetm.calls.must_pass_in_stack (mode, type);
}
+/* Return true if a parameter follows callee copies conventions. This
+ version of the hook is true for all named arguments. */
+
+bool
+hook_callee_copies_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type ATTRIBUTE_UNUSED, bool named)
+{
+ return named;
+}
/* Emit any directives required to unwind this instruction. */
@@ -262,3 +261,21 @@ default_scalar_mode_supported_p (enum machine_mode mode)
abort ();
}
}
+
+bool
+hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false (
+ CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
+{
+ return false;
+}
+
+bool
+hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true (
+ CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
+{
+ return true;
+}
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 8745f7eb5b7..bbdfacdc0a5 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -28,22 +28,31 @@ extern bool default_return_in_memory (tree, tree);
extern rtx default_expand_builtin_saveregs (void);
extern void default_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int);
extern rtx default_builtin_setjmp_frame_value (void);
-extern bool hook_bool_CUMULATIVE_ARGS_false (CUMULATIVE_ARGS *);
extern bool default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *);
extern enum machine_mode default_eh_return_filter_mode (void);
extern unsigned HOST_WIDE_INT default_shift_truncation_mask
(enum machine_mode);
-extern bool hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS *);
extern tree default_cxx_guard_type (void);
extern tree default_cxx_get_cookie_size (tree);
-extern bool hook_pass_by_reference_false
- (CUMULATIVE_ARGS *, enum machine_mode mode, tree, bool);
extern bool hook_pass_by_reference_must_pass_in_stack
(CUMULATIVE_ARGS *, enum machine_mode mode, tree, bool);
+extern bool hook_callee_copies_named
+ (CUMULATIVE_ARGS *ca, enum machine_mode, tree, bool);
extern void default_unwind_emit (FILE *, rtx);
extern bool default_scalar_mode_supported_p (enum machine_mode);
+
+/* These are here, and not in hooks.[ch], because not all users of
+ hooks.h include tm.h, and thus we don't have CUMULATIVE_ARGS. */
+
+extern bool hook_bool_CUMULATIVE_ARGS_false (CUMULATIVE_ARGS *);
+extern bool hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS *);
+
+extern bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false
+ (CUMULATIVE_ARGS *, enum machine_mode, tree, bool);
+extern bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
+ (CUMULATIVE_ARGS *, enum machine_mode, tree, bool);