From cd90919ddf67bf946228a11ba0cf0c7402dda3fe Mon Sep 17 00:00:00 2001 From: aesok Date: Tue, 25 Aug 2009 21:09:00 +0000 Subject: [PATCH] * hooks.h (hook_bool_const_int_const_int_true): Declare. * hooks.c (hook_bool_const_int_const_int_true): New function. * target.h (struct gcc_target): Add can_eliminate field. * target-def.h (TARGET_CAN_ELIMINATE): Define. (TARGET_INITIALIZER): Use TARGET_CAN_ELIMINATE. * ira.c (setup_eliminable_regset): Use can_eliminate target hook. * reload1.c (update_eliminables, init_elim_table): (Ditto.). (elim_table): Revise comment. * system.h (CAN_ELIMINATE): Poison. * defaults.h (CAN_ELIMINATE): Remove. * doc/tm.texi (CAN_ELIMINATE): Revise documentation. * config/alpha/vms.h (CAN_ELIMINATE): Remove macro. * config/alpha/alpha.c (TARGET_CAN_ELIMINATE) [TARGET_ABI_OPEN_VMS]: Define macro. (alpha_vms_can_eliminate): Declare as static, change return type to bool. * config/alpha/alpha-protos.h (alpha_vms_can_eliminate): Remove. * config/arm/arm.h (CAN_ELIMINATE): Remove macro. * config/arm/arm.c (TARGET_CAN_ELIMINATE): Define macro. (arm_can_eliminate): New function. * config/avr/avr.h (CAN_ELIMINATE): Remove macro. * config/avr/avr.c (TARGET_CAN_ELIMINATE): Define macro. (avr_can_eliminate): Declare as static. * config/avr/avr-protos.h (avr_can_eliminate): Remove. * config/bfin/bfin.h (CAN_ELIMINATE): Remove macro. * config/bfin/bfin.c (TARGET_CAN_ELIMINATE): Define macro. (bfin_can_eliminate): New function. * config/crx/crx.h (CAN_ELIMINATE): Remove macro. * config/crx/crx.c (TARGET_CAN_ELIMINATE): Define macro. (crx_can_eliminate): New function. * config/fr30/fr30.h (CAN_ELIMINATE): Remove macro. * config/fr30/fr30.c (TARGET_CAN_ELIMINATE): Define macro. (fr30_can_eliminate): New function. * config/frv/frv.h (CAN_ELIMINATE): Remove macro. * config/frv/frv.c (TARGET_CAN_ELIMINATE): Define macro. (frv_can_eliminate): New function. * config/h8300/h8300.h (CAN_ELIMINATE): Remove macro. * config/h8300/h8300.c (TARGET_CAN_ELIMINATE): Define macro. (h8300_can_eliminate): New function. * config/i386/i386.h (CAN_ELIMINATE): Remove macro. * config/i386/i386.c (TARGET_CAN_ELIMINATE): Define macro. (i386_can_eliminate): Declare as static, change return type to bool. * config/i386/i386-protos.h (i386_can_eliminate): Remove. * config/ia64/ia64.h (CAN_ELIMINATE): Remove macro. * config/ia64/ia64.c (TARGET_CAN_ELIMINATE): Define macro. (ia64_can_eliminate): New function. * config/iq2000/iq2000.h (CAN_ELIMINATE): Remove macro. * config/iq2000/iq2000.c (TARGET_CAN_ELIMINATE): Define macro. (iq2000_can_eliminate): New function. * config/m32r/m32r.h (CAN_ELIMINATE): Remove macro. * config/m32r/m32r.c (TARGET_CAN_ELIMINATE): Define macro. (m32r_can_eliminate): New function. * config/m68hc11/m68hc11.h (CAN_ELIMINATE): Remove macro. * config/m68hc11/m68hc11.c (TARGET_CAN_ELIMINATE): Define macro. (m68hc11_can_eliminate): New function. * config/m68k/m68k.h (CAN_ELIMINATE): Remove macro. * config/m68k/m68k.c (TARGET_CAN_ELIMINATE): Define macro. (m68k_can_eliminate): New function. * config/mep/mep.h (CAN_ELIMINATE): Remove macro. * config/mep/mep.c (TARGET_CAN_ELIMINATE): Define macro. (mep_can_eliminate): New function. * config/mips/mips.h (CAN_ELIMINATE): Remove macro. * config/mips/mips.c (TARGET_CAN_ELIMINATE): Define macro. (mips_can_eliminate): New function. * config/rs6000/rs6000.h (CAN_ELIMINATE): Remove macro. * config/rs6000/rs6000.c (TARGET_CAN_ELIMINATE): Define macro. (rs6000_can_eliminate): New function. * config/s390/s390.h (CAN_ELIMINATE): Remove macro. * config/s390/s390.c (TARGET_CAN_ELIMINATE): Define macro. (s390_can_eliminate): Declare as static. * config/s390/s390-protos.h (sparc_can_eliminate): Remove. * config/score/score.h (CAN_ELIMINATE): Remove macro. * config/score/score.c (TARGET_CAN_ELIMINATE): Define macro. (score_can_eliminate): New function. * config/sparc/sparc.h (CAN_ELIMINATE): Remove macro. * config/sparc/sparc.c (TARGET_CAN_ELIMINATE): Define macro. (sparc_can_eliminate): Declare as static. * config/sparc/sparc-protos.h (sparc_can_eliminate): Remove. * config/stormy16/stormy16.h (CAN_ELIMINATE): Remove macro. * config/stormy16/stormy16.c (TARGET_CAN_ELIMINATE): Define macro. (xstormy16_can_eliminate): New function. * config/v850/v850.h (CAN_ELIMINATE): Remove macro. * config/v850/v850.c (TARGET_CAN_ELIMINATE): Define macro. (v850_can_eliminate): New function. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151096 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 109 ++++++++++++++++++++++++++++++++++++++++ gcc/config/alpha/alpha-protos.h | 1 - gcc/config/alpha/alpha.c | 8 ++- gcc/config/alpha/vms.h | 4 -- gcc/config/arm/arm.c | 22 ++++++++ gcc/config/arm/arm.h | 15 ------ gcc/config/avr/avr-protos.h | 1 - gcc/config/avr/avr.c | 5 +- gcc/config/avr/avr.h | 2 - gcc/config/bfin/bfin.c | 14 ++++++ gcc/config/bfin/bfin.h | 8 --- gcc/config/crx/crx.c | 12 +++++ gcc/config/crx/crx.h | 3 -- gcc/config/fr30/fr30.c | 13 +++++ gcc/config/fr30/fr30.h | 9 ---- gcc/config/frv/frv.c | 14 ++++++ gcc/config/frv/frv.h | 11 ---- gcc/config/h8300/h8300.c | 17 +++++++ gcc/config/h8300/h8300.h | 13 +---- gcc/config/i386/i386-protos.h | 1 - gcc/config/i386/i386.c | 9 ++-- gcc/config/i386/i386.h | 5 -- gcc/config/ia64/ia64.c | 15 +++++- gcc/config/ia64/ia64.h | 11 +--- gcc/config/iq2000/iq2000.c | 22 +++++++- gcc/config/iq2000/iq2000.h | 13 +---- gcc/config/m32r/m32r.c | 15 ++++++ gcc/config/m32r/m32r.h | 12 ----- gcc/config/m68hc11/m68hc11.c | 17 +++++++ gcc/config/m68hc11/m68hc11.h | 13 +---- gcc/config/m68k/m68k.c | 12 +++++ gcc/config/m68k/m68k.h | 6 +-- gcc/config/mep/mep.c | 13 +++++ gcc/config/mep/mep.h | 5 -- gcc/config/mips/mips.c | 12 +++++ gcc/config/mips/mips.h | 5 -- gcc/config/rs6000/rs6000.c | 24 +++++++++ gcc/config/rs6000/rs6000.h | 16 ------ gcc/config/s390/s390-protos.h | 5 +- gcc/config/s390/s390.c | 7 ++- gcc/config/s390/s390.h | 3 -- gcc/config/score/score.c | 15 +++++- gcc/config/score/score.h | 7 --- gcc/config/sparc/sparc-protos.h | 1 - gcc/config/sparc/sparc.c | 4 ++ gcc/config/sparc/sparc.h | 6 --- gcc/config/stormy16/stormy16.c | 13 +++++ gcc/config/stormy16/stormy16.h | 7 +-- gcc/config/v850/v850.c | 12 +++++ gcc/config/v850/v850.h | 12 +---- gcc/defaults.h | 4 -- gcc/doc/tm.texi | 12 ++--- gcc/hooks.c | 7 +++ gcc/hooks.h | 1 + gcc/ira.c | 2 +- gcc/reload1.c | 9 ++-- gcc/system.h | 3 +- gcc/target-def.h | 5 ++ gcc/target.h | 4 ++ 59 files changed, 435 insertions(+), 211 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 277d6a210e7..4d4a8e659f0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,112 @@ +2009-08-25 Anatoly Sokolov + + * hooks.h (hook_bool_const_int_const_int_true): Declare. + * hooks.c (hook_bool_const_int_const_int_true): New function. + * target.h (struct gcc_target): Add can_eliminate field. + * target-def.h (TARGET_CAN_ELIMINATE): Define. + (TARGET_INITIALIZER): Use TARGET_CAN_ELIMINATE. + * ira.c (setup_eliminable_regset): Use can_eliminate target hook. + * reload1.c (update_eliminables, init_elim_table): (Ditto.). + (elim_table): Revise comment. + * system.h (CAN_ELIMINATE): Poison. + * defaults.h (CAN_ELIMINATE): Remove. + * doc/tm.texi (CAN_ELIMINATE): Revise documentation. + + * config/alpha/vms.h (CAN_ELIMINATE): Remove macro. + * config/alpha/alpha.c (TARGET_CAN_ELIMINATE) [TARGET_ABI_OPEN_VMS]: + Define macro. + (alpha_vms_can_eliminate): Declare as static, change return type to + bool. + * config/alpha/alpha-protos.h (alpha_vms_can_eliminate): Remove. + + * config/arm/arm.h (CAN_ELIMINATE): Remove macro. + * config/arm/arm.c (TARGET_CAN_ELIMINATE): Define macro. + (arm_can_eliminate): New function. + + * config/avr/avr.h (CAN_ELIMINATE): Remove macro. + * config/avr/avr.c (TARGET_CAN_ELIMINATE): Define macro. + (avr_can_eliminate): Declare as static. + * config/avr/avr-protos.h (avr_can_eliminate): Remove. + + * config/bfin/bfin.h (CAN_ELIMINATE): Remove macro. + * config/bfin/bfin.c (TARGET_CAN_ELIMINATE): Define macro. + (bfin_can_eliminate): New function. + + * config/crx/crx.h (CAN_ELIMINATE): Remove macro. + * config/crx/crx.c (TARGET_CAN_ELIMINATE): Define macro. + (crx_can_eliminate): New function. + + * config/fr30/fr30.h (CAN_ELIMINATE): Remove macro. + * config/fr30/fr30.c (TARGET_CAN_ELIMINATE): Define macro. + (fr30_can_eliminate): New function. + + * config/frv/frv.h (CAN_ELIMINATE): Remove macro. + * config/frv/frv.c (TARGET_CAN_ELIMINATE): Define macro. + (frv_can_eliminate): New function. + + * config/h8300/h8300.h (CAN_ELIMINATE): Remove macro. + * config/h8300/h8300.c (TARGET_CAN_ELIMINATE): Define macro. + (h8300_can_eliminate): New function. + + * config/i386/i386.h (CAN_ELIMINATE): Remove macro. + * config/i386/i386.c (TARGET_CAN_ELIMINATE): Define macro. + (i386_can_eliminate): Declare as static, change return type to bool. + * config/i386/i386-protos.h (i386_can_eliminate): Remove. + + * config/ia64/ia64.h (CAN_ELIMINATE): Remove macro. + * config/ia64/ia64.c (TARGET_CAN_ELIMINATE): Define macro. + (ia64_can_eliminate): New function. + + * config/iq2000/iq2000.h (CAN_ELIMINATE): Remove macro. + * config/iq2000/iq2000.c (TARGET_CAN_ELIMINATE): Define macro. + (iq2000_can_eliminate): New function. + + * config/m32r/m32r.h (CAN_ELIMINATE): Remove macro. + * config/m32r/m32r.c (TARGET_CAN_ELIMINATE): Define macro. + (m32r_can_eliminate): New function. + + * config/m68hc11/m68hc11.h (CAN_ELIMINATE): Remove macro. + * config/m68hc11/m68hc11.c (TARGET_CAN_ELIMINATE): Define macro. + (m68hc11_can_eliminate): New function. + + * config/m68k/m68k.h (CAN_ELIMINATE): Remove macro. + * config/m68k/m68k.c (TARGET_CAN_ELIMINATE): Define macro. + (m68k_can_eliminate): New function. + + * config/mep/mep.h (CAN_ELIMINATE): Remove macro. + * config/mep/mep.c (TARGET_CAN_ELIMINATE): Define macro. + (mep_can_eliminate): New function. + + * config/mips/mips.h (CAN_ELIMINATE): Remove macro. + * config/mips/mips.c (TARGET_CAN_ELIMINATE): Define macro. + (mips_can_eliminate): New function. + + * config/rs6000/rs6000.h (CAN_ELIMINATE): Remove macro. + * config/rs6000/rs6000.c (TARGET_CAN_ELIMINATE): Define macro. + (rs6000_can_eliminate): New function. + + * config/s390/s390.h (CAN_ELIMINATE): Remove macro. + * config/s390/s390.c (TARGET_CAN_ELIMINATE): Define macro. + (s390_can_eliminate): Declare as static. + * config/s390/s390-protos.h (sparc_can_eliminate): Remove. + + * config/score/score.h (CAN_ELIMINATE): Remove macro. + * config/score/score.c (TARGET_CAN_ELIMINATE): Define macro. + (score_can_eliminate): New function. + + * config/sparc/sparc.h (CAN_ELIMINATE): Remove macro. + * config/sparc/sparc.c (TARGET_CAN_ELIMINATE): Define macro. + (sparc_can_eliminate): Declare as static. + * config/sparc/sparc-protos.h (sparc_can_eliminate): Remove. + + * config/stormy16/stormy16.h (CAN_ELIMINATE): Remove macro. + * config/stormy16/stormy16.c (TARGET_CAN_ELIMINATE): Define macro. + (xstormy16_can_eliminate): New function. + + * config/v850/v850.h (CAN_ELIMINATE): Remove macro. + * config/v850/v850.c (TARGET_CAN_ELIMINATE): Define macro. + (v850_can_eliminate): New function. + 2009-08-25 Uros Bizjak * config/alpha/alpha.md (*cmpdf_ieee_ext[123]): Remove. diff --git a/gcc/config/alpha/alpha-protos.h b/gcc/config/alpha/alpha-protos.h index 43665d3af20..7e9d14b5f4b 100644 --- a/gcc/config/alpha/alpha-protos.h +++ b/gcc/config/alpha/alpha-protos.h @@ -114,7 +114,6 @@ extern void avms_asm_output_external (FILE *, tree, const char *); extern void vms_output_aligned_decl_common (FILE *, tree, const char *, unsigned HOST_WIDE_INT, unsigned int); -extern int alpha_vms_can_eliminate (unsigned int, unsigned int); extern HOST_WIDE_INT alpha_vms_initial_elimination_offset (unsigned int, unsigned int); #endif diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 08de3636536..1c15e53f996 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -7483,8 +7483,10 @@ alpha_initial_elimination_offset (unsigned int from, #if TARGET_ABI_OPEN_VMS -int -alpha_vms_can_eliminate (unsigned int from ATTRIBUTE_UNUSED, unsigned int to) +/* Worker function for TARGET_CAN_ELIMINATE. */ + +static bool +alpha_vms_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) { /* We need the alpha_procedure_type to decide. Evaluate it now. */ alpha_sa_size (); @@ -10983,6 +10985,8 @@ alpha_init_libfuncs (void) #if TARGET_ABI_OPEN_VMS # undef TARGET_ATTRIBUTE_TABLE # define TARGET_ATTRIBUTE_TABLE vms_attribute_table +# undef TARGET_CAN_ELIMINATE +# define TARGET_CAN_ELIMINATE alpha_vms_can_eliminate #endif #undef TARGET_IN_SMALL_DATA_P diff --git a/gcc/config/alpha/vms.h b/gcc/config/alpha/vms.h index e3781b57163..cb84a040eee 100644 --- a/gcc/config/alpha/vms.h +++ b/gcc/config/alpha/vms.h @@ -142,10 +142,6 @@ along with GCC; see the file COPYING3. If not see #undef EPILOGUE_USES #define EPILOGUE_USES(REGNO) ((REGNO) == 26 || (REGNO) == 29) -#undef CAN_ELIMINATE -#define CAN_ELIMINATE(FROM, TO) \ - (alpha_vms_can_eliminate ((FROM), (TO))) - #undef INITIAL_ELIMINATION_OFFSET #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ ((OFFSET) = alpha_vms_initial_elimination_offset(FROM, TO)) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 1ac6510312c..1cc9557361a 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -218,6 +218,7 @@ static tree arm_promoted_type (const_tree t); static tree arm_convert_to_type (tree type, tree expr); static bool arm_scalar_mode_supported_p (enum machine_mode); static bool arm_frame_pointer_required (void); +static bool arm_can_eliminate (const int, const int); /* Table of machine attributes. */ @@ -485,6 +486,9 @@ static const struct attribute_spec arm_attribute_table[] = #undef TARGET_FRAME_POINTER_REQUIRED #define TARGET_FRAME_POINTER_REQUIRED arm_frame_pointer_required +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE arm_can_eliminate + struct gcc_target targetm = TARGET_INITIALIZER; /* Obstack for minipool constant handling. */ @@ -14065,6 +14069,24 @@ arm_compute_initial_elimination_offset (unsigned int from, unsigned int to) } } +/* Given FROM and TO register numbers, say whether this elimination is + allowed. Frame pointer elimination is automatically handled. + + All eliminations are permissible. Note that ARG_POINTER_REGNUM and + HARD_FRAME_POINTER_REGNUM are in fact the same thing. If we need a frame + pointer, we must eliminate FRAME_POINTER_REGNUM into + HARD_FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM or + ARG_POINTER_REGNUM. */ + +bool +arm_can_eliminate (const int from, const int to) +{ + return ((to == FRAME_POINTER_REGNUM && from == ARG_POINTER_REGNUM) ? false : + (to == STACK_POINTER_REGNUM && frame_pointer_needed) ? false : + (to == ARM_HARD_FRAME_POINTER_REGNUM && TARGET_THUMB) ? false : + (to == THUMB_HARD_FRAME_POINTER_REGNUM && TARGET_ARM) ? false : + true); +} /* Emit RTL to save coprocessor registers on function entry. Returns the number of bytes pushed. */ diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index c84d58bbcb0..ae32da563e1 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1846,21 +1846,6 @@ typedef struct { FRAME_POINTER_REGNUM, ARM_HARD_FRAME_POINTER_REGNUM },\ { FRAME_POINTER_REGNUM, THUMB_HARD_FRAME_POINTER_REGNUM }} -/* Given FROM and TO register numbers, say whether this elimination is - allowed. Frame pointer elimination is automatically handled. - - All eliminations are permissible. Note that ARG_POINTER_REGNUM and - HARD_FRAME_POINTER_REGNUM are in fact the same thing. If we need a frame - pointer, we must eliminate FRAME_POINTER_REGNUM into - HARD_FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM or - ARG_POINTER_REGNUM. */ -#define CAN_ELIMINATE(FROM, TO) \ - (((TO) == FRAME_POINTER_REGNUM && (FROM) == ARG_POINTER_REGNUM) ? 0 : \ - ((TO) == STACK_POINTER_REGNUM && frame_pointer_needed) ? 0 : \ - ((TO) == ARM_HARD_FRAME_POINTER_REGNUM && TARGET_THUMB) ? 0 : \ - ((TO) == THUMB_HARD_FRAME_POINTER_REGNUM && TARGET_ARM) ? 0 : \ - 1) - /* Define the offset between two registers, one to be eliminated, and the other its replacement, at the start of a routine. */ #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h index 719829d431f..c39b97be177 100644 --- a/gcc/config/avr/avr-protos.h +++ b/gcc/config/avr/avr-protos.h @@ -34,7 +34,6 @@ extern enum reg_class avr_reg_class_from_letter (int c); extern void asm_globalize_label (FILE *file, const char *name); extern void avr_asm_declare_function_name (FILE *, const char *, tree); extern void order_regs_for_local_alloc (void); -extern bool avr_can_eliminate (int, int); extern int avr_initial_elimination_offset (int from, int to); extern int avr_simple_epilogue (void); extern void gas_output_limited_string (FILE *file, const char *str); diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index d08d89fb697..2c562e9a18f 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -90,6 +90,7 @@ static rtx avr_builtin_setjmp_frame_value (void); static bool avr_hard_regno_scratch_ok (unsigned int); static unsigned int avr_case_values_threshold (void); static bool avr_frame_pointer_required_p (void); +static bool avr_can_eliminate (const int, const int); /* Allocate registers from r25 to r8 for parameters for function calls. */ #define FIRST_CUM_REG 26 @@ -191,6 +192,8 @@ static const struct attribute_spec avr_attribute_table[] = #undef TARGET_FRAME_POINTER_REQUIRED #define TARGET_FRAME_POINTER_REQUIRED avr_frame_pointer_required_p +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE avr_can_eliminate struct gcc_target targetm = TARGET_INITIALIZER; @@ -428,7 +431,7 @@ avr_regs_to_save (HARD_REG_SET *set) /* Return true if register FROM can be eliminated via register TO. */ bool -avr_can_eliminate (int from, int to) +avr_can_eliminate (const int from, const int to) { return ((from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM) || ((from == FRAME_POINTER_REGNUM diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index 7100ad17fe8..ff409398249 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -364,8 +364,6 @@ enum reg_class { {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \ ,{FRAME_POINTER_REGNUM+1,STACK_POINTER_REGNUM+1}} -#define CAN_ELIMINATE(FROM, TO) avr_can_eliminate (FROM, TO) - #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ OFFSET = avr_initial_elimination_offset (FROM, TO) diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index 13887480d1f..61da6db38eb 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -883,6 +883,17 @@ n_regs_saved_by_prologue (void) return n; } +/* Given FROM and TO register numbers, say whether this elimination is + allowed. Frame pointer elimination is automatically handled. + + All other eliminations are valid. */ + +static bool +bfin_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) +{ + return (to == STACK_POINTER_REGNUM ? ! frame_pointer_needed : true); +} + /* Return the offset between two registers, one to be eliminated, and the other its replacement, at the start of a routine. */ @@ -6338,4 +6349,7 @@ bfin_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED, #undef TARGET_FRAME_POINTER_REQUIRED #define TARGET_FRAME_POINTER_REQUIRED bfin_frame_pointer_required +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE bfin_can_eliminate + struct gcc_target targetm = TARGET_INITIALIZER; diff --git a/gcc/config/bfin/bfin.h b/gcc/config/bfin/bfin.h index a79420476c6..a9ff6fa8b47 100644 --- a/gcc/config/bfin/bfin.h +++ b/gcc/config/bfin/bfin.h @@ -376,14 +376,6 @@ extern const char *bfin_library_id_string; { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}} \ -/* Given FROM and TO register numbers, say whether this elimination is - allowed. Frame pointer elimination is automatically handled. - - All other eliminations are valid. */ - -#define CAN_ELIMINATE(FROM, TO) \ - ((TO) == STACK_POINTER_REGNUM ? ! frame_pointer_needed : 1) - /* Define the offset between two registers, one to be eliminated, and the other its replacement, at the start of a routine. */ diff --git a/gcc/config/crx/crx.c b/gcc/config/crx/crx.c index 4aa617fa28e..a0b43a4aa18 100644 --- a/gcc/config/crx/crx.c +++ b/gcc/config/crx/crx.c @@ -129,6 +129,7 @@ static rtx crx_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED, static bool crx_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED); static int crx_address_cost (rtx, bool); static bool crx_legitimate_address_p (enum machine_mode, rtx, bool); +static bool crx_can_eliminate (const int, const int); /*****************************************************************************/ /* RTL VALIDITY */ @@ -137,6 +138,9 @@ static bool crx_legitimate_address_p (enum machine_mode, rtx, bool); #undef TARGET_LEGITIMATE_ADDRESS_P #define TARGET_LEGITIMATE_ADDRESS_P crx_legitimate_address_p +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE crx_can_eliminate + /*****************************************************************************/ /* STACK LAYOUT AND CALLING CONVENTIONS */ /*****************************************************************************/ @@ -320,6 +324,14 @@ crx_compute_frame (void) crtl->outgoing_args_size : 0); } +/* Worker function for TARGET_CAN_ELIMINATE. */ + +bool +crx_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) +{ + return (to == STACK_POINTER_REGNUM ? ! frame_pointer_needed : true); +} + /* Implements the macro INITIAL_ELIMINATION_OFFSET, return the OFFSET. */ int diff --git a/gcc/config/crx/crx.h b/gcc/config/crx/crx.h index dcddaf03ecd..ed6d3d6edd2 100644 --- a/gcc/config/crx/crx.h +++ b/gcc/config/crx/crx.h @@ -298,9 +298,6 @@ enum reg_class { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \ } -#define CAN_ELIMINATE(FROM, TO) \ - ((TO) == STACK_POINTER_REGNUM ? ! frame_pointer_needed : 1) - #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ do { \ (OFFSET) = crx_initial_elimination_offset ((FROM), (TO)); \ diff --git a/gcc/config/fr30/fr30.c b/gcc/config/fr30/fr30.c index fc412eef8f0..431af8f63f9 100644 --- a/gcc/config/fr30/fr30.c +++ b/gcc/config/fr30/fr30.c @@ -120,6 +120,7 @@ static bool fr30_must_pass_in_stack (enum machine_mode, const_tree); static int fr30_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, tree, bool); static bool fr30_frame_pointer_required (void); +static bool fr30_can_eliminate (const int, const int); #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM)) #define RETURN_POINTER_MASK (1 << (RETURN_POINTER_REGNUM)) @@ -161,8 +162,20 @@ static bool fr30_frame_pointer_required (void); #undef TARGET_FRAME_POINTER_REQUIRED #define TARGET_FRAME_POINTER_REQUIRED fr30_frame_pointer_required +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE fr30_can_eliminate + struct gcc_target targetm = TARGET_INITIALIZER; + +/* Worker function for TARGET_CAN_ELIMINATE. */ + +bool +fr30_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) +{ + return (to == FRAME_POINTER_REGNUM || ! frame_pointer_needed); +} + /* Returns the number of bytes offset between FROM_REG and TO_REG for the current function. As a side effect it fills in the current_frame_info structure, if the data is available. */ diff --git a/gcc/config/fr30/fr30.h b/gcc/config/fr30/fr30.h index 9af74a97c14..f055a1a05dc 100644 --- a/gcc/config/fr30/fr30.h +++ b/gcc/config/fr30/fr30.h @@ -549,15 +549,6 @@ enum reg_class {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \ } -/* A C expression that returns nonzero if the compiler is allowed to try to - replace register number FROM with register number TO. This macro - need only be defined if `ELIMINABLE_REGS' is defined, and will usually be - the constant 1, since most of the cases preventing register elimination are - things that the compiler already knows about. */ - -#define CAN_ELIMINATE(FROM, TO) \ - ((TO) == FRAME_POINTER_REGNUM || ! frame_pointer_needed) - /* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the initial difference between the specified pair of registers. This macro must be defined if `ELIMINABLE_REGS' is defined. */ diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c index 658b5b4c275..63e65fb8bbf 100644 --- a/gcc/config/frv/frv.c +++ b/gcc/config/frv/frv.c @@ -382,6 +382,7 @@ static bool frv_secondary_reload (bool, rtx, enum reg_class, enum machine_mode, secondary_reload_info *); static bool frv_frame_pointer_required (void); +static bool frv_can_eliminate (const int, const int); /* Allow us to easily change the default for -malloc-cc. */ #ifndef DEFAULT_NO_ALLOC_CC @@ -475,6 +476,9 @@ static bool frv_frame_pointer_required (void); #undef TARGET_FRAME_POINTER_REQUIRED #define TARGET_FRAME_POINTER_REQUIRED frv_frame_pointer_required +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE frv_can_eliminate + struct gcc_target targetm = TARGET_INITIALIZER; #define FRV_SYMBOL_REF_TLS_P(RTX) \ @@ -2145,6 +2149,16 @@ frv_frame_pointer_required (void) } +/* Worker function for TARGET_CAN_ELIMINATE. */ + +bool +frv_can_eliminate (const int from, const int to) +{ + return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM + ? ! frame_pointer_needed + : true); +} + /* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the initial difference between the specified pair of registers. This macro must be defined if `ELIMINABLE_REGS' is defined. */ diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h index dfb3fb8eeb1..0516ecf2cac 100644 --- a/gcc/config/frv/frv.h +++ b/gcc/config/frv/frv.h @@ -1594,17 +1594,6 @@ typedef struct frv_stack { {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \ } -/* A C expression that returns nonzero if the compiler is allowed to try to - replace register number FROM with register number TO. This macro need only - be defined if `ELIMINABLE_REGS' is defined, and will usually be the constant - 1, since most of the cases preventing register elimination are things that - the compiler already knows about. */ - -#define CAN_ELIMINATE(FROM, TO) \ - ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM \ - ? ! frame_pointer_needed \ - : 1) - /* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the initial difference between the specified pair of registers. This macro must be defined if `ELIMINABLE_REGS' is defined. */ diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index c3dd29723fe..02b3ff6094a 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -1825,6 +1825,20 @@ h8300_expand_movsi (rtx operands[]) return 0; } +/* Given FROM and TO register numbers, say whether this elimination is allowed. + Frame pointer elimination is automatically handled. + + For the h8300, if frame pointer elimination is being done, we would like to + convert ap and rp into sp, not fp. + + All other eliminations are valid. */ + +static bool +h8300_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) +{ + return (to == STACK_POINTER_REGNUM ? ! frame_pointer_needed : true); +} + /* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET). Define the offset between two registers, one to be eliminated, and the other its replacement, at the start of a routine. */ @@ -5801,4 +5815,7 @@ h8300_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) #undef TARGET_DEFAULT_TARGET_FLAGS #define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE h8300_can_eliminate + struct gcc_target targetm = TARGET_INITIALIZER; diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h index dd95ed7253d..884e49a9d4a 100644 --- a/gcc/config/h8300/h8300.h +++ b/gcc/config/h8300/h8300.h @@ -1,7 +1,7 @@ /* Definitions of target machine for GNU compiler. Renesas H8/300 (generic) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008 + 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Steve Chamberlain (sac@cygnus.com), Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com). @@ -558,17 +558,6 @@ enum reg_class { { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} -/* Given FROM and TO register numbers, say whether this elimination is allowed. - Frame pointer elimination is automatically handled. - - For the h8300, if frame pointer elimination is being done, we would like to - convert ap and rp into sp, not fp. - - All other eliminations are valid. */ - -#define CAN_ELIMINATE(FROM, TO) \ - ((TO) == STACK_POINTER_REGNUM ? ! frame_pointer_needed : 1) - /* Define the offset between two registers, one to be eliminated, and the other its replacement, at the start of a routine. */ diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 324062ec7df..183352b73ba 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -28,7 +28,6 @@ extern int ix86_can_use_return_insn_p (void); extern void ix86_setup_frame_addresses (void); extern void ix86_file_end (void); -extern int ix86_can_eliminate (int, int); extern HOST_WIDE_INT ix86_initial_elimination_offset (int, int); extern void ix86_expand_prologue (void); extern void ix86_expand_epilogue (int); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 8b73fca0c6f..b761ab2545d 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -7794,8 +7794,8 @@ ix86_nsaved_sseregs (void) pointer. Otherwise, frame pointer elimination is automatically handled and all other eliminations are valid. */ -int -ix86_can_eliminate (int from, int to) +static bool +ix86_can_eliminate (const int from, const int to) { if (stack_realign_fp) return ((from == ARG_POINTER_REGNUM @@ -7803,7 +7803,7 @@ ix86_can_eliminate (int from, int to) || (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)); else - return to == STACK_POINTER_REGNUM ? !frame_pointer_needed : 1; + return to == STACK_POINTER_REGNUM ? !frame_pointer_needed : true; } /* Return the offset between two registers, one to be eliminated, and the other @@ -30664,6 +30664,9 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree) #undef TARGET_FRAME_POINTER_REQUIRED #define TARGET_FRAME_POINTER_REQUIRED ix86_frame_pointer_required +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE ix86_can_eliminate + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-i386.h" diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 15ac4d38247..88e310eccd4 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1684,11 +1684,6 @@ typedef struct ix86_args { { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} \ -/* Given FROM and TO register numbers, say whether this elimination is - allowed. */ - -#define CAN_ELIMINATE(FROM, TO) ix86_can_eliminate ((FROM), (TO)) - /* Define the offset between two registers, one to be eliminated, and the other its replacement, at the start of a routine. */ diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 42eec174c9e..85bca08d385 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -1,6 +1,7 @@ /* Definitions of target machine for GNU compiler. Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, - 2009 Free Software Foundation, Inc. + 2009 + Free Software Foundation, Inc. Contributed by James E. Wilson and David Mosberger . @@ -199,6 +200,7 @@ static rtx gen_movdi_x (rtx, rtx, rtx); static rtx gen_fr_spill_x (rtx, rtx, rtx); static rtx gen_fr_restore_x (rtx, rtx, rtx); +static bool ia64_can_eliminate (const int, const int); static enum machine_mode hfa_element_mode (const_tree, bool); static void ia64_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int); @@ -522,6 +524,9 @@ static const struct attribute_spec ia64_attribute_table[] = #undef TARGET_C_MODE_FOR_SUFFIX #define TARGET_C_MODE_FOR_SUFFIX ia64_c_mode_for_suffix +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE ia64_can_eliminate + struct gcc_target targetm = TARGET_INITIALIZER; typedef enum @@ -2639,6 +2644,14 @@ ia64_compute_frame_size (HOST_WIDE_INT size) current_frame_info.initialized = reload_completed; } +/* Worker function for TARGET_CAN_ELIMINATE. */ + +bool +ia64_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) +{ + return (to == BR_REG (0) ? current_function_is_leaf : true); +} + /* Compute the initial difference between the specified pair of registers. */ HOST_WIDE_INT diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index f91e63942f8..40c85501cda 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -1,6 +1,6 @@ /* Definitions of target machine GNU compiler. IA-64 version. - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 - Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, + 2009 Free Software Foundation, Inc. Contributed by James E. Wilson and David Mosberger . @@ -1027,13 +1027,6 @@ enum reg_class {FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ } -/* A C expression that returns nonzero if the compiler is allowed to try to - replace register number FROM with register number TO. The frame pointer - is automatically handled. */ - -#define CAN_ELIMINATE(FROM, TO) \ - (TO == BR_REG (0) ? current_function_is_leaf : 1) - /* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the initial difference between the specified pair of registers. This macro must be defined if `ELIMINABLE_REGS' is diff --git a/gcc/config/iq2000/iq2000.c b/gcc/config/iq2000/iq2000.c index ff0c868aaf2..85a8e5ac9f4 100644 --- a/gcc/config/iq2000/iq2000.c +++ b/gcc/config/iq2000/iq2000.c @@ -1,5 +1,5 @@ /* Subroutines used for code generation on Vitesse IQ2000 processors - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -165,6 +165,7 @@ static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, tree, bool); static void iq2000_va_start (tree, rtx); static bool iq2000_legitimate_address_p (enum machine_mode, rtx, bool); +static bool iq2000_can_eliminate (const int, const int); #undef TARGET_INIT_BUILTINS #define TARGET_INIT_BUILTINS iq2000_init_builtins @@ -214,6 +215,9 @@ static bool iq2000_legitimate_address_p (enum machine_mode, rtx, bool); #undef TARGET_LEGITIMATE_ADDRESS_P #define TARGET_LEGITIMATE_ADDRESS_P iq2000_legitimate_address_p +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE iq2000_can_eliminate + struct gcc_target targetm = TARGET_INITIALIZER; /* Return nonzero if we split the address into high and low parts. */ @@ -1678,6 +1682,22 @@ compute_frame_size (HOST_WIDE_INT size) return total_size; } + +/* We can always eliminate to the frame pointer. We can eliminate to the + stack pointer unless a frame pointer is needed. */ + +bool +iq2000_can_eliminate (const int from, const int to) +{ + return (from == RETURN_ADDRESS_POINTER_REGNUM + && (! leaf_function_p () + || (to == GP_REG_FIRST + 31 && leaf_function_p))) + || (from != RETURN_ADDRESS_POINTER_REGNUM + && (to == HARD_FRAME_POINTER_REGNUM + || (to == STACK_POINTER_REGNUM + && ! frame_pointer_needed))); +} + /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame pointer, argument pointer, or return address pointer. TO is either the stack pointer or hard frame pointer. */ diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h index c1506a4a1f1..43bacfdd28e 100644 --- a/gcc/config/iq2000/iq2000.h +++ b/gcc/config/iq2000/iq2000.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler. Vitesse IQ2000 processors - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -354,17 +354,6 @@ enum reg_class { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} - -/* We can always eliminate to the frame pointer. We can eliminate to the - stack pointer unless a frame pointer is needed. */ - -#define CAN_ELIMINATE(FROM, TO) \ - (((FROM) == RETURN_ADDRESS_POINTER_REGNUM && (! leaf_function_p () \ - || (TO == GP_REG_FIRST + 31 && leaf_function_p))) \ - || ((FROM) != RETURN_ADDRESS_POINTER_REGNUM \ - && ((TO) == HARD_FRAME_POINTER_REGNUM \ - || ((TO) == STACK_POINTER_REGNUM && ! frame_pointer_needed)))) - #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ (OFFSET) = iq2000_initial_elimination_offset ((FROM), (TO)) diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c index 372ede596c0..fdd89bc27a5 100644 --- a/gcc/config/m32r/m32r.c +++ b/gcc/config/m32r/m32r.c @@ -87,6 +87,7 @@ static bool m32r_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); static int m32r_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, tree, bool); +static bool m32r_can_eliminate (const int, const int); /* M32R specific attributes. */ @@ -151,6 +152,9 @@ static const struct attribute_spec m32r_attribute_table[] = #undef TARGET_ARG_PARTIAL_BYTES #define TARGET_ARG_PARTIAL_BYTES m32r_arg_partial_bytes +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE m32r_can_eliminate + struct gcc_target targetm = TARGET_INITIALIZER; /* Implement TARGET_HANDLE_OPTION. */ @@ -1472,6 +1476,17 @@ m32r_compute_frame_size (int size) /* # of var. bytes allocated. */ /* Ok, we're done. */ return total_size; } + +/* Worker function for TARGET_CAN_ELIMINATE. */ + +bool +m32r_can_eliminate (const int from, const int to) +{ + return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM + ? ! frame_pointer_needed + : true); +} + /* The table we use to reference PIC data. */ static rtx global_offset_table; diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h index 0ddbcfae263..da6a105247b 100644 --- a/gcc/config/m32r/m32r.h +++ b/gcc/config/m32r/m32r.h @@ -793,18 +793,6 @@ extern enum reg_class m32r_regno_reg_class[FIRST_PSEUDO_REGISTER]; { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }} -/* A C expression that returns nonzero if the compiler is allowed to - try to replace register number FROM-REG with register number - TO-REG. This macro need only be defined if `ELIMINABLE_REGS' is - defined, and will usually be the constant 1, since most of the - cases preventing register elimination are things that the compiler - already knows about. */ - -#define CAN_ELIMINATE(FROM, TO) \ - ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM \ - ? ! frame_pointer_needed \ - : 1) - /* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the initial difference between the specified pair of registers. This macro must be defined if `ELIMINABLE_REGS' is diff --git a/gcc/config/m68hc11/m68hc11.c b/gcc/config/m68hc11/m68hc11.c index 6cb0ed5f321..d30b84ccfd5 100644 --- a/gcc/config/m68hc11/m68hc11.c +++ b/gcc/config/m68hc11/m68hc11.c @@ -91,6 +91,7 @@ static int m68hc11_make_autoinc_notes (rtx *, void *); static void m68hc11_init_libfuncs (void); static rtx m68hc11_struct_value_rtx (tree, int); static bool m68hc11_return_in_memory (const_tree, const_tree); +static bool m68hc11_can_eliminate (const int, const int); /* Must be set to 1 to produce debug messages. */ int debug_m6811 = 0; @@ -278,6 +279,9 @@ static const struct attribute_spec m68hc11_attribute_table[] = #undef TARGET_LEGITIMATE_ADDRESS_P #define TARGET_LEGITIMATE_ADDRESS_P m68hc11_legitimate_address_p +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE m68hc11_can_eliminate + struct gcc_target targetm = TARGET_INITIALIZER; int @@ -1280,6 +1284,19 @@ m68hc11_is_trap_symbol (rtx sym) /* Argument support functions. */ +/* Given FROM and TO register numbers, say whether this elimination is + allowed. Frame pointer elimination is automatically handled. + + All other eliminations are valid. */ + +bool +m68hc11_can_eliminate (const int from, const int to) +{ + return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM + ? ! frame_pointer_needed + : true); +} + /* Define the offset between two registers, one to be eliminated, and the other its replacement, at the start of a routine. */ int diff --git a/gcc/config/m68hc11/m68hc11.h b/gcc/config/m68hc11/m68hc11.h index e795485f9c1..9b19c33e0f8 100644 --- a/gcc/config/m68hc11/m68hc11.h +++ b/gcc/config/m68hc11/m68hc11.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler. Motorola 68HC11 and 68HC12. - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008 + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Stephane Carrez (stcarrez@nerim.fr) @@ -883,17 +883,6 @@ extern enum reg_class m68hc11_tmp_regs_class; {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ {FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} -/* Given FROM and TO register numbers, say whether this elimination is allowed. - Frame pointer elimination is automatically handled. - - All other eliminations are valid. */ - -#define CAN_ELIMINATE(FROM, TO) \ - ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM \ - ? ! frame_pointer_needed \ - : 1) - - /* Define the offset between two registers, one to be eliminated, and the other its replacement, at the start of a routine. */ diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index 1027d1c724c..033872c28a1 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -132,6 +132,7 @@ static void m68k_sched_dfa_pre_advance_cycle (void); static void m68k_sched_dfa_post_advance_cycle (void); static int m68k_sched_first_cycle_multipass_dfa_lookahead (void); +static bool m68k_can_eliminate (const int, const int); static bool m68k_legitimate_address_p (enum machine_mode, rtx, bool); static bool m68k_handle_option (size_t, const char *, int); static rtx find_addr_reg (rtx); @@ -263,6 +264,9 @@ const char *m68k_library_id_string = "_current_shared_library_a5_offset_"; #undef TARGET_LEGITIMATE_ADDRESS_P #define TARGET_LEGITIMATE_ADDRESS_P m68k_legitimate_address_p +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE m68k_can_eliminate + static const struct attribute_spec m68k_attribute_table[] = { /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ @@ -866,6 +870,14 @@ m68k_compute_frame_layout (void) current_frame.funcdef_no = current_function_funcdef_no; } +/* Worker function for TARGET_CAN_ELIMINATE. */ + +bool +m68k_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) +{ + return (to == STACK_POINTER_REGNUM ? ! frame_pointer_needed : true); +} + HOST_WIDE_INT m68k_initial_elimination_offset (int from, int to) { diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h index 24598c5ba07..b2cfb1d8fd1 100644 --- a/gcc/config/m68k/m68k.h +++ b/gcc/config/m68k/m68k.h @@ -1,6 +1,7 @@ /* Definitions of target machine for GCC for Motorola 680x0/ColdFire. Copyright (C) 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + Free Software Foundation, Inc. This file is part of GCC. @@ -663,9 +664,6 @@ __transfer_from_trampoline () \ { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }} -#define CAN_ELIMINATE(FROM, TO) \ - ((TO) == STACK_POINTER_REGNUM ? ! frame_pointer_needed : 1) - #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ (OFFSET) = m68k_initial_elimination_offset(FROM, TO) diff --git a/gcc/config/mep/mep.c b/gcc/config/mep/mep.c index cf2e7d53fc0..b255339bfc3 100644 --- a/gcc/config/mep/mep.c +++ b/gcc/config/mep/mep.c @@ -227,6 +227,7 @@ static rtx mep_expand_builtin_saveregs (void); static tree mep_build_builtin_va_list (void); static void mep_expand_va_start (tree, rtx); static tree mep_gimplify_va_arg_expr (tree, tree, tree *, tree *); +static bool mep_can_eliminate (const int, const int); /* Initialize the GCC target structure. */ @@ -298,6 +299,8 @@ static tree mep_gimplify_va_arg_expr (tree, tree, tree *, tree *); #define TARGET_EXPAND_BUILTIN_VA_START mep_expand_va_start #undef TARGET_GIMPLIFY_VA_ARG_EXPR #define TARGET_GIMPLIFY_VA_ARG_EXPR mep_gimplify_va_arg_expr +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE mep_can_eliminate struct gcc_target targetm = TARGET_INITIALIZER; @@ -2609,6 +2612,16 @@ mep_reg_size (int regno) return 4; } +/* Worker function for TARGET_CAN_ELIMINATE. */ + +bool +mep_can_eliminate (const int from, const int to) +{ + return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM + ? ! frame_pointer_needed + : true); +} + int mep_elimination_offset (int from, int to) { diff --git a/gcc/config/mep/mep.h b/gcc/config/mep/mep.h index 1cdd7468284..58a688614cc 100644 --- a/gcc/config/mep/mep.h +++ b/gcc/config/mep/mep.h @@ -498,11 +498,6 @@ extern unsigned int mep_selected_isa; {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \ } -#define CAN_ELIMINATE(FROM, TO) \ - ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM \ - ? ! frame_pointer_needed \ - : 1) - #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ (OFFSET) = mep_elimination_offset (FROM, TO) diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 04a1f0ed8cd..42363992376 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -8989,6 +8989,15 @@ mips_frame_pointer_required (void) return false; } +/* Make sure that we're not trying to eliminate to the wrong hard frame + pointer. */ + +static bool +mips_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) +{ + return (to == HARD_FRAME_POINTER_REGNUM || to == STACK_POINTER_REGNUM); +} + /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame pointer or argument pointer. TO is either the stack pointer or hard frame pointer. */ @@ -15010,6 +15019,9 @@ mips_final_postscan_insn (FILE *file ATTRIBUTE_UNUSED, rtx insn, #undef TARGET_FRAME_POINTER_REQUIRED #define TARGET_FRAME_POINTER_REQUIRED mips_frame_pointer_required +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE mips_can_eliminate + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-mips.h" diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 76ab40a1e57..2c9199a12c3 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -2166,11 +2166,6 @@ enum reg_class { FRAME_POINTER_REGNUM, GP_REG_FIRST + 30}, \ { FRAME_POINTER_REGNUM, GP_REG_FIRST + 17}} -/* Make sure that we're not trying to eliminate to the wrong hard frame - pointer. */ -#define CAN_ELIMINATE(FROM, TO) \ - ((TO) == HARD_FRAME_POINTER_REGNUM || (TO) == STACK_POINTER_REGNUM) - #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ (OFFSET) = mips_initial_elimination_offset ((FROM), (TO)) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 95f8ab5aae2..cb64d28f4c9 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1088,6 +1088,7 @@ static const enum reg_class *rs6000_ira_cover_classes (void); const int INSN_NOT_AVAILABLE = -1; static enum machine_mode rs6000_eh_return_filter_mode (void); +static bool rs6000_can_eliminate (const int, const int); /* Hash table stuff for keeping track of TOC entries. */ @@ -1453,6 +1454,9 @@ static const struct attribute_spec rs6000_attribute_table[] = #undef TARGET_LEGITIMATE_ADDRESS_P #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE rs6000_can_eliminate + struct gcc_target targetm = TARGET_INITIALIZER; /* Return number of consecutive hard regs needed starting at reg REGNO @@ -25011,6 +25015,26 @@ rs6000_libcall_value (enum machine_mode mode) return gen_rtx_REG (mode, regno); } + +/* Given FROM and TO register numbers, say whether this elimination is allowed. + Frame pointer elimination is automatically handled. + + For the RS/6000, if frame pointer elimination is being done, we would like + to convert ap into fp, not sp. + + We need r30 if -mminimal-toc was specified, and there are constant pool + references. */ + +bool +rs6000_can_eliminate (const int from, const int to) +{ + return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM + ? ! frame_pointer_needed + : from == RS6000_PIC_OFFSET_TABLE_REGNUM + ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0 + : true); +} + /* Define the offset between two registers, FROM to be eliminated and its replacement TO, at the start of a routine. */ HOST_WIDE_INT diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 0c5e59333ab..d837d44c9be 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1786,22 +1786,6 @@ typedef struct rs6000_args { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ { RS6000_PIC_OFFSET_TABLE_REGNUM, RS6000_PIC_OFFSET_TABLE_REGNUM } } -/* Given FROM and TO register numbers, say whether this elimination is allowed. - Frame pointer elimination is automatically handled. - - For the RS/6000, if frame pointer elimination is being done, we would like - to convert ap into fp, not sp. - - We need r30 if -mminimal-toc was specified, and there are constant pool - references. */ - -#define CAN_ELIMINATE(FROM, TO) \ - ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM \ - ? ! frame_pointer_needed \ - : (FROM) == RS6000_PIC_OFFSET_TABLE_REGNUM \ - ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0 \ - : 1) - /* Define the offset between two registers, one to be eliminated, and the other its replacement, at the start of a routine. */ #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 8b9ad5aedb5..be68bd530c3 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler, for IBM S/390. - Copyright (C) 2000, 2002, 2003, 2004, 2005, 2007, 2008 Free - Software Foundation, Inc. + Copyright (C) 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009 + Free Software Foundation, Inc. Contributed by Hartmut Penner (hpenner@de.ibm.com) @@ -36,7 +36,6 @@ extern bool s390_check_symref_alignment (rtx addr, HOST_WIDE_INT alignment); extern void optimization_options (int, int); extern void override_options (void); -extern bool s390_can_eliminate (int, int); extern HOST_WIDE_INT s390_initial_elimination_offset (int, int); extern void s390_emit_prologue (void); extern void s390_emit_epilogue (bool); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 47b939c676a..05896064d6e 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -7335,8 +7335,8 @@ s390_class_max_nregs (enum reg_class rclass, enum machine_mode mode) /* Return true if register FROM can be eliminated via register TO. */ -bool -s390_can_eliminate (int from, int to) +static bool +s390_can_eliminate (const int from, const int to) { /* On zSeries machines, we have not marked the base register as fixed. Instead, we have an elimination rule BASE_REGNUM -> BASE_REGNUM. @@ -10146,6 +10146,9 @@ s390_reorg (void) #undef TARGET_LEGITIMATE_ADDRESS_P #define TARGET_LEGITIMATE_ADDRESS_P s390_legitimate_address_p +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE s390_can_eliminate + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-s390.h" diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index 4772367eee5..3c93fb770f6 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -646,9 +646,6 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER]; { RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \ { BASE_REGNUM, BASE_REGNUM }} -#define CAN_ELIMINATE(FROM, TO) \ - s390_can_eliminate ((FROM), (TO)) - #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ (OFFSET) = s390_initial_elimination_offset ((FROM), (TO)) diff --git a/gcc/config/score/score.c b/gcc/config/score/score.c index 0241383fc86..12eb76b1a41 100644 --- a/gcc/config/score/score.c +++ b/gcc/config/score/score.c @@ -1,5 +1,5 @@ /* Output routines for Sunplus S+CORE processor - Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Sunnorth. This file is part of GCC. @@ -116,6 +116,9 @@ #undef TARGET_LEGITIMATE_ADDRESS_P #define TARGET_LEGITIMATE_ADDRESS_P score_legitimate_address_p +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE score_can_eliminate + struct extern_list *extern_head = 0; /* default 0 = NO_REGS */ @@ -426,6 +429,16 @@ score_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode) gcc_unreachable (); } +/* We can always eliminate to the hard frame pointer. We can eliminate + to the stack pointer unless a frame pointer is needed. */ + +static bool +score_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) +{ + return (to == HARD_FRAME_POINTER_REGNUM + || (to == STACK_POINTER_REGNUM && !frame_pointer_needed)); +} + /* Implement INITIAL_ELIMINATION_OFFSET. FROM is either the frame pointer or argument pointer. TO is either the stack pointer or hard frame pointer. */ diff --git a/gcc/config/score/score.h b/gcc/config/score/score.h index ed3f1a4b3c0..ea3e0168995 100644 --- a/gcc/config/score/score.h +++ b/gcc/config/score/score.h @@ -564,13 +564,6 @@ extern enum reg_class score_char_to_class[256]; { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} -/* We can always eliminate to the hard frame pointer. We can eliminate - to the stack pointer unless a frame pointer is needed. */ -#define CAN_ELIMINATE(FROM, TO) \ - (((TO) == HARD_FRAME_POINTER_REGNUM) \ - || ((TO) == STACK_POINTER_REGNUM \ - && !frame_pointer_needed)) - #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ (OFFSET) = score_initial_elimination_offset ((FROM), (TO)) diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index 552d5596331..4ece6c0b161 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -50,7 +50,6 @@ extern int short_branch (int, int); extern void sparc_profile_hook (int); extern void sparc_override_options (void); extern void sparc_output_scratch_registers (FILE *); -extern bool sparc_can_eliminate (const int, const int); #ifdef RTX_CODE extern enum machine_mode select_cc_mode (enum rtx_code, rtx, rtx); diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index a0adfd02168..ea439142dea 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -420,6 +420,7 @@ static void sparc_dwarf_handle_frame_unspec (const char *, rtx, int); static void sparc_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; static void sparc_file_end (void); static bool sparc_frame_pointer_required (void); +static bool sparc_can_eliminate (const int, const int); #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING static const char *sparc_mangle_type (const_tree); #endif @@ -588,6 +589,9 @@ static bool fpu_option_set = false; #undef TARGET_FRAME_POINTER_REQUIRED #define TARGET_FRAME_POINTER_REQUIRED sparc_frame_pointer_required +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE sparc_can_eliminate + #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING #undef TARGET_MANGLE_TYPE #define TARGET_MANGLE_TYPE sparc_mangle_type diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 3b713611f84..c5c762a44ec 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -1369,12 +1369,6 @@ extern char leaf_reg_remap[]; {{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM} } -/* The way this is structured, we can't eliminate SFP in favor of SP - if the frame pointer is required: we want to use the SFP->HFP elimination - in that case. But the test in update_eliminables doesn't know we are - assuming below that we only do the former elimination. */ -#define CAN_ELIMINATE(FROM, TO) sparc_can_eliminate((FROM), (TO)) - /* We always pretend that this is a leaf function because if it's not, there's no point in trying to eliminate the frame pointer. If it is a leaf function, we guessed right! */ diff --git a/gcc/config/stormy16/stormy16.c b/gcc/config/stormy16/stormy16.c index 06b96c7b8ce..1c076b2c649 100644 --- a/gcc/config/stormy16/stormy16.c +++ b/gcc/config/stormy16/stormy16.c @@ -1016,6 +1016,16 @@ xstormy16_compute_stack_layout (void) return layout; } +/* Worker function for TARGET_CAN_ELIMINATE. */ + +static bool +xstormy16_can_eliminate (const int from, const int to) +{ + return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM + ? ! frame_pointer_needed + : true); +} + /* Determine how all the special registers get eliminated. */ int @@ -2654,6 +2664,9 @@ xstormy16_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) #undef TARGET_LEGITIMATE_ADDRESS_P #define TARGET_LEGITIMATE_ADDRESS_P xstormy16_legitimate_address_p +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE xstormy16_can_eliminate + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-stormy16.h" diff --git a/gcc/config/stormy16/stormy16.h b/gcc/config/stormy16/stormy16.h index cb35a13ab6a..49505b507b0 100644 --- a/gcc/config/stormy16/stormy16.h +++ b/gcc/config/stormy16/stormy16.h @@ -1,6 +1,6 @@ /* Xstormy16 cpu description. Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, - 2008 Free Software Foundation, Inc. + 2008, 2009 Free Software Foundation, Inc. Contributed by Red Hat, Inc. This file is part of GCC. @@ -375,11 +375,6 @@ enum reg_class {ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ } -#define CAN_ELIMINATE(FROM, TO) \ - ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM \ - ? ! frame_pointer_needed \ - : 1) - #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ (OFFSET) = xstormy16_initial_elimination_offset (FROM, TO) diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c index 5e1594a9be5..19268e2bd3b 100644 --- a/gcc/config/v850/v850.c +++ b/gcc/config/v850/v850.c @@ -72,6 +72,7 @@ static bool v850_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); static int v850_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, tree, bool); +static bool v850_can_eliminate (const int, const int); /* Information about the various small memory areas. */ struct small_memory_info small_memory[ (int)SMALL_MEMORY_max ] = @@ -173,6 +174,9 @@ static const struct attribute_spec v850_attribute_table[] = #undef TARGET_ARG_PARTIAL_BYTES #define TARGET_ARG_PARTIAL_BYTES v850_arg_partial_bytes +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE v850_can_eliminate + struct gcc_target targetm = TARGET_INITIALIZER; /* Set the maximum size of small memory area TYPE to the value given @@ -2957,4 +2961,12 @@ v850_setup_incoming_varargs (CUMULATIVE_ARGS *ca, ca->anonymous_args = (!TARGET_GHS ? 1 : 0); } +/* Worker function for TARGET_CAN_ELIMINATE. */ + +bool +v850_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) +{ + return (to == STACK_POINTER_REGNUM ? ! frame_pointer_needed : true); +} + #include "gt-v850.h" diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h index b841963bd2b..026a2292588 100644 --- a/gcc/config/v850/v850.h +++ b/gcc/config/v850/v850.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler. NEC V850 series Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2007, 2008 Free Software Foundation, Inc. + 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Jeff Law (law@cygnus.com). This file is part of GCC. @@ -538,16 +538,6 @@ enum reg_class { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }} \ -/* A C expression that returns nonzero if the compiler is allowed to - try to replace register number FROM-REG with register number - TO-REG. This macro need only be defined if `ELIMINABLE_REGS' is - defined, and will usually be the constant 1, since most of the - cases preventing register elimination are things that the compiler - already knows about. */ - -#define CAN_ELIMINATE(FROM, TO) \ - ((TO) == STACK_POINTER_REGNUM ? ! frame_pointer_needed : 1) - /* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the initial difference between the specified pair of registers. This macro must be defined if `ELIMINABLE_REGS' is diff --git a/gcc/defaults.h b/gcc/defaults.h index b6cec4b249b..f1d96833070 100644 --- a/gcc/defaults.h +++ b/gcc/defaults.h @@ -1147,10 +1147,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define ATTRIBUTE_ALIGNED_VALUE BIGGEST_ALIGNMENT #endif -#ifndef CAN_ELIMINATE -#define CAN_ELIMINATE(FROM, TO) true -#endif - /* Many ports have no mode-dependent addresses (except possibly autoincrement and autodecrement addresses, which are handled by target-independent code in recog.c). */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index df4973d8368..818df81a4d3 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -3812,16 +3812,16 @@ Note that the elimination of the argument pointer with the stack pointer is specified first since that is the preferred elimination. @end defmac -@defmac CAN_ELIMINATE (@var{from-reg}, @var{to-reg}) -A C expression that returns @code{true} if the compiler is allowed to try -to replace register number @var{from-reg} with register number -@var{to-reg}. This macro need only be defined if @code{ELIMINABLE_REGS} +@deftypefn {Target Hook} bool TARGET_CAN_ELIMINATE (const int @var{from-reg}, const int @var{to-reg}) +This target hook should returns @code{true} if the compiler is allowed to +try to replace register number @var{from-reg} with register number +@var{to-reg}. This target hook need only be defined if @code{ELIMINABLE_REGS} is defined, and will usually be @code{true}, since most of the cases preventing register elimination are things that the compiler already knows about. -Default value is @code{true}. -@end defmac +Default return value is @code{true}. +@end deftypefn @defmac INITIAL_ELIMINATION_OFFSET (@var{from-reg}, @var{to-reg}, @var{offset-var}) This macro is similar to @code{INITIAL_FRAME_POINTER_OFFSET}. It diff --git a/gcc/hooks.c b/gcc/hooks.c index 5af3cd1c411..0547ca81bb6 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -56,6 +56,13 @@ hook_bool_bool_false (bool a ATTRIBUTE_UNUSED) return false; } +/* Generic hook that takes const int, const int) and returns true. */ +bool hook_bool_const_int_const_int_true (const int a ATTRIBUTE_UNUSED, + const int b ATTRIBUTE_UNUSED) +{ + return true; +} + /* Generic hook that takes (enum machine_mode) and returns false. */ bool hook_bool_mode_false (enum machine_mode mode ATTRIBUTE_UNUSED) diff --git a/gcc/hooks.h b/gcc/hooks.h index b057d5d6118..2704e25234f 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -28,6 +28,7 @@ extern bool hook_bool_void_false (void); extern bool hook_bool_void_true (void); extern bool hook_bool_bool_false (bool); +extern bool hook_bool_const_int_const_int_true (const int, const int); extern bool hook_bool_mode_false (enum machine_mode); extern bool hook_bool_mode_const_rtx_false (enum machine_mode, const_rtx); extern bool hook_bool_mode_const_rtx_true (enum machine_mode, const_rtx); diff --git a/gcc/ira.c b/gcc/ira.c index e4caf31fb8d..c6a87237621 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -1458,7 +1458,7 @@ setup_eliminable_regset (void) for (i = 0; i < (int) ARRAY_SIZE (eliminables); i++) { bool cannot_elim - = (! CAN_ELIMINATE (eliminables[i].from, eliminables[i].to) + = (! targetm.can_eliminate (eliminables[i].from, eliminables[i].to) || (eliminables[i].to == STACK_POINTER_REGNUM && need_fp)); if (! regs_asm_clobbered[eliminables[i].from]) diff --git a/gcc/reload1.c b/gcc/reload1.c index 7900841a239..25af8404e10 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -318,8 +318,9 @@ struct elim_table int to; /* Register number used as replacement. */ HOST_WIDE_INT initial_offset; /* Initial difference between values. */ int can_eliminate; /* Nonzero if this elimination can be done. */ - int can_eliminate_previous; /* Value of CAN_ELIMINATE in previous scan over - insns made by reload. */ + int can_eliminate_previous; /* Value returned by TARGET_CAN_ELIMINATE + target hook in previous scan over insns + made by reload. */ HOST_WIDE_INT offset; /* Current offset between the two regs. */ HOST_WIDE_INT previous_offset;/* Offset at end of previous insn. */ int ref_outside_mem; /* "to" has been referenced outside a MEM. */ @@ -3705,7 +3706,7 @@ update_eliminables (HARD_REG_SET *pset) if ((ep->from == HARD_FRAME_POINTER_REGNUM && targetm.frame_pointer_required ()) #ifdef ELIMINABLE_REGS - || ! CAN_ELIMINATE (ep->from, ep->to) + || ! targetm.can_eliminate (ep->from, ep->to) #endif ) ep->can_eliminate = 0; @@ -3811,7 +3812,7 @@ init_elim_table (void) ep->from = ep1->from; ep->to = ep1->to; ep->can_eliminate = ep->can_eliminate_previous - = (CAN_ELIMINATE (ep->from, ep->to) + = (targetm.can_eliminate (ep->from, ep->to) && ! (ep->to == STACK_POINTER_REGNUM && frame_pointer_needed && (! SUPPORTS_STACK_ALIGNMENT diff --git a/gcc/system.h b/gcc/system.h index 5d47f2e1839..f73097a035d 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -693,7 +693,8 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; MUST_PASS_IN_STACK FUNCTION_ARG_PASS_BY_REFERENCE \ VECTOR_MODE_SUPPORTED_P TARGET_SUPPORTS_HIDDEN \ FUNCTION_ARG_PARTIAL_NREGS ASM_OUTPUT_DWARF_DTPREL \ - ALLOCATE_INITIAL_VALUE LEGITIMIZE_ADDRESS FRAME_POINTER_REQUIRED + ALLOCATE_INITIAL_VALUE LEGITIMIZE_ADDRESS FRAME_POINTER_REQUIRED \ + CAN_ELIMINATE /* Other obsolete target macros, or macros that used to be in target headers and were not used, and may be obsolete or may never have diff --git a/gcc/target-def.h b/gcc/target-def.h index b8a28a442ae..3cef10a55cc 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -666,6 +666,10 @@ #define TARGET_FRAME_POINTER_REQUIRED hook_bool_void_false #endif +#ifndef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE hook_bool_const_int_const_int_true +#endif + /* C specific. */ #ifndef TARGET_C_MODE_FOR_SUFFIX #define TARGET_C_MODE_FOR_SUFFIX default_mode_for_suffix @@ -939,6 +943,7 @@ TARGET_HARD_REGNO_SCRATCH_OK, \ TARGET_CASE_VALUES_THRESHOLD, \ TARGET_FRAME_POINTER_REQUIRED, \ + TARGET_CAN_ELIMINATE, \ TARGET_C, \ TARGET_CXX, \ TARGET_EMUTLS, \ diff --git a/gcc/target.h b/gcc/target.h index 786f98793ac..7f7f177904f 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -971,6 +971,10 @@ struct gcc_target /* Retutn true if a function must have and use a frame pointer. */ bool (* frame_pointer_required) (void); + /* Returns true if the compiler is allowed to try to replace register number + from-reg with register number to-reg. */ + bool (* can_eliminate) (const int, const int); + /* Functions specific to the C family of frontends. */ struct c { /* Return machine mode for non-standard suffix -- 2.11.0