From: Richard Henderson Date: Wed, 8 Sep 2004 18:45:21 +0000 (-0700) Subject: function.c (reference_callee_copied): New. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6cdd56724aff3adc4bef1b5441526d84ddb6d2cb;p=gcc.git function.c (reference_callee_copied): New. * 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. From-SVN: r87195 --- 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 + + * 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 - * 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 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 @@ -3143,25 +3143,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. */ 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);