From 53a7698da79832cf080a3e7d6a48ac5d0a5c89a7 Mon Sep 17 00:00:00 2001 From: Anatoly Sokolov Date: Sun, 2 May 2010 10:49:10 +0000 Subject: * target.h (struct calls): Add function_value_regno_p field. * target-def.h (TARGET_FUNCTION_VALUE_REGNO_P): Define. (TARGET_INITIALIZER): Use TARGET_FUNCTION_VALUE_REGNO_P. * targhooks.c (default_function_value_regno_p): New function. * targhooks.h (default_function_value_regno_p): Declare function. * rtlanal.c (keep_with_call_p): Use function_value_regno_p hook. * builtins.c. (apply_result_size): (Ditto.). * combine.c. (likely_spilled_retval_p): (Ditto.). * mode-switching.c. Include 'target.h'. (create_pre_exit): Use function_value_regno_p hook. * Makefile.in (mode-switching.o): Add dependency on TARGET_H. * doc/tm.texi (FUNCTION_VALUE_REGNO_P, TARGET_FUNCTION_VALUE_REGNO_P): Revise documentation. * config/i386/i386.h (TARGET_FUNCTION_VALUE_REGNO_P): Remove macro. * config/i386/i386.c (TARGET_FUNCTION_VALUE_REGNO_P): Define macro. (ix86_function_value_regno_p): Declare as static, change argument type to const unsigned int. * config/i386/i386-protos.h (ix86_function_value_regno_p): Remove. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@158970 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 22 ++++++++++++++++++++++ gcc/Makefile.in | 2 +- gcc/builtins.c | 2 +- gcc/combine.c | 4 ++-- gcc/config/i386/i386-protos.h | 1 - gcc/config/i386/i386.c | 8 ++++++-- gcc/config/i386/i386.h | 2 -- gcc/doc/tm.texi | 18 ++++++++++++++++++ gcc/mode-switching.c | 6 ++++-- gcc/rtlanal.c | 2 +- gcc/target-def.h | 2 ++ gcc/target.h | 4 ++++ gcc/targhooks.c | 12 ++++++++++++ gcc/targhooks.h | 1 + 14 files changed, 74 insertions(+), 12 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7f636b3c908..d0122024500 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2010-05-01 Anatoly Sokolov + + * target.h (struct calls): Add function_value_regno_p field. + * target-def.h (TARGET_FUNCTION_VALUE_REGNO_P): Define. + (TARGET_INITIALIZER): Use TARGET_FUNCTION_VALUE_REGNO_P. + * targhooks.c (default_function_value_regno_p): New function. + * targhooks.h (default_function_value_regno_p): Declare function. + * rtlanal.c (keep_with_call_p): Use function_value_regno_p hook. + * builtins.c. (apply_result_size): (Ditto.). + * combine.c. (likely_spilled_retval_p): (Ditto.). + * mode-switching.c. Include 'target.h'. + (create_pre_exit): Use function_value_regno_p hook. + * Makefile.in (mode-switching.o): Add dependency on TARGET_H. + * doc/tm.texi (FUNCTION_VALUE_REGNO_P, + TARGET_FUNCTION_VALUE_REGNO_P): Revise documentation. + + * config/i386/i386.h (TARGET_FUNCTION_VALUE_REGNO_P): Remove macro. + * config/i386/i386.c (TARGET_FUNCTION_VALUE_REGNO_P): Define macro. + (ix86_function_value_regno_p): Declare as static, change argument + type to const unsigned int. + * config/i386/i386-protos.h (ix86_function_value_regno_p): Remove. + 2010-05-01 Richard Guenther PR tree-optimization/43949 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 48f2c618ea5..95185da5354 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2991,7 +2991,7 @@ lcm.o : lcm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \ mode-switching.o : mode-switching.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ $(INSN_ATTR_H) $(RECOG_H) $(BASIC_BLOCK_H) $(TM_P_H) $(FUNCTION_H) \ - output.h $(TREE_PASS_H) $(TIMEVAR_H) $(REAL_H) $(DF_H) + output.h $(TREE_PASS_H) $(TIMEVAR_H) $(REAL_H) $(DF_H) $(TARGET_H) tree-ssa-dce.o : tree-ssa-dce.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ $(RTL_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) \ coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(FLAGS_H) $(BASIC_BLOCK_H) \ diff --git a/gcc/builtins.c b/gcc/builtins.c index b514ae03b41..5f4b7176155 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -1322,7 +1322,7 @@ apply_result_size (void) size = 0; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - if (FUNCTION_VALUE_REGNO_P (regno)) + if (targetm.calls.function_value_regno_p (regno)) { mode = reg_raw_mode[regno]; diff --git a/gcc/combine.c b/gcc/combine.c index 0c934457d26..303f180f790 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -2076,14 +2076,14 @@ likely_spilled_retval_p (rtx insn) unsigned regno, nregs; /* We assume here that no machine mode needs more than 32 hard registers when the value overlaps with a register - for which FUNCTION_VALUE_REGNO_P is true. */ + for which TARGET_FUNCTION_VALUE_REGNO_P is true. */ unsigned mask; struct likely_spilled_retval_info info; if (!NONJUMP_INSN_P (use) || GET_CODE (PATTERN (use)) != USE || insn == use) return 0; reg = XEXP (PATTERN (use), 0); - if (!REG_P (reg) || !FUNCTION_VALUE_REGNO_P (REGNO (reg))) + if (!REG_P (reg) || !targetm.calls.function_value_regno_p (REGNO (reg))) return 0; regno = REGNO (reg); nregs = hard_regno_nregs[regno][GET_MODE (reg)]; diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 5c6140d88a0..48695c080b1 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -136,7 +136,6 @@ extern int ix86_attr_length_vex_default (rtx, int, int); extern enum machine_mode ix86_fp_compare_mode (enum rtx_code); extern rtx ix86_libcall_value (enum machine_mode); -extern bool ix86_function_value_regno_p (int); extern bool ix86_function_arg_regno_p (int); extern int ix86_function_arg_boundary (enum machine_mode, tree); extern bool ix86_sol10_return_in_memory (const_tree,const_tree); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 63545c807c8..61a619bed2a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1880,6 +1880,7 @@ static bool ext_80387_constants_init = 0; static struct machine_function * ix86_init_machine_status (void); static rtx ix86_function_value (const_tree, const_tree, bool); +static bool ix86_function_value_regno_p (const unsigned int); static rtx ix86_static_chain (const_tree, bool); static int ix86_function_regparm (const_tree, const_tree); static void ix86_compute_frame_layout (struct ix86_frame *); @@ -6331,8 +6332,8 @@ ix86_function_arg_boundary (enum machine_mode mode, tree type) /* Return true if N is a possible register number of function value. */ -bool -ix86_function_value_regno_p (int regno) +static bool +ix86_function_value_regno_p (const unsigned int regno) { switch (regno) { @@ -30656,6 +30657,9 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree) #undef TARGET_FUNCTION_VALUE #define TARGET_FUNCTION_VALUE ix86_function_value +#undef TARGET_FUNCTION_VALUE_REGNO_P +#define TARGET_FUNCTION_VALUE_REGNO_P ix86_function_value_regno_p + #undef TARGET_SECONDARY_RELOAD #define TARGET_SECONDARY_RELOAD ix86_secondary_reload diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 9be3eb8cae8..ebe32388d80 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1554,8 +1554,6 @@ enum reg_class #define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) \ ix86_return_pops_args ((FUNDECL), (FUNTYPE), (SIZE)) -#define FUNCTION_VALUE_REGNO_P(N) ix86_function_value_regno_p (N) - /* Define how to find the value returned by a library function assuming the value has mode MODE. */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 6582ab1cd91..a20d48c9f9c 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -4461,8 +4461,26 @@ suffices: If the machine has register windows, so that the caller and the called function use different registers for the return value, this macro should recognize only the caller's register numbers. + +This macro has been deprecated. Use @code{TARGET_FUNCTION_VALUE_REGNO_P} +for a new target instead. @end defmac +@deftypefn {Target Hook} bool TARGET_FUNCTION_VALUE_REGNO_P (const unsigned int @var{regno}) +A target hook that return @code{true} if @var{regno} is the number of a hard +register in which the values of called function may come back. + +A register whose use for returning values is limited to serving as the +second of a pair (for a value of type @code{double}, say) need not be +recognized by this target hook. + +If the machine has register windows, so that the caller and the called +function use different registers for the return value, this target hook +should recognize only the caller's register numbers. + +If this hook is not defined, then FUNCTION_VALUE_REGNO_P will be used. +@end deftypefn + @defmac TARGET_ENUM_VA_LIST (@var{idx}, @var{pname}, @var{ptype}) This target macro is used in function @code{c_common_nodes_and_builtins} to iterate through the target specific builtin types for va_list. The diff --git a/gcc/mode-switching.c b/gcc/mode-switching.c index 140c513918e..30051c6ea24 100644 --- a/gcc/mode-switching.c +++ b/gcc/mode-switching.c @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "tm.h" +#include "target.h" #include "rtl.h" #include "regs.h" #include "hard-reg-set.h" @@ -262,7 +263,7 @@ create_pre_exit (int n_entities, int *entity_map, const int *num_modes) case USE: /* Skip __builtin_apply pattern. */ if (GET_CODE (XEXP (return_copy_pat, 0)) == REG - && (FUNCTION_VALUE_REGNO_P + && (targetm.calls.function_value_regno_p (REGNO (XEXP (return_copy_pat, 0))))) { maybe_builtin_apply = 1; @@ -359,7 +360,8 @@ create_pre_exit (int n_entities, int *entity_map, const int *num_modes) && copy_start + copy_num <= ret_end) nregs -= copy_num; else if (!maybe_builtin_apply - || !FUNCTION_VALUE_REGNO_P (copy_start)) + || !targetm.calls.function_value_regno_p + (copy_start)) break; last_insn = return_copy; } diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 0e3b77bc0c9..8a5df24632d 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -3474,7 +3474,7 @@ keep_with_call_p (const_rtx insn) && general_operand (SET_SRC (set), VOIDmode)) return true; if (REG_P (SET_SRC (set)) - && FUNCTION_VALUE_REGNO_P (REGNO (SET_SRC (set))) + && targetm.calls.function_value_regno_p (REGNO (SET_SRC (set))) && REG_P (SET_DEST (set)) && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER) return true; diff --git a/gcc/target-def.h b/gcc/target-def.h index d0566650cf7..feca6c5270c 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -661,6 +661,7 @@ #define TARGET_FUNCTION_VALUE default_function_value #define TARGET_LIBCALL_VALUE default_libcall_value +#define TARGET_FUNCTION_VALUE_REGNO_P default_function_value_regno_p #define TARGET_INTERNAL_ARG_POINTER default_internal_arg_pointer #define TARGET_UPDATE_STACK_BOUNDARY NULL #define TARGET_GET_DRAP_RTX NULL @@ -687,6 +688,7 @@ TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN, \ TARGET_FUNCTION_VALUE, \ TARGET_LIBCALL_VALUE, \ + TARGET_FUNCTION_VALUE_REGNO_P, \ TARGET_INTERNAL_ARG_POINTER, \ TARGET_UPDATE_STACK_BOUNDARY, \ TARGET_GET_DRAP_RTX, \ diff --git a/gcc/target.h b/gcc/target.h index 7729525512d..62a1bcc3d7e 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -968,6 +968,10 @@ struct gcc_target calling the function FN_NAME. */ rtx (*libcall_value) (enum machine_mode, const_rtx); + /* Return true if REGNO is a possible register number for + a function value as seen by the caller. */ + bool (*function_value_regno_p) (const unsigned int); + /* Return an rtx for the argument pointer incoming to the current function. */ rtx (*internal_arg_pointer) (void); diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 00fa5024fa1..8df0de421f8 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -619,6 +619,18 @@ default_libcall_value (enum machine_mode mode ATTRIBUTE_UNUSED, #endif } +/* The default hook for TARGET_FUNCTION_VALUE_REGNO_P. */ + +bool +default_function_value_regno_p (const unsigned int regno ATTRIBUTE_UNUSED) +{ +#ifdef FUNCTION_VALUE_REGNO_P + return FUNCTION_VALUE_REGNO_P (regno); +#else + gcc_unreachable (); +#endif +} + rtx default_internal_arg_pointer (void) { diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 209ed79b0c8..e70eef4d555 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -99,6 +99,7 @@ extern const char *hook_invalid_arg_for_unprototyped_fn extern bool hook_bool_const_rtx_commutative_p (const_rtx, int); extern rtx default_function_value (const_tree, const_tree, bool); extern rtx default_libcall_value (enum machine_mode, const_rtx); +extern bool default_function_value_regno_p (const unsigned int); extern rtx default_internal_arg_pointer (void); extern rtx default_static_chain (const_tree, bool); extern void default_trampoline_init (rtx, tree, rtx); -- cgit v1.2.3