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:
parent
a9a4005fca
commit
3a04ff6433
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -114,3 +114,10 @@ hook_bool_tree_false (a)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
hook_bool_rtx_false (a)
|
||||
rtx a ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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, \
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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-*-* } } } */
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue