Commit 1d3dbd99 by Richard Sandiford Committed by Richard Sandiford

hooks.c (hook_bool_mode_rtx_true): New function.

	* hooks.c (hook_bool_mode_rtx_true): New function.
	* hooks.h (hook_bool_mode_rtx_true): Declare.
	* toplev.c (compile_file): Call output_shared_constant_pool.
	* varasm.c (shared_constant_pool): New variable.
	(assemble_start_function, assemble_end_function): Remove arguments
	from call to output_constant_pool.
	(create_constant_pool): New function, split out from...
	(init_varasm_status): ...here.
	(force_const_mem): Choose between the shared and per-function constant
	pools.  Set current_function_uses_const_pool when reusing old entries
	as well as when creating new ones.
	(mark_constant): Ignore data argument.
	(mark_constants): Remove pool argument.
	(mark_constant_pool): Likewise.  Use current_function_uses_const_pool
	to decide whether the function uses a constant pool.
	(output_constant_pool_contents): New function, split out from...
	(output_constant_pool): ...here.
	(output_shared_constant_pool): New function.
	(init_varasm_once): Initialize shared_constant_pool.
	* output.h (output_constant_pool): Delete.
	(output_shared_constant_pool): Declare.
	* config/s390/s390-protos.h (s390_output_constant_pool): Delete.
	* config/i386/i386.c (TARGET_USE_BLOCKS_FOR_CONSTANT_P): Override.

From-SVN: r111804
parent 06af4f5d
2006-03-07 Richard Sandiford <richard@codesourcery.com>
* hooks.c (hook_bool_mode_rtx_true): New function.
* hooks.h (hook_bool_mode_rtx_true): Declare.
* toplev.c (compile_file): Call output_shared_constant_pool.
* varasm.c (shared_constant_pool): New variable.
(assemble_start_function, assemble_end_function): Remove arguments
from call to output_constant_pool.
(create_constant_pool): New function, split out from...
(init_varasm_status): ...here.
(force_const_mem): Choose between the shared and per-function constant
pools. Set current_function_uses_const_pool when reusing old entries
as well as when creating new ones.
(mark_constant): Ignore data argument.
(mark_constants): Remove pool argument.
(mark_constant_pool): Likewise. Use current_function_uses_const_pool
to decide whether the function uses a constant pool.
(output_constant_pool_contents): New function, split out from...
(output_constant_pool): ...here.
(output_shared_constant_pool): New function.
(init_varasm_once): Initialize shared_constant_pool.
* output.h (output_constant_pool): Delete.
(output_shared_constant_pool): Declare.
* config/s390/s390-protos.h (s390_output_constant_pool): Delete.
* config/i386/i386.c (TARGET_USE_BLOCKS_FOR_CONSTANT_P): Override.
2006-03-06 Nick Clifton <nickc@redhat.com> 2006-03-06 Nick Clifton <nickc@redhat.com>
* config/m32r/m32r.h (OPTIMIZATION_OPTIONS): Remove reference to * config/m32r/m32r.h (OPTIMIZATION_OPTIONS): Remove reference to
......
...@@ -1261,6 +1261,8 @@ static section *x86_64_elf_select_section (tree decl, int reloc, ...@@ -1261,6 +1261,8 @@ static section *x86_64_elf_select_section (tree decl, int reloc,
#endif #endif
#undef TARGET_CANNOT_FORCE_CONST_MEM #undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM ix86_cannot_force_const_mem #define TARGET_CANNOT_FORCE_CONST_MEM ix86_cannot_force_const_mem
#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
#define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_rtx_true
#undef TARGET_DELEGITIMIZE_ADDRESS #undef TARGET_DELEGITIMIZE_ADDRESS
#define TARGET_DELEGITIMIZE_ADDRESS ix86_delegitimize_address #define TARGET_DELEGITIMIZE_ADDRESS ix86_delegitimize_address
......
...@@ -90,7 +90,6 @@ extern void s390_split_access_reg (rtx, rtx *, rtx *); ...@@ -90,7 +90,6 @@ extern void s390_split_access_reg (rtx, rtx *, rtx *);
extern bool s390_output_addr_const_extra (FILE*, rtx); extern bool s390_output_addr_const_extra (FILE*, rtx);
extern void print_operand_address (FILE *, rtx); extern void print_operand_address (FILE *, rtx);
extern void print_operand (FILE *, rtx, int); extern void print_operand (FILE *, rtx, int);
extern void s390_output_constant_pool (rtx, rtx);
extern void s390_output_pool_entry (rtx, enum machine_mode, unsigned int); extern void s390_output_pool_entry (rtx, enum machine_mode, unsigned int);
extern void s390_trampoline_template (FILE *); extern void s390_trampoline_template (FILE *);
extern void s390_initialize_trampoline (rtx, rtx, rtx); extern void s390_initialize_trampoline (rtx, rtx, rtx);
......
...@@ -77,6 +77,14 @@ hook_bool_mode_rtx_false (enum machine_mode mode ATTRIBUTE_UNUSED, ...@@ -77,6 +77,14 @@ hook_bool_mode_rtx_false (enum machine_mode mode ATTRIBUTE_UNUSED,
return false; return false;
} }
/* Generic hook that takes (enum machine_mode, rtx) and returns true. */
bool
hook_bool_mode_rtx_true (enum machine_mode mode ATTRIBUTE_UNUSED,
rtx value ATTRIBUTE_UNUSED)
{
return true;
}
/* Generic hook that takes (FILE *, const char *) and does nothing. */ /* Generic hook that takes (FILE *, const char *) and does nothing. */
void void
hook_void_FILEptr_constcharptr (FILE *a ATTRIBUTE_UNUSED, const char *b ATTRIBUTE_UNUSED) hook_void_FILEptr_constcharptr (FILE *a ATTRIBUTE_UNUSED, const char *b ATTRIBUTE_UNUSED)
......
...@@ -29,6 +29,7 @@ extern bool hook_bool_void_true (void); ...@@ -29,6 +29,7 @@ extern bool hook_bool_void_true (void);
extern bool hook_bool_bool_false (bool); extern bool hook_bool_bool_false (bool);
extern bool hook_bool_mode_false (enum machine_mode); extern bool hook_bool_mode_false (enum machine_mode);
extern bool hook_bool_mode_rtx_false (enum machine_mode, rtx); extern bool hook_bool_mode_rtx_false (enum machine_mode, rtx);
extern bool hook_bool_mode_rtx_true (enum machine_mode, rtx);
extern bool hook_bool_tree_false (tree); extern bool hook_bool_tree_false (tree);
extern bool hook_bool_tree_true (tree); extern bool hook_bool_tree_true (tree);
extern bool hook_bool_tree_hwi_hwi_tree_false (tree, HOST_WIDE_INT, HOST_WIDE_INT, extern bool hook_bool_tree_hwi_hwi_tree_false (tree, HOST_WIDE_INT, HOST_WIDE_INT,
......
...@@ -272,8 +272,7 @@ extern int get_pool_size (void); ...@@ -272,8 +272,7 @@ extern int get_pool_size (void);
extern rtx peephole (rtx); extern rtx peephole (rtx);
#endif #endif
/* Write all the constants in the constant pool. */ extern void output_shared_constant_pool (void);
extern void output_constant_pool (const char *, tree);
extern void output_object_blocks (void); extern void output_object_blocks (void);
......
...@@ -1022,6 +1022,7 @@ compile_file (void) ...@@ -1022,6 +1022,7 @@ compile_file (void)
if (flag_mudflap) if (flag_mudflap)
mudflap_finish_file (); mudflap_finish_file ();
output_shared_constant_pool ();
output_object_blocks (); output_object_blocks ();
/* Write out any pending weak symbol declarations. */ /* Write out any pending weak symbol declarations. */
......
...@@ -139,6 +139,7 @@ static void asm_output_aligned_bss (FILE *, tree, const char *, ...@@ -139,6 +139,7 @@ static void asm_output_aligned_bss (FILE *, tree, const char *,
#endif #endif
#endif /* BSS_SECTION_ASM_OP */ #endif /* BSS_SECTION_ASM_OP */
static void mark_weak (tree); static void mark_weak (tree);
static void output_constant_pool (void);
/* Well-known sections, each one associated with some sort of *_ASM_OP. */ /* Well-known sections, each one associated with some sort of *_ASM_OP. */
section *text_section; section *text_section;
...@@ -196,6 +197,9 @@ static GTY((param_is (struct object_block))) htab_t object_block_htab; ...@@ -196,6 +197,9 @@ static GTY((param_is (struct object_block))) htab_t object_block_htab;
/* The next number to use for internal anchor labels. */ /* The next number to use for internal anchor labels. */
static GTY(()) int anchor_labelno; static GTY(()) int anchor_labelno;
/* A pool of constants that can be shared between functions. */
static GTY(()) struct rtx_constant_pool *shared_constant_pool;
/* Helper routines for maintaining section_htab. */ /* Helper routines for maintaining section_htab. */
static int static int
...@@ -1328,7 +1332,7 @@ assemble_start_function (tree decl, const char *fnname) ...@@ -1328,7 +1332,7 @@ assemble_start_function (tree decl, const char *fnname)
app_disable (); app_disable ();
if (CONSTANT_POOL_BEFORE_FUNCTION) if (CONSTANT_POOL_BEFORE_FUNCTION)
output_constant_pool (fnname, decl); output_constant_pool ();
resolve_unique_section (decl, 0, flag_function_sections); resolve_unique_section (decl, 0, flag_function_sections);
...@@ -1446,7 +1450,7 @@ assemble_end_function (tree decl, const char *fnname) ...@@ -1446,7 +1450,7 @@ assemble_end_function (tree decl, const char *fnname)
#endif #endif
if (! CONSTANT_POOL_BEFORE_FUNCTION) if (! CONSTANT_POOL_BEFORE_FUNCTION)
{ {
output_constant_pool (fnname, decl); output_constant_pool ();
switch_to_section (function_section (decl)); /* need to switch back */ switch_to_section (function_section (decl)); /* need to switch back */
} }
/* Output labels for end of hot/cold text sections (to be used by /* Output labels for end of hot/cold text sections (to be used by
...@@ -3122,25 +3126,34 @@ const_rtx_hash (rtx x) ...@@ -3122,25 +3126,34 @@ const_rtx_hash (rtx x)
} }
/* Create and return a new rtx constant pool. */
static struct rtx_constant_pool *
create_constant_pool (void)
{
struct rtx_constant_pool *pool;
pool = ggc_alloc (sizeof (struct rtx_constant_pool));
pool->const_rtx_htab = htab_create_ggc (31, const_desc_rtx_hash,
const_desc_rtx_eq, NULL);
pool->first = NULL;
pool->last = NULL;
pool->offset = 0;
return pool;
}
/* Initialize constant pool hashing for a new function. */ /* Initialize constant pool hashing for a new function. */
void void
init_varasm_status (struct function *f) init_varasm_status (struct function *f)
{ {
struct varasm_status *p; struct varasm_status *p;
struct rtx_constant_pool *pool;
p = ggc_alloc (sizeof (struct varasm_status)); p = ggc_alloc (sizeof (struct varasm_status));
f->varasm = p; f->varasm = p;
pool = ggc_alloc (sizeof (struct rtx_constant_pool)); p->pool = create_constant_pool ();
p->pool = pool;
p->deferred_constants = 0; p->deferred_constants = 0;
pool->const_rtx_htab = htab_create_ggc (31, const_desc_rtx_hash,
const_desc_rtx_eq, NULL);
pool->first = pool->last = NULL;
pool->offset = 0;
} }
/* Given a MINUS expression, simplify it if both sides /* Given a MINUS expression, simplify it if both sides
...@@ -3160,7 +3173,7 @@ rtx ...@@ -3160,7 +3173,7 @@ rtx
force_const_mem (enum machine_mode mode, rtx x) force_const_mem (enum machine_mode mode, rtx x)
{ {
struct constant_descriptor_rtx *desc, tmp; struct constant_descriptor_rtx *desc, tmp;
struct rtx_constant_pool *pool = cfun->varasm->pool; struct rtx_constant_pool *pool;
char label[256]; char label[256];
rtx def, symbol; rtx def, symbol;
hashval_t hash; hashval_t hash;
...@@ -3171,6 +3184,14 @@ force_const_mem (enum machine_mode mode, rtx x) ...@@ -3171,6 +3184,14 @@ force_const_mem (enum machine_mode mode, rtx x)
if (targetm.cannot_force_const_mem (x)) if (targetm.cannot_force_const_mem (x))
return NULL_RTX; return NULL_RTX;
/* Record that this function has used a constant pool entry. */
current_function_uses_const_pool = 1;
/* Decide which pool to use. */
pool = (targetm.use_blocks_for_constant_p (mode, x)
? shared_constant_pool
: cfun->varasm->pool);
/* Lookup the value in the hashtable. */ /* Lookup the value in the hashtable. */
tmp.constant = x; tmp.constant = x;
tmp.mode = mode; tmp.mode = mode;
...@@ -3233,7 +3254,6 @@ force_const_mem (enum machine_mode mode, rtx x) ...@@ -3233,7 +3254,6 @@ force_const_mem (enum machine_mode mode, rtx x)
SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LOCAL; SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LOCAL;
CONSTANT_POOL_ADDRESS_P (symbol) = 1; CONSTANT_POOL_ADDRESS_P (symbol) = 1;
SET_SYMBOL_REF_CONSTANT (symbol, desc); SET_SYMBOL_REF_CONSTANT (symbol, desc);
current_function_uses_const_pool = 1;
/* Construct the MEM. */ /* Construct the MEM. */
desc->mem = def = gen_const_mem (mode, symbol); desc->mem = def = gen_const_mem (mode, symbol);
...@@ -3404,9 +3424,8 @@ output_constant_pool_1 (struct constant_descriptor_rtx *desc, ...@@ -3404,9 +3424,8 @@ output_constant_pool_1 (struct constant_descriptor_rtx *desc,
be used with for_each_rtx to mark all SYMBOL_REFs in an rtx. */ be used with for_each_rtx to mark all SYMBOL_REFs in an rtx. */
static int static int
mark_constant (rtx *current_rtx, void *data) mark_constant (rtx *current_rtx, void *data ATTRIBUTE_UNUSED)
{ {
struct rtx_constant_pool *pool = data;
rtx x = *current_rtx; rtx x = *current_rtx;
if (x == NULL_RTX || GET_CODE (x) != SYMBOL_REF) if (x == NULL_RTX || GET_CODE (x) != SYMBOL_REF)
...@@ -3418,7 +3437,7 @@ mark_constant (rtx *current_rtx, void *data) ...@@ -3418,7 +3437,7 @@ mark_constant (rtx *current_rtx, void *data)
if (desc->mark == 0) if (desc->mark == 0)
{ {
desc->mark = 1; desc->mark = 1;
for_each_rtx (&desc->constant, mark_constant, pool); for_each_rtx (&desc->constant, mark_constant, NULL);
} }
} }
else if (TREE_CONSTANT_POOL_ADDRESS_P (x)) else if (TREE_CONSTANT_POOL_ADDRESS_P (x))
...@@ -3440,7 +3459,7 @@ mark_constant (rtx *current_rtx, void *data) ...@@ -3440,7 +3459,7 @@ mark_constant (rtx *current_rtx, void *data)
deferred strings that are used. */ deferred strings that are used. */
static void static void
mark_constants (struct rtx_constant_pool *pool, rtx insn) mark_constants (rtx insn)
{ {
if (!INSN_P (insn)) if (!INSN_P (insn))
return; return;
...@@ -3456,11 +3475,11 @@ mark_constants (struct rtx_constant_pool *pool, rtx insn) ...@@ -3456,11 +3475,11 @@ mark_constants (struct rtx_constant_pool *pool, rtx insn)
{ {
rtx subinsn = XVECEXP (seq, 0, i); rtx subinsn = XVECEXP (seq, 0, i);
if (INSN_P (subinsn)) if (INSN_P (subinsn))
for_each_rtx (&PATTERN (subinsn), mark_constant, pool); for_each_rtx (&PATTERN (subinsn), mark_constant, NULL);
} }
} }
else else
for_each_rtx (&PATTERN (insn), mark_constant, pool); for_each_rtx (&PATTERN (insn), mark_constant, NULL);
} }
/* Look through the instructions for this function, and mark all the /* Look through the instructions for this function, and mark all the
...@@ -3468,40 +3487,29 @@ mark_constants (struct rtx_constant_pool *pool, rtx insn) ...@@ -3468,40 +3487,29 @@ mark_constants (struct rtx_constant_pool *pool, rtx insn)
which have indeed been used. */ which have indeed been used. */
static void static void
mark_constant_pool (struct rtx_constant_pool *pool) mark_constant_pool (void)
{ {
rtx insn, link; rtx insn, link;
if (pool->first == 0 && n_deferred_constants == 0) if (!current_function_uses_const_pool && n_deferred_constants == 0)
return; return;
for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
mark_constants (pool, insn); mark_constants (insn);
for (link = current_function_epilogue_delay_list; for (link = current_function_epilogue_delay_list;
link; link;
link = XEXP (link, 1)) link = XEXP (link, 1))
mark_constants (pool, XEXP (link, 0)); mark_constants (XEXP (link, 0));
} }
/* Write all the constants in the constant pool. */ /* Write all the constants in POOL. */
void static void
output_constant_pool (const char *fnname ATTRIBUTE_UNUSED, output_constant_pool_contents (struct rtx_constant_pool *pool)
tree fndecl ATTRIBUTE_UNUSED)
{ {
struct rtx_constant_pool *pool = cfun->varasm->pool;
struct constant_descriptor_rtx *desc; struct constant_descriptor_rtx *desc;
/* It is possible for gcc to call force_const_mem and then to later
discard the instructions which refer to the constant. In such a
case we do not need to output the constant. */
mark_constant_pool (pool);
#ifdef ASM_OUTPUT_POOL_PROLOGUE
ASM_OUTPUT_POOL_PROLOGUE (asm_out_file, fnname, fndecl, pool->offset);
#endif
for (desc = pool->first; desc ; desc = desc->next) for (desc = pool->first; desc ; desc = desc->next)
if (desc->mark) if (desc->mark)
{ {
...@@ -3519,12 +3527,40 @@ output_constant_pool (const char *fnname ATTRIBUTE_UNUSED, ...@@ -3519,12 +3527,40 @@ output_constant_pool (const char *fnname ATTRIBUTE_UNUSED,
output_constant_pool_1 (desc, desc->align); output_constant_pool_1 (desc, desc->align);
} }
} }
}
/* Mark all constants that are used in the current function, then write
out the function's private constant pool. */
static void
output_constant_pool (void)
{
struct rtx_constant_pool *pool = cfun->varasm->pool;
/* It is possible for gcc to call force_const_mem and then to later
discard the instructions which refer to the constant. In such a
case we do not need to output the constant. */
mark_constant_pool ();
#ifdef ASM_OUTPUT_POOL_PROLOGUE
ASM_OUTPUT_POOL_PROLOGUE (asm_out_file, fnname, fndecl, pool->offset);
#endif
output_constant_pool_contents (pool);
#ifdef ASM_OUTPUT_POOL_EPILOGUE #ifdef ASM_OUTPUT_POOL_EPILOGUE
ASM_OUTPUT_POOL_EPILOGUE (asm_out_file, fnname, fndecl, pool->offset); ASM_OUTPUT_POOL_EPILOGUE (asm_out_file, fnname, fndecl, pool->offset);
#endif #endif
} }
/* Write the contents of the shared constant pool. */
void
output_shared_constant_pool (void)
{
output_constant_pool_contents (shared_constant_pool);
}
/* Determine what kind of relocations EXP may need. */ /* Determine what kind of relocations EXP may need. */
int int
...@@ -5064,6 +5100,7 @@ init_varasm_once (void) ...@@ -5064,6 +5100,7 @@ init_varasm_once (void)
const_desc_eq, NULL); const_desc_eq, NULL);
const_alias_set = new_alias_set (); const_alias_set = new_alias_set ();
shared_constant_pool = create_constant_pool ();
#ifdef TEXT_SECTION_ASM_OP #ifdef TEXT_SECTION_ASM_OP
text_section = get_unnamed_section (SECTION_CODE, output_section_asm_op, text_section = get_unnamed_section (SECTION_CODE, output_section_asm_op,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment