Patchwork Add a mode argument to cannot_force_const_mem

login
register
mail settings
Submitter Richard Sandiford
Date April 4, 2011, 9:15 a.m.
Message ID <g4ipuujs1s.fsf@linaro.org>
Download mbox | patch
Permalink /patch/89601/
State New
Headers show

Comments

Richard Sandiford - April 4, 2011, 9:15 a.m.
I'm about to post a patch that adds a mode argument to LEGITIMATE_CONSTANT_P.
Since LEGITIMATE_CONSTANT_P is closely associated with force_const_mem
(by explicit calls on some targets), I thought I'd better add a mode
argument there too.  The mode argument will be used more after that
L_C_P patch.

Tested by building all-gcc for these targets:

    alpha-linux-gnu arm-linux-gnueabi avr-rtems bfin-elf cris-elf
    fr30-elf frv-linux-gnu h8300-elf ia64-linux-gnu iq2000-elf
    lm32-elf m32c-elf m32r-elf m68k-linux-gnu mcore-elf mep-elf
    microblaze-elf mips-linux-gnu mmix mn10300-elf moxie-elf
    hppa64-hp-hpux11.23 pdp11 picochip-elf powerpc-linux-gnu
    rx-elf s390-linux-gnu score-elf sh-linux-gnu sparc-linux-gnu
    spu-elf xstormy16-elf v850-elf vax-netbsdelf xtensa-elf

and making sure that the output for gcc.dg, gcc.c-torture and g++.dg
didn't change.  I also checked that there were no new warnings in
the build log.

Also tested on arm-linux-gnueabi in the normal way.  OK to install?

Richard


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.

Patch

Index: gcc/target.def
===================================================================
--- gcc/target.def	2011-04-04 09:12:11.000000000 +0100
+++ gcc/target.def	2011-04-04 09:12:32.000000000 +0100
@@ -1348,8 +1348,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,
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	2011-04-04 09:12:11.000000000 +0100
+++ gcc/doc/tm.texi.in	2011-04-04 09:12:32.000000000 +0100
@@ -5527,8 +5527,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
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	2011-04-04 09:12:11.000000000 +0100
+++ gcc/doc/tm.texi	2011-04-04 09:12:32.000000000 +0100
@@ -5573,10 +5573,12 @@  the semantics of these opaque @code{UNSP
 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
Index: gcc/hooks.h
===================================================================
--- gcc/hooks.h	2011-04-04 09:12:11.000000000 +0100
+++ gcc/hooks.h	2011-04-04 09:12:56.000000000 +0100
@@ -34,6 +34,7 @@  extern bool hook_bool_mode_false (enum m
 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_mode_uhwi_false (enum machine_mode,
 				       unsigned HOST_WIDE_INT);
 extern bool hook_bool_tree_false (tree);
Index: gcc/hooks.c
===================================================================
--- gcc/hooks.c	2011-04-04 09:12:11.000000000 +0100
+++ gcc/hooks.c	2011-04-04 09:12:32.000000000 +0100
@@ -85,7 +85,7 @@  hook_bool_mode_true (enum machine_mode m
   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 mac
   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)
@@ -110,6 +110,14 @@  hook_bool_mode_uhwi_false (enum machine_
   return false;
 }
 
+/* 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)
Index: gcc/reload.c
===================================================================
--- gcc/reload.c	2011-04-04 09:12:11.000000000 +0100
+++ gcc/reload.c	2011-04-04 09:12:32.000000000 +0100
@@ -112,11 +112,13 @@  #define REG_OK_STRICT
 #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
 			&& 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
 			     && 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
 			/* 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
 		 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
 	    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);
Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c	2011-04-04 09:12:11.000000000 +0100
+++ gcc/varasm.c	2011-04-04 09:12:32.000000000 +0100
@@ -3508,7 +3508,7 @@  force_const_mem (enum machine_mode mode,
   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.  */
Index: gcc/config/alpha/alpha.c
===================================================================
--- gcc/config/alpha/alpha.c	2011-04-04 09:12:11.000000000 +0100
+++ gcc/config/alpha/alpha.c	2011-04-04 09:12:32.000000000 +0100
@@ -1095,7 +1095,7 @@  alpha_legitimize_address (rtx x, rtx old
    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;
Index: gcc/config/arm/arm-protos.h
===================================================================
--- gcc/config/arm/arm-protos.h	2011-04-04 09:12:11.000000000 +0100
+++ gcc/config/arm/arm-protos.h	2011-04-04 09:12:32.000000000 +0100
@@ -81,7 +81,7 @@  extern void neon_disambiguate_copy (rtx 
 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);
Index: gcc/config/arm/arm.h
===================================================================
--- gcc/config/arm/arm.h	2011-04-04 09:12:11.000000000 +0100
+++ gcc/config/arm/arm.h	2011-04-04 09:12:32.000000000 +0100
@@ -1772,7 +1772,7 @@  #define THUMB_LEGITIMATE_CONSTANT_P(X)	\
   || 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)))
 
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	2011-04-04 09:12:11.000000000 +0100
+++ gcc/config/arm/arm.c	2011-04-04 09:12:32.000000000 +0100
@@ -6555,7 +6555,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;
 
Index: gcc/config/bfin/bfin.c
===================================================================
--- gcc/config/bfin/bfin.c	2011-04-04 09:12:11.000000000 +0100
+++ gcc/config/bfin/bfin.c	2011-04-04 09:12:32.000000000 +0100
@@ -3055,7 +3055,8 @@  bfin_legitimate_address_p (enum machine_
    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
Index: gcc/config/frv/frv.c
===================================================================
--- gcc/config/frv/frv.c	2011-04-04 09:12:11.000000000 +0100
+++ gcc/config/frv/frv.c	2011-04-04 09:12:32.000000000 +0100
@@ -372,7 +372,7 @@  static int frv_memory_move_cost			(enum 
 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_un
    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;
 }
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	2011-04-04 09:12:11.000000000 +0100
+++ gcc/config/i386/i386.c	2011-04-04 09:12:32.000000000 +0100
@@ -12020,7 +12020,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))
Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c	2011-04-04 09:12:11.000000000 +0100
+++ gcc/config/ia64/ia64.c	2011-04-04 09:12:32.000000000 +0100
@@ -316,7 +316,7 @@  static rtx ia64_struct_value_rtx (tree, 
 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;
 }
Index: gcc/config/m68k/m68k.c
===================================================================
--- gcc/config/m68k/m68k.c	2011-04-04 09:06:23.000000000 +0100
+++ gcc/config/m68k/m68k.c	2011-04-04 09:12:32.000000000 +0100
@@ -163,6 +163,7 @@  static void m68k_function_arg_advance (C
 				       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 @@  #define TARGET_PROMOTE_PROTOTYPES hook_b
 #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
@@ -1982,6 +1983,14 @@  m68k_illegitimate_symbolic_constant_p (r
   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.  */
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	2011-04-04 09:12:11.000000000 +0100
+++ gcc/config/mips/mips.c	2011-04-04 09:12:32.000000000 +0100
@@ -1997,7 +1997,7 @@  mips_tls_symbol_ref_1 (rtx *x, void *dat
 /* 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
      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);
@@ -11080,7 +11080,7 @@  mips_secondary_reload_class (enum reg_cl
 	/* 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.  */
Index: gcc/config/pa/pa.c
===================================================================
--- gcc/config/pa/pa.c	2011-04-04 09:06:23.000000000 +0100
+++ gcc/config/pa/pa.c	2011-04-04 09:12:32.000000000 +0100
@@ -187,6 +187,7 @@  static bool pa_can_eliminate (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 @@  #define TARGET_GIMPLIFY_VA_ARG_EXPR hppa
 #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
@@ -1590,6 +1591,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
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	2011-04-04 09:06:23.000000000 +0100
+++ gcc/config/rs6000/rs6000.c	2011-04-04 09:12:32.000000000 +0100
@@ -1212,6 +1212,7 @@  static enum machine_mode rs6000_eh_retur
 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 @@  #define TARGET_ASM_ASSEMBLE_VISIBILITY r
 #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.  */
 
Index: gcc/config/s390/s390.c
===================================================================
--- gcc/config/s390/s390.c	2011-04-04 09:12:11.000000000 +0100
+++ gcc/config/s390/s390.c	2011-04-04 09:12:32.000000000 +0100
@@ -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))
Index: gcc/config/sparc/sparc.c
===================================================================
--- gcc/config/sparc/sparc.c	2011-04-04 09:12:11.000000000 +0100
+++ gcc/config/sparc/sparc.c	2011-04-04 09:12:32.000000000 +0100
@@ -417,7 +417,7 @@  static void sparc_output_mi_thunk (FILE 
 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);
@@ -2920,7 +2920,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))
     {
@@ -2943,11 +2943,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:
Index: gcc/config/xtensa/xtensa.c
===================================================================
--- gcc/config/xtensa/xtensa.c	2011-04-04 09:06:23.000000000 +0100
+++ gcc/config/xtensa/xtensa.c	2011-04-04 09:12:32.000000000 +0100
@@ -164,6 +164,7 @@  static rtx xtensa_static_chain (const_tr
 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 @@  #define TARGET_SECONDARY_RELOAD xtensa_s
 #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
@@ -2016,6 +2017,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