diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3108964bfa2a1a43a4b94063313d8feaba92c4ae..c58585af6e9028d766d0a86b19155e92751249d4 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 eea4146e16bdb8a2f2b04aea89538ed0e023d94a..09c24d7c27b2cb2930f1f4392cccc9aa1439136f 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 9fc5ee2d1853262a70f8b356b97632a47bb7b06f..90419f9fefd465f7488c202c4551cf8539c4d6b1 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 eefac0ce212dbed70c563bbdea8eb1a7a7681b10..6b94cd1e3a335b65e87620d2f5137160e79d9aab 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 a63669b36cc85885fec985a4f2db0dd26cb2414b..611e8d6262f2e5444254038e33f7714336836702 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 7bd22f25af983aa34a5f879f7017caebbb1e596e..58d86a9b2536990d972ccdf8f973a78ff0896182 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 bb960e62d702426886a51c42960136d1a99d417d..84e59cfa3a5d256f3dd4a563b2d8bb5d19cdf2ce 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 ece7021b1616b9afc8b696b61c04f9e201a9c80e..3f39ec557b7663de836c326e17c5dedce048a935 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 f6f381089e29672d11e5bba5ed6bf27bd6ee2d63..09cca0f1658b6975493d7e8ca147845f866a4e31 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 99d9568339f7e94ebc8bacd1fd96d26e2c05d950..4d47a6275cf6c2edeb1ccdb78d1dadd55d7269eb 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 9732219c298204a7b0aa89976c08f91b4e9faa31..497c53574d25ddbd224071666fe3f839470f76d8 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 ea0eb7b41f3b1a685b5249a372676628a9ad4f9c..b3be4bb418b6ed758ee5bfd1b08e00ba0fe84987 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 f9104bdff4d6e4d0ee23299ecc9842d5daa709ec..3428ac9a4fee457e355038042d9f929709632f34 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 6c5a193b2278c425fa6f330f77f913c86a341d7a..c08fa92e1d71b0b94f1362c8e057e7ffc2dfbce3 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 6894337b2ff30c22c39fee937d31b1981be1dece..143c8de462e64b30604a50f60c5c8b716de98464 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 7b805310e09cad30cc26328365e8bb24e9c063f4..b0af9d91d27e60477646947be7ca76f8dd704d40 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 e77f9d26e44adc88b908cc97c77297db1b015b18..df1a4b114448f5db6850fe3af2dc087e72692f4b 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 401c642481efc293774d6f82c32d66824918e242..7c875817b40a17f223df3aec69c1e85bffecb7f6 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 4a6f78cbc62772350ae9106632445ab32f0b13b0..7e4e1fd9fcf68f73a95219ffaf592830e3165d7a 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 087bb7fd47fcd27c4f660b66681a7fc233aae15a..b58293d8a35bf89c41225a144af73b5ffc130741 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 5f6cc48f1ccaf0682395314554f6f948b873bdaa..61fd9ca6f37f4b3efe816102bfe090b5437aed42 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 398fe7e1c3e00c87c46b15e916d9f4e746eaf807..98c24c94ffed23516b7bca97ab2984d71a22e9f3 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 5643a9df7496d2230c427741d627a7def0f367a4..fe3a659c963a6f89aa9d8ba027e447a9c0058bc7 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 a99ebd5449bcf3f91e1939befb018ffd3ad2e91b..113dc147e79d03748fc988cfeaa7573243f46947 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 74d3b4df4073a53c34bbe0c56920b07783efdb28..0734b2cebc57fd8772305766fd63fbd7450f0b4c 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 a3276299e498b6d8c7cbcc0d684eb12c78a46a43..2f693bb3daf726bfef0f10459f240ae5684c83b9 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 589294ff7a8f213ca9f011df9ef56d33b06328c9..34c5d65dbe8c2f1851e3c39dca00e17dda348b55 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 0c1ca1aba5f351045dd53eca0aa08a7d74997076..e38b5294dbb3216ef91f756830e019578f1575ad 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 01837efd60460c62b43887eda23f4ef371c4ac3f..38042069122072d7fe78fb16f351e89d69fc0e6e 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 e91219cfd5634f0d5bc9cf248e503a4084022b59..acb1814bcc3efc991c5ff0e455861a22e60ef821 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 5ecb6d8370d5010283840609c5b8c835e1941579..042c83efb4c253c6105a06893c29a701b3870d4c 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 8745f7eb5b7ec02b4eab886519d981c0ac4a842c..bbdfacdc0a5cb25e36d88f9cd8bbcdc267d8db48 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);