From fbbf66e77a385fc1901fdc33c1d977681cab39bf Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 21 Apr 2011 09:37:44 +0000 Subject: [PATCH] target.def (cannot_force_const_mem): Add a mode argument. gcc/ * target.def (cannot_force_const_mem): Add a mode argument. * doc/tm.texi.in (TARGET_CANNOT_FORCE_CONST_MEM): Update accordingly. * doc/tm.texi: Regenerate. * hooks.h (hook_bool_mode_rtx_false): Declare. * hooks.c (hook_bool_mode_const_rtx_false): Fix commentary. (hook_bool_mode_const_rtx_true): Likewise. (hook_bool_mode_rtx_false): New function. * reload.c (CONST_POOL_OK_P): Take a mode argument and require it to be non-VOID. Update call to cannot_force_const_mem. (find_reloads): Update accordingly. * varasm.c (force_const_mem): Update call to cannot_force_const_mem. * config/alpha/alpha.c (alpha_cannot_force_const_mem): Add a mode argument. * config/arm/arm-protos.h (arm_cannot_force_const_mem): Likewise. * config/arm/arm.h (LEGITIMATE_CONSTANT_P): Update call. * config/arm/arm.c (arm_cannot_force_const_mem): Add a mode argument. * config/bfin/bfin.c (bfin_cannot_force_const_mem): Likewise. * config/frv/frv.c (frv_cannot_force_const_mem): Likewise. * config/i386/i386.c (ix86_cannot_force_const_mem): Likewise. * config/ia64/ia64.c (ia64_cannot_force_const_mem): Likewise. * config/m68k/m68k.c (TARGET_CANNOT_FORCE_CONST_MEM): Redefine to... (m68k_cannot_force_const_mem): ...this new function. * config/mips/mips.c (mips_cannot_force_const_mem): Add a mode argument. (mips_const_insns, mips_legitimize_const_move): Update calls. (mips_secondary_reload_class): Likewise. * config/pa/pa.c (TARGET_CANNOT_FORCE_CONST_MEM): Redefine to... (pa_cannot_force_const_mem): ...this new function. * config/rs6000/rs6000.c (TARGET_CANNOT_FORCE_CONST_MEM): Reefine to... (rs6000_cannot_force_const_mem): ...this new function. * config/s390/s390.c (s390_cannot_force_const_mem): Add a mode argument. * config/sparc/sparc.c (sparc_cannot_force_const_mem): Likewise. * config/xtensa/xtensa.c (TARGET_CANNOT_FORCE_CONST_MEM): Redefine to... (xtensa_cannot_force_const_mem): ...this new function. From-SVN: r172813 --- gcc/ChangeLog | 40 +++++++++++++++++++++++++++++++++++++ gcc/config/alpha/alpha.c | 2 +- gcc/config/arm/arm-protos.h | 2 +- gcc/config/arm/arm.c | 2 +- gcc/config/arm/arm.h | 2 +- gcc/config/bfin/bfin.c | 3 ++- gcc/config/frv/frv.c | 5 +++-- gcc/config/i386/i386.c | 2 +- gcc/config/ia64/ia64.c | 6 +++--- gcc/config/m68k/m68k.c | 11 +++++++++- gcc/config/mips/mips.c | 8 ++++---- gcc/config/pa/pa.c | 11 +++++++++- gcc/config/rs6000/rs6000.c | 11 +++++++++- gcc/config/s390/s390.c | 8 ++++---- gcc/config/sparc/sparc.c | 10 +++++----- gcc/config/xtensa/xtensa.c | 12 ++++++++++- gcc/doc/tm.texi | 8 +++++--- gcc/doc/tm.texi.in | 6 ++++-- gcc/hooks.c | 12 +++++++++-- gcc/hooks.h | 1 + gcc/reload.c | 26 ++++++++++++------------ gcc/target.def | 4 ++-- gcc/varasm.c | 2 +- 23 files changed, 143 insertions(+), 51 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9a2cd4f8106..3f346fc8dd8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,43 @@ +2011-04-21 Richard Sandiford + + * target.def (cannot_force_const_mem): Add a mode argument. + * doc/tm.texi.in (TARGET_CANNOT_FORCE_CONST_MEM): Update accordingly. + * doc/tm.texi: Regenerate. + * hooks.h (hook_bool_mode_rtx_false): Declare. + * hooks.c (hook_bool_mode_const_rtx_false): Fix commentary. + (hook_bool_mode_const_rtx_true): Likewise. + (hook_bool_mode_rtx_false): New function. + * reload.c (CONST_POOL_OK_P): Take a mode argument and require it + to be non-VOID. Update call to cannot_force_const_mem. + (find_reloads): Update accordingly. + * varasm.c (force_const_mem): Update call to cannot_force_const_mem. + * config/alpha/alpha.c (alpha_cannot_force_const_mem): Add a mode + argument. + * config/arm/arm-protos.h (arm_cannot_force_const_mem): Likewise. + * config/arm/arm.h (LEGITIMATE_CONSTANT_P): Update call. + * config/arm/arm.c (arm_cannot_force_const_mem): Add a mode argument. + * config/bfin/bfin.c (bfin_cannot_force_const_mem): Likewise. + * config/frv/frv.c (frv_cannot_force_const_mem): Likewise. + * config/i386/i386.c (ix86_cannot_force_const_mem): Likewise. + * config/ia64/ia64.c (ia64_cannot_force_const_mem): Likewise. + * config/m68k/m68k.c (TARGET_CANNOT_FORCE_CONST_MEM): Redefine to... + (m68k_cannot_force_const_mem): ...this new function. + * config/mips/mips.c (mips_cannot_force_const_mem): Add a mode + argument. + (mips_const_insns, mips_legitimize_const_move): Update calls. + (mips_secondary_reload_class): Likewise. + * config/pa/pa.c (TARGET_CANNOT_FORCE_CONST_MEM): Redefine to... + (pa_cannot_force_const_mem): ...this new function. + * config/rs6000/rs6000.c (TARGET_CANNOT_FORCE_CONST_MEM): Reefine + to... + (rs6000_cannot_force_const_mem): ...this new function. + * config/s390/s390.c (s390_cannot_force_const_mem): Add a mode + argument. + * config/sparc/sparc.c (sparc_cannot_force_const_mem): Likewise. + * config/xtensa/xtensa.c (TARGET_CANNOT_FORCE_CONST_MEM): Redefine + to... + (xtensa_cannot_force_const_mem): ...this new function. + 2011-04-20 Nathan Froyd * config/mips/mips.c (mips16_build_function_stub): Call diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 5e85e2be471..ba0dfe633cc 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -1095,7 +1095,7 @@ alpha_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, should never be spilling symbolic operands to the constant pool, ever. */ static bool -alpha_cannot_force_const_mem (rtx x) +alpha_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) { enum rtx_code code = GET_CODE (x); return code == SYMBOL_REF || code == LABEL_REF || code == CONST; diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 190fec0ecef..da3241d2bf3 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -82,7 +82,7 @@ extern void neon_disambiguate_copy (rtx *, rtx *, rtx *, unsigned int); extern enum reg_class coproc_secondary_reload_class (enum machine_mode, rtx, bool); extern bool arm_tls_referenced_p (rtx); -extern bool arm_cannot_force_const_mem (rtx); +extern bool arm_cannot_force_const_mem (enum machine_mode, rtx); extern int cirrus_memory_offset (rtx); extern int arm_coproc_mem_operand (rtx, bool); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 46255cbeebb..0f944fd869d 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -6500,7 +6500,7 @@ arm_tls_referenced_p (rtx x) /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */ bool -arm_cannot_force_const_mem (rtx x) +arm_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) { rtx base, offset; diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index e45b9274323..76efdec8e50 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1763,7 +1763,7 @@ typedef struct || flag_pic) #define LEGITIMATE_CONSTANT_P(X) \ - (!arm_cannot_force_const_mem (X) \ + (!arm_cannot_force_const_mem (VOIDmode, X) \ && (TARGET_32BIT ? ARM_LEGITIMATE_CONSTANT_P (X) \ : THUMB_LEGITIMATE_CONSTANT_P (X))) diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index 5d0843748a8..2a9730fa902 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -3055,7 +3055,8 @@ bfin_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) another way. */ static bool -bfin_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED) +bfin_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, + rtx x ATTRIBUTE_UNUSED) { /* We have only one class of non-legitimate constants, and our movsi expander knows how to handle them. Dropping these constants into the diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c index 09137654ad1..5b0c0847e15 100644 --- a/gcc/config/frv/frv.c +++ b/gcc/config/frv/frv.c @@ -372,7 +372,7 @@ static int frv_memory_move_cost (enum machine_mode, static void frv_asm_out_constructor (rtx, int); static void frv_asm_out_destructor (rtx, int); static bool frv_function_symbol_referenced_p (rtx); -static bool frv_cannot_force_const_mem (rtx); +static bool frv_cannot_force_const_mem (enum machine_mode, rtx); static const char *unspec_got_name (int); static void frv_output_const_unspec (FILE *, const struct frv_unspec *); @@ -616,7 +616,8 @@ frv_const_unspec_p (rtx x, struct frv_unspec *unspec) 4. In many cases, it's more efficient to calculate the constant in-line. */ static bool -frv_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED) +frv_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, + rtx x ATTRIBUTE_UNUSED) { return TARGET_FDPIC; } diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 7cb7c2db017..c4b18ef56ad 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -12005,7 +12005,7 @@ legitimate_constant_p (rtx x) is checked above. */ static bool -ix86_cannot_force_const_mem (rtx x) +ix86_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) { /* We can always put integral constants and vectors in memory. */ switch (GET_CODE (x)) diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 5f22b17ef67..60832793017 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -316,7 +316,7 @@ static rtx ia64_struct_value_rtx (tree, int); static tree ia64_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *); static bool ia64_scalar_mode_supported_p (enum machine_mode mode); static bool ia64_vector_mode_supported_p (enum machine_mode mode); -static bool ia64_cannot_force_const_mem (rtx); +static bool ia64_cannot_force_const_mem (enum machine_mode, rtx); static const char *ia64_mangle_type (const_tree); static const char *ia64_invalid_conversion (const_tree, const_tree); static const char *ia64_invalid_unary_op (int, const_tree); @@ -1014,9 +1014,9 @@ ia64_legitimate_constant_p (rtx x) /* Don't allow TLS addresses to get spilled to memory. */ static bool -ia64_cannot_force_const_mem (rtx x) +ia64_cannot_force_const_mem (enum machine_mode mode, rtx x) { - if (GET_MODE (x) == RFmode) + if (mode == RFmode) return true; return tls_symbolic_operand_type (x) != 0; } diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index 654c0e5cfbc..7553183d541 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -163,6 +163,7 @@ static void m68k_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); static rtx m68k_function_arg (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool); +static bool m68k_cannot_force_const_mem (enum machine_mode mode, rtx x); /* Specify the identification number of the library being built */ @@ -256,7 +257,7 @@ const char *m68k_library_id_string = "_current_shared_library_a5_offset_"; #define TARGET_STRUCT_VALUE_RTX m68k_struct_value_rtx #undef TARGET_CANNOT_FORCE_CONST_MEM -#define TARGET_CANNOT_FORCE_CONST_MEM m68k_illegitimate_symbolic_constant_p +#define TARGET_CANNOT_FORCE_CONST_MEM m68k_cannot_force_const_mem #undef TARGET_FUNCTION_OK_FOR_SIBCALL #define TARGET_FUNCTION_OK_FOR_SIBCALL m68k_ok_for_sibcall_p @@ -1937,6 +1938,14 @@ m68k_illegitimate_symbolic_constant_p (rtx x) return m68k_tls_reference_p (x, false); } +/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */ + +static bool +m68k_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) +{ + return m68k_illegitimate_symbolic_constant_p (x); +} + /* Return true if X is a legitimate constant address that can reach bytes in the range [X, X + REACH). STRICT_P says whether we need strict checking. */ diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 2dd90e28ec2..f6a4ec98cbe 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -1997,7 +1997,7 @@ mips_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED) /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */ static bool -mips_cannot_force_const_mem (rtx x) +mips_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) { enum mips_symbol_type type; rtx base, offset; @@ -2387,7 +2387,7 @@ mips_const_insns (rtx x) { if (SMALL_INT (offset)) return n + 1; - else if (!targetm.cannot_force_const_mem (x)) + else if (!targetm.cannot_force_const_mem (GET_MODE (x), x)) return n + 1 + mips_build_integer (codes, INTVAL (offset)); } } @@ -3090,7 +3090,7 @@ mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src) forced into memory, as it usually produces better code. */ split_const (src, &base, &offset); if (offset != const0_rtx - && (targetm.cannot_force_const_mem (src) + && (targetm.cannot_force_const_mem (mode, src) || (!TARGET_MIPS16 && can_create_pseudo_p ()))) { base = mips_force_temporary (dest, base); @@ -11087,7 +11087,7 @@ mips_secondary_reload_class (enum reg_class rclass, /* In this case we can use mtc1, mfc1, dmtc1 or dmfc1. */ return NO_REGS; - if (CONSTANT_P (x) && !targetm.cannot_force_const_mem (x)) + if (CONSTANT_P (x) && !targetm.cannot_force_const_mem (mode, x)) /* We can force the constant to memory and use lwc1 and ldc1. As above, we will use pairs of lwc1s if ldc1 is not supported. */ diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index aeb80613383..ab0fe6a8a09 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -187,6 +187,7 @@ static bool pa_can_eliminate (const int, const int); static void pa_conditional_register_usage (void); static enum machine_mode pa_c_mode_for_suffix (char); static section *pa_function_section (tree, enum node_frequency, bool, bool); +static bool pa_cannot_force_const_mem (enum machine_mode, rtx); /* The following extra sections are only used for SOM. */ static GTY(()) section *som_readonly_data_section; @@ -369,7 +370,7 @@ static const struct default_options pa_option_optimization_table[] = #define TARGET_SCALAR_MODE_SUPPORTED_P pa_scalar_mode_supported_p #undef TARGET_CANNOT_FORCE_CONST_MEM -#define TARGET_CANNOT_FORCE_CONST_MEM pa_tls_referenced_p +#define TARGET_CANNOT_FORCE_CONST_MEM pa_cannot_force_const_mem #undef TARGET_SECONDARY_RELOAD #define TARGET_SECONDARY_RELOAD pa_secondary_reload @@ -1563,6 +1564,14 @@ pa_tls_referenced_p (rtx x) return for_each_rtx (&x, &pa_tls_symbol_ref_1, 0); } +/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */ + +static bool +pa_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) +{ + return pa_tls_referenced_p (x); +} + /* Emit insns to move operands[1] into operands[0]. Return 1 if we have written out everything that needs to be done to diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 8182bf0b70d..201c2fb5cda 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1212,6 +1212,7 @@ static enum machine_mode rs6000_eh_return_filter_mode (void); static bool rs6000_can_eliminate (const int, const int); static void rs6000_conditional_register_usage (void); static void rs6000_trampoline_init (rtx, tree, rtx); +static bool rs6000_cannot_force_const_mem (enum machine_mode, rtx); /* Hash table stuff for keeping track of TOC entries. */ @@ -1388,7 +1389,7 @@ static const struct default_options rs6000_option_optimization_table[] = #define TARGET_HAVE_TLS HAVE_AS_TLS #undef TARGET_CANNOT_FORCE_CONST_MEM -#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p +#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem #undef TARGET_DELEGITIMIZE_ADDRESS #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address @@ -6619,6 +6620,14 @@ rs6000_tls_referenced_p (rtx x) return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0); } +/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */ + +static bool +rs6000_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) +{ + return rs6000_tls_referenced_p (x); +} + /* Return 1 if *X is a thread-local symbol. This is the same as rs6000_tls_symbol_ref except for the type of the unused argument. */ diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index caee07758fe..8454333f2ed 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -2810,7 +2810,7 @@ legitimate_constant_p (rtx op) not constant (TLS) or not known at final link time (PIC). */ static bool -s390_cannot_force_const_mem (rtx x) +s390_cannot_force_const_mem (enum machine_mode mode, rtx x) { switch (GET_CODE (x)) { @@ -2832,11 +2832,11 @@ s390_cannot_force_const_mem (rtx x) return flag_pic != 0; case CONST: - return s390_cannot_force_const_mem (XEXP (x, 0)); + return s390_cannot_force_const_mem (mode, XEXP (x, 0)); case PLUS: case MINUS: - return s390_cannot_force_const_mem (XEXP (x, 0)) - || s390_cannot_force_const_mem (XEXP (x, 1)); + return s390_cannot_force_const_mem (mode, XEXP (x, 0)) + || s390_cannot_force_const_mem (mode, XEXP (x, 1)); case UNSPEC: switch (XINT (x, 1)) diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 03b5e668f7b..b112f7e3d47 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -417,7 +417,7 @@ static void sparc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, static bool sparc_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT, const_tree); static struct machine_function * sparc_init_machine_status (void); -static bool sparc_cannot_force_const_mem (rtx); +static bool sparc_cannot_force_const_mem (enum machine_mode, rtx); static rtx sparc_tls_get_addr (void); static rtx sparc_tls_got (void); static const char *get_some_local_dynamic_name (void); @@ -2924,7 +2924,7 @@ reg_unused_after (rtx reg, rtx insn) not constant (TLS) or not known at final link time (PIC). */ static bool -sparc_cannot_force_const_mem (rtx x) +sparc_cannot_force_const_mem (enum machine_mode mode, rtx x) { switch (GET_CODE (x)) { @@ -2947,11 +2947,11 @@ sparc_cannot_force_const_mem (rtx x) return flag_pic != 0; case CONST: - return sparc_cannot_force_const_mem (XEXP (x, 0)); + return sparc_cannot_force_const_mem (mode, XEXP (x, 0)); case PLUS: case MINUS: - return sparc_cannot_force_const_mem (XEXP (x, 0)) - || sparc_cannot_force_const_mem (XEXP (x, 1)); + return sparc_cannot_force_const_mem (mode, XEXP (x, 0)) + || sparc_cannot_force_const_mem (mode, XEXP (x, 1)); case UNSPEC: return true; default: diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index fe70270df86..2ffc39f7fd1 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -164,6 +164,7 @@ static rtx xtensa_static_chain (const_tree, bool); static void xtensa_asm_trampoline_template (FILE *); static void xtensa_trampoline_init (rtx, tree, rtx); static bool xtensa_output_addr_const_extra (FILE *, rtx); +static bool xtensa_cannot_force_const_mem (enum machine_mode, rtx); static reg_class_t xtensa_preferred_reload_class (rtx, reg_class_t); static reg_class_t xtensa_preferred_output_reload_class (rtx, reg_class_t); @@ -285,7 +286,7 @@ static const struct default_options xtensa_option_optimization_table[] = #define TARGET_HAVE_TLS (TARGET_THREADPTR && HAVE_AS_TLS) #undef TARGET_CANNOT_FORCE_CONST_MEM -#define TARGET_CANNOT_FORCE_CONST_MEM xtensa_tls_referenced_p +#define TARGET_CANNOT_FORCE_CONST_MEM xtensa_cannot_force_const_mem #undef TARGET_LEGITIMATE_ADDRESS_P #define TARGET_LEGITIMATE_ADDRESS_P xtensa_legitimate_address_p @@ -2014,6 +2015,15 @@ xtensa_tls_referenced_p (rtx x) } +/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */ + +static bool +xtensa_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) +{ + return xtensa_tls_referenced_p (x); +} + + /* Return the debugger register number to use for 'regno'. */ int diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index de0381fcb1b..ec555517537 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -5553,10 +5553,12 @@ the semantics of these opaque @code{UNSPEC}s by converting them back into their original form. @end deftypefn -@deftypefn {Target Hook} bool TARGET_CANNOT_FORCE_CONST_MEM (rtx @var{x}) +@deftypefn {Target Hook} bool TARGET_CANNOT_FORCE_CONST_MEM (enum machine_mode @var{mode}, rtx @var{x}) This hook should return true if @var{x} is of a form that cannot (or -should not) be spilled to the constant pool. The default version of -this hook returns false. +should not) be spilled to the constant pool. @var{mode} is the mode +of @var{x}. + +The default version of this hook returns false. The primary reason to define this hook is to prevent reload from deciding that a non-legitimate constant would be better reloaded diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 8ae45957663..1c96941f643 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -5533,8 +5533,10 @@ into their original form. @hook TARGET_CANNOT_FORCE_CONST_MEM This hook should return true if @var{x} is of a form that cannot (or -should not) be spilled to the constant pool. The default version of -this hook returns false. +should not) be spilled to the constant pool. @var{mode} is the mode +of @var{x}. + +The default version of this hook returns false. The primary reason to define this hook is to prevent reload from deciding that a non-legitimate constant would be better reloaded diff --git a/gcc/hooks.c b/gcc/hooks.c index 594e34408bd..a991980a987 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -85,7 +85,7 @@ hook_bool_mode_true (enum machine_mode mode ATTRIBUTE_UNUSED) return true; } -/* Generic hook that takes (enum machine_mode, rtx) and returns false. */ +/* Generic hook that takes (enum machine_mode, const_rtx) and returns false. */ bool hook_bool_mode_const_rtx_false (enum machine_mode mode ATTRIBUTE_UNUSED, const_rtx value ATTRIBUTE_UNUSED) @@ -93,7 +93,7 @@ hook_bool_mode_const_rtx_false (enum machine_mode mode ATTRIBUTE_UNUSED, return false; } -/* Generic hook that takes (enum machine_mode, rtx) and returns true. */ +/* Generic hook that takes (enum machine_mode, const_rtx) and returns true. */ bool hook_bool_mode_const_rtx_true (enum machine_mode mode ATTRIBUTE_UNUSED, const_rtx value ATTRIBUTE_UNUSED) @@ -101,6 +101,14 @@ hook_bool_mode_const_rtx_true (enum machine_mode mode ATTRIBUTE_UNUSED, return true; } +/* Generic hook that takes (enum machine_mode, rtx) and returns false. */ +bool +hook_bool_mode_rtx_false (enum machine_mode mode ATTRIBUTE_UNUSED, + rtx value ATTRIBUTE_UNUSED) +{ + return false; +} + /* Generic hook that takes (FILE *, const char *) and does nothing. */ void hook_void_FILEptr_constcharptr (FILE *a ATTRIBUTE_UNUSED, const char *b ATTRIBUTE_UNUSED) diff --git a/gcc/hooks.h b/gcc/hooks.h index 90e3a14ae9a..548dad34751 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -34,6 +34,7 @@ extern bool hook_bool_mode_false (enum machine_mode); extern bool hook_bool_mode_true (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); +extern bool hook_bool_mode_rtx_false (enum machine_mode, rtx); extern bool hook_bool_tree_false (tree); extern bool hook_bool_const_tree_false (const_tree); extern bool hook_bool_tree_true (tree); diff --git a/gcc/reload.c b/gcc/reload.c index 582371f212d..372eccc0fb9 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -112,11 +112,13 @@ a register with any other reload. */ #include "target.h" #include "ira.h" -/* True if X is a constant that can be forced into the constant pool. */ -#define CONST_POOL_OK_P(X) \ - (CONSTANT_P (X) \ +/* True if X is a constant that can be forced into the constant pool. + MODE is the mode of the operand, or VOIDmode if not known. */ +#define CONST_POOL_OK_P(MODE, X) \ + ((MODE) != VOIDmode \ + && CONSTANT_P (X) \ && GET_CODE (X) != HIGH \ - && !targetm.cannot_force_const_mem (X)) + && !targetm.cannot_force_const_mem (MODE, X)) /* True if C is a non-empty register class that has too few registers to be safely used as a reload target class. */ @@ -3246,7 +3248,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, && REGNO (operand) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (operand)] < 0)) win = 1; - if (CONST_POOL_OK_P (operand)) + if (CONST_POOL_OK_P (operand_mode[i], operand)) badop = 0; constmemok = 1; break; @@ -3308,7 +3310,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, && offsettable_memref_p (reg_equiv_mem (REGNO (operand)))) || (reg_equiv_address (REGNO (operand)) != 0)))) win = 1; - if (CONST_POOL_OK_P (operand) + if (CONST_POOL_OK_P (operand_mode[i], operand) || MEM_P (operand)) badop = 0; constmemok = 1; @@ -3424,7 +3426,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, /* If we didn't already win, we can reload constants via force_const_mem, and other MEMs by reloading the address like for 'o'. */ - if (CONST_POOL_OK_P (operand) + if (CONST_POOL_OK_P (operand_mode[i], operand) || MEM_P (operand)) badop = 0; constmemok = 1; @@ -3503,12 +3505,11 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, an early reload pass. Note that the test here is precisely the same as in the code below that calls force_const_mem. */ - if (CONST_POOL_OK_P (operand) + if (CONST_POOL_OK_P (operand_mode[i], operand) && ((targetm.preferred_reload_class (operand, this_alternative[i]) == NO_REGS) - || no_input_reloads) - && operand_mode[i] != VOIDmode) + || no_input_reloads)) { const_to_mem = 1; if (this_alternative[i] != NO_REGS) @@ -3911,11 +3912,10 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, op = XEXP (op, 1); } - if (CONST_POOL_OK_P (op) + if (CONST_POOL_OK_P (mode, op) && ((targetm.preferred_reload_class (op, goal_alternative[i]) == NO_REGS) - || no_input_reloads) - && mode != VOIDmode) + || no_input_reloads)) { int this_address_reloaded; rtx tem = force_const_mem (mode, op); diff --git a/gcc/target.def b/gcc/target.def index b25ca270edd..ce01faa92d5 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -1295,8 +1295,8 @@ DEFHOOK DEFHOOK (cannot_force_const_mem, "", - bool, (rtx x), - hook_bool_rtx_false) + bool, (enum machine_mode mode, rtx x), + hook_bool_mode_rtx_false) DEFHOOK_UNDOC (cannot_copy_insn_p, diff --git a/gcc/varasm.c b/gcc/varasm.c index e60c95eafbe..8755dded36e 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -3476,7 +3476,7 @@ force_const_mem (enum machine_mode mode, rtx x) void **slot; /* If we're not allowed to drop X into the constant pool, don't. */ - if (targetm.cannot_force_const_mem (x)) + if (targetm.cannot_force_const_mem (mode, x)) return NULL_RTX; /* Record that this function has used a constant pool entry. */ -- 2.30.2