aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2002-12-09 23:54:01 +0000
committerRichard Henderson <rth@redhat.com>2002-12-09 23:54:01 +0000
commitd72db3bfb6d80eba4438ce364400cc064c33f82e (patch)
tree57341f6e2c1ac600113f5797665b9c84f0d000d3
parentee23abdcf9f324ad7cb38f05cf39fb6ed30fd566 (diff)
* target.h (gcc_target): Add cannot_force_const_mem.
* target-def.h (TARGET_CANNOT_FORCE_CONST_MEM): New. (TARGET_INITIALIZER): Add it. * varasm.c (force_const_mem): Fail if cannot_force_const_mem. * expr.c (emit_move_insn): Be prepared for force_const_mem to fail. * reload1.c (reload): Likewise. * hooks.c (hook_bool_rtx_false): New. * hooks.h: Declare it. * config/i386/i386.c (ix86_cannot_force_const_mem): New. (TARGET_CANNOT_FORCE_CONST_MEM): New. (ix86_expand_move): Remove de-const-pooling hack. * gcc.dg/tls/opt-4.c: New. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@59971 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/config/i386/i386.c37
-rw-r--r--gcc/expr.c6
-rw-r--r--gcc/hooks.c7
-rw-r--r--gcc/hooks.h1
-rw-r--r--gcc/reload1.c8
-rw-r--r--gcc/target-def.h2
-rw-r--r--gcc/target.h3
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-4.c53
-rw-r--r--gcc/varasm.c4
10 files changed, 111 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 770112f3d7f..0b812c18a53 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2002-12-09 Richard Henderson <rth@redhat.com>
+
+ * target.h (gcc_target): Add cannot_force_const_mem.
+ * target-def.h (TARGET_CANNOT_FORCE_CONST_MEM): New.
+ (TARGET_INITIALIZER): Add it.
+ * varasm.c (force_const_mem): Fail if cannot_force_const_mem.
+ * expr.c (emit_move_insn): Be prepared for force_const_mem to fail.
+ * reload1.c (reload): Likewise.
+ * hooks.c (hook_bool_rtx_false): New.
+ * hooks.h: Declare it.
+
+ * config/i386/i386.c (ix86_cannot_force_const_mem): New.
+ (TARGET_CANNOT_FORCE_CONST_MEM): New.
+ (ix86_expand_move): Remove de-const-pooling hack.
+
Mon Dec 9 21:33:38 CET 2002 Jan Hubicka <jh@suse.cz>
* toplev.c (dump_file): Fix order to match reality.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 7337312ac8e..42f6d93d3c3 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -763,6 +763,7 @@ struct ix86_address
};
static int ix86_decompose_address PARAMS ((rtx, struct ix86_address *));
+static bool ix86_cannot_force_const_mem PARAMS ((rtx));
static void ix86_encode_section_info PARAMS ((tree, int)) ATTRIBUTE_UNUSED;
static const char *ix86_strip_name_encoding PARAMS ((const char *))
@@ -900,6 +901,8 @@ static enum x86_64_reg_class merge_classes PARAMS ((enum x86_64_reg_class,
#undef TARGET_HAVE_TLS
#define TARGET_HAVE_TLS true
#endif
+#undef TARGET_CANNOT_FORCE_CONST_MEM
+#define TARGET_CANNOT_FORCE_CONST_MEM ix86_cannot_force_const_mem
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
@@ -5050,6 +5053,17 @@ legitimate_constant_p (x)
return true;
}
+/* Determine if it's legal to put X into the constant pool. This
+ is not possible for the address of thread-local symbols, which
+ is checked above. */
+
+static bool
+ix86_cannot_force_const_mem (x)
+ rtx x;
+{
+ return !legitimate_constant_p (x);
+}
+
/* Determine if a given RTX is a valid constant address. */
bool
@@ -7686,29 +7700,6 @@ ix86_expand_move (mode, operands)
op0 = operands[0];
op1 = operands[1];
- /* ??? We have a slight problem. We need to say that tls symbols are
- not legitimate constants so that reload does not helpfully reload
- these constants from a REG_EQUIV, which we cannot handle. (Recall
- that general- and local-dynamic address resolution requires a
- function call.)
-
- However, if we say that tls symbols are not legitimate constants,
- then emit_move_insn helpfully drop them into the constant pool.
-
- It is far easier to work around emit_move_insn than reload. Recognize
- the MEM that we would have created and extract the symbol_ref. */
-
- if (mode == Pmode
- && GET_CODE (op1) == MEM
- && RTX_UNCHANGING_P (op1))
- {
- tmp = maybe_get_pool_constant (op1);
- /* Note that we only care about symbolic constants here, which
- unlike CONST_INT will always have a proper mode. */
- if (tmp && GET_MODE (tmp) == Pmode)
- op1 = tmp;
- }
-
if (tls_symbolic_operand (op1, Pmode))
{
op1 = legitimize_address (op1, op1, VOIDmode);
diff --git a/gcc/expr.c b/gcc/expr.c
index 85d329f9ffc..f1b2271edd8 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -3146,6 +3146,12 @@ emit_move_insn (x, y)
{
y_cst = y;
y = force_const_mem (mode, y);
+
+ /* If the target's cannot_force_const_mem prevented the spill,
+ assume that the target's move expanders will also take care
+ of the non-legitimate constant. */
+ if (!y)
+ y = y_cst;
}
}
diff --git a/gcc/hooks.c b/gcc/hooks.c
index 6569a38d7a0..3f212ef3e1b 100644
--- a/gcc/hooks.c
+++ b/gcc/hooks.c
@@ -114,3 +114,10 @@ hook_bool_tree_false (a)
{
return false;
}
+
+bool
+hook_bool_rtx_false (a)
+ rtx a ATTRIBUTE_UNUSED;
+{
+ return false;
+}
diff --git a/gcc/hooks.h b/gcc/hooks.h
index 4e09da932a3..8c28194f6ac 100644
--- a/gcc/hooks.h
+++ b/gcc/hooks.h
@@ -28,6 +28,7 @@ bool hook_bool_tree_hwi_hwi_tree_false
PARAMS ((tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
bool hook_bool_tree_hwi_hwi_tree_true
PARAMS ((tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
+bool hook_bool_rtx_false PARAMS ((rtx));
void hook_void_tree_int PARAMS ((tree, int));
void hook_void_void PARAMS ((void));
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 2704dadab4d..0f5d688c8a5 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -817,8 +817,12 @@ reload (first, global)
else if (LEGITIMATE_CONSTANT_P (x))
reg_equiv_constant[i] = x;
else
- reg_equiv_memory_loc[i]
- = force_const_mem (GET_MODE (SET_DEST (set)), x);
+ {
+ reg_equiv_memory_loc[i]
+ = force_const_mem (GET_MODE (SET_DEST (set)), x);
+ if (!reg_equiv_memory_loc[i])
+ continue;
+ }
}
else
continue;
diff --git a/gcc/target-def.h b/gcc/target-def.h
index b866c858de7..154d58d47e9 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -241,6 +241,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/* In hook.c. */
#define TARGET_CANNOT_MODIFY_JUMPS_P hook_bool_void_false
+#define TARGET_CANNOT_FORCE_CONST_MEM hook_bool_rtx_false
#define TARGET_COMP_TYPE_ATTRIBUTES hook_int_tree_tree_1
#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES hook_void_tree
#define TARGET_INSERT_ATTRIBUTES hook_void_tree_treeptr
@@ -272,6 +273,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
TARGET_EXPAND_BUILTIN, \
TARGET_SECTION_TYPE_FLAGS, \
TARGET_CANNOT_MODIFY_JUMPS_P, \
+ TARGET_CANNOT_FORCE_CONST_MEM, \
TARGET_IN_SMALL_DATA_P, \
TARGET_BINDS_LOCAL_P, \
TARGET_ENCODE_SECTION_INFO, \
diff --git a/gcc/target.h b/gcc/target.h
index d9475625414..0ac1c5aa17b 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -262,6 +262,9 @@ struct gcc_target
not, at the current point in the compilation. */
bool (* cannot_modify_jumps_p) PARAMS ((void));
+ /* True if the constant X cannot be placed in the constant pool. */
+ bool (* cannot_force_const_mem) PARAMS ((rtx));
+
/* True if EXP should be placed in a "small data" section. */
bool (* in_small_data_p) PARAMS ((tree));
diff --git a/gcc/testsuite/gcc.dg/tls/opt-4.c b/gcc/testsuite/gcc.dg/tls/opt-4.c
new file mode 100644
index 00000000000..3a95688963b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-4.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct A
+{
+ int a1;
+ int a2;
+};
+
+extern __thread const unsigned char *tcc1, **tcc2;
+
+extern inline const unsigned char ** __attribute__ ((const))
+foo (void)
+{
+ const unsigned char **a = &tcc1;
+ if (*a == 0)
+ *a = *tcc2 + 128;
+ return a;
+}
+
+extern inline int
+bar (const struct A *x)
+{
+ int a;
+
+ if (x->a2 & 8)
+ return 0;
+ a = x->a1;
+ return a > 0 && ((*foo ())[a] & 64);
+}
+
+int
+baz (const struct A *x, char *y)
+{
+ const struct A *a;
+
+ for (a = x; !!a->a1; a++)
+ if (! (x->a2 & 8))
+ if (bar (a))
+ {
+ *y++ = a->a1;
+ if (x->a1)
+ *y++ = ':';
+ *y = '\0';
+ }
+ return 0;
+}
+
+/* Verify tcc1 and tcc2 variables show up only in the TLS access sequences. */
+/* { dg-final { scan-assembler "tcc1@" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-assembler "tcc2@" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-assembler-not "tcc1\[^@\]" { target i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-assembler-not "tcc2\[^@\]" { target i?86-*-* x86_64-*-* } } } */
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 2ac3da5338c..f8b33d080a6 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -3209,6 +3209,10 @@ force_const_mem (mode, x)
struct pool_constant *pool;
unsigned int align;
+ /* If we're not allowed to drop X into the constant pool, don't. */
+ if ((*targetm.cannot_force_const_mem) (x))
+ return NULL_RTX;
+
/* Compute hash code of X. Search the descriptors for that hash code
to see if any of them describes X. If yes, we have an rtx to use. */
hash = const_hash_rtx (mode, x);