target.h (gcc_target): Add cannot_force_const_mem.

* 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.

From-SVN: r59971
This commit is contained in:
Richard Henderson 2002-12-09 15:54:01 -08:00 committed by Richard Henderson
parent a9a4005fca
commit 3a04ff6433
10 changed files with 111 additions and 25 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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;
}
}

View File

@ -114,3 +114,10 @@ hook_bool_tree_false (a)
{
return false;
}
bool
hook_bool_rtx_false (a)
rtx a ATTRIBUTE_UNUSED;
{
return false;
}

View File

@ -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));

View File

@ -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;

View File

@ -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, \

View File

@ -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));

View File

@ -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-*-* } } } */

View File

@ -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);