From 1d3dbd99b6a956e8fac57bd0c96470a9667fa469 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 7 Mar 2006 07:41:39 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 26 ++++++++ gcc/config/i386/i386.c | 2 + gcc/config/s390/s390-protos.h | 1 - gcc/hooks.c | 8 +++ gcc/hooks.h | 1 + gcc/output.h | 3 +- gcc/toplev.c | 1 + gcc/varasm.c | 109 +++++++++++++++++++++++----------- 8 files changed, 112 insertions(+), 39 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d8ecfa7cd2e..fcdd12b2d55 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,29 @@ +2006-03-07 Richard Sandiford + + * 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 * config/m32r/m32r.h (OPTIMIZATION_OPTIONS): Remove reference to diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 7758f430a14..bf792a91403 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1261,6 +1261,8 @@ static section *x86_64_elf_select_section (tree decl, int reloc, #endif #undef TARGET_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 #define TARGET_DELEGITIMIZE_ADDRESS ix86_delegitimize_address diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 710f4e750a5..460fac6d086 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -90,7 +90,6 @@ extern void s390_split_access_reg (rtx, rtx *, rtx *); extern bool s390_output_addr_const_extra (FILE*, rtx); extern void print_operand_address (FILE *, rtx); 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_trampoline_template (FILE *); extern void s390_initialize_trampoline (rtx, rtx, rtx); diff --git a/gcc/hooks.c b/gcc/hooks.c index 8a708777113..18b17dc85f2 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -77,6 +77,14 @@ hook_bool_mode_rtx_false (enum machine_mode mode ATTRIBUTE_UNUSED, 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. */ void hook_void_FILEptr_constcharptr (FILE *a ATTRIBUTE_UNUSED, const char *b ATTRIBUTE_UNUSED) diff --git a/gcc/hooks.h b/gcc/hooks.h index a1053e9875f..02664c12803 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -29,6 +29,7 @@ extern bool hook_bool_void_true (void); extern bool hook_bool_bool_false (bool); 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_true (enum machine_mode, rtx); extern bool hook_bool_tree_false (tree); extern bool hook_bool_tree_true (tree); extern bool hook_bool_tree_hwi_hwi_tree_false (tree, HOST_WIDE_INT, HOST_WIDE_INT, diff --git a/gcc/output.h b/gcc/output.h index 89743516050..69f8378a0bc 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -272,8 +272,7 @@ extern int get_pool_size (void); extern rtx peephole (rtx); #endif -/* Write all the constants in the constant pool. */ -extern void output_constant_pool (const char *, tree); +extern void output_shared_constant_pool (void); extern void output_object_blocks (void); diff --git a/gcc/toplev.c b/gcc/toplev.c index fab180db83d..a9705a70b5b 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1022,6 +1022,7 @@ compile_file (void) if (flag_mudflap) mudflap_finish_file (); + output_shared_constant_pool (); output_object_blocks (); /* Write out any pending weak symbol declarations. */ diff --git a/gcc/varasm.c b/gcc/varasm.c index 2a0ad5f16e5..b01ad1dd067 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -139,6 +139,7 @@ static void asm_output_aligned_bss (FILE *, tree, const char *, #endif #endif /* BSS_SECTION_ASM_OP */ static void mark_weak (tree); +static void output_constant_pool (void); /* Well-known sections, each one associated with some sort of *_ASM_OP. */ section *text_section; @@ -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. */ 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. */ static int @@ -1328,7 +1332,7 @@ assemble_start_function (tree decl, const char *fnname) app_disable (); if (CONSTANT_POOL_BEFORE_FUNCTION) - output_constant_pool (fnname, decl); + output_constant_pool (); resolve_unique_section (decl, 0, flag_function_sections); @@ -1446,7 +1450,7 @@ assemble_end_function (tree decl, const char *fnname) #endif if (! CONSTANT_POOL_BEFORE_FUNCTION) { - output_constant_pool (fnname, decl); + output_constant_pool (); switch_to_section (function_section (decl)); /* need to switch back */ } /* Output labels for end of hot/cold text sections (to be used by @@ -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. */ void init_varasm_status (struct function *f) { struct varasm_status *p; - struct rtx_constant_pool *pool; p = ggc_alloc (sizeof (struct varasm_status)); f->varasm = p; - pool = ggc_alloc (sizeof (struct rtx_constant_pool)); - p->pool = pool; + p->pool = create_constant_pool (); 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 @@ -3160,7 +3173,7 @@ rtx force_const_mem (enum machine_mode mode, rtx x) { struct constant_descriptor_rtx *desc, tmp; - struct rtx_constant_pool *pool = cfun->varasm->pool; + struct rtx_constant_pool *pool; char label[256]; rtx def, symbol; hashval_t hash; @@ -3171,6 +3184,14 @@ force_const_mem (enum machine_mode mode, rtx x) if (targetm.cannot_force_const_mem (x)) 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. */ tmp.constant = x; tmp.mode = mode; @@ -3233,7 +3254,6 @@ force_const_mem (enum machine_mode mode, rtx x) SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LOCAL; CONSTANT_POOL_ADDRESS_P (symbol) = 1; SET_SYMBOL_REF_CONSTANT (symbol, desc); - current_function_uses_const_pool = 1; /* Construct the MEM. */ desc->mem = def = gen_const_mem (mode, symbol); @@ -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. */ 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; if (x == NULL_RTX || GET_CODE (x) != SYMBOL_REF) @@ -3418,7 +3437,7 @@ mark_constant (rtx *current_rtx, void *data) if (desc->mark == 0) { 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)) @@ -3440,7 +3459,7 @@ mark_constant (rtx *current_rtx, void *data) deferred strings that are used. */ static void -mark_constants (struct rtx_constant_pool *pool, rtx insn) +mark_constants (rtx insn) { if (!INSN_P (insn)) return; @@ -3456,11 +3475,11 @@ mark_constants (struct rtx_constant_pool *pool, rtx insn) { rtx subinsn = XVECEXP (seq, 0, i); if (INSN_P (subinsn)) - for_each_rtx (&PATTERN (subinsn), mark_constant, pool); + for_each_rtx (&PATTERN (subinsn), mark_constant, NULL); } } 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 @@ -3468,40 +3487,29 @@ mark_constants (struct rtx_constant_pool *pool, rtx insn) which have indeed been used. */ static void -mark_constant_pool (struct rtx_constant_pool *pool) +mark_constant_pool (void) { rtx insn, link; - if (pool->first == 0 && n_deferred_constants == 0) + if (!current_function_uses_const_pool && n_deferred_constants == 0) return; for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - mark_constants (pool, insn); + mark_constants (insn); for (link = current_function_epilogue_delay_list; link; 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 -output_constant_pool (const char *fnname ATTRIBUTE_UNUSED, - tree fndecl ATTRIBUTE_UNUSED) +static void +output_constant_pool_contents (struct rtx_constant_pool *pool) { - struct rtx_constant_pool *pool = cfun->varasm->pool; 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) if (desc->mark) { @@ -3519,12 +3527,40 @@ output_constant_pool (const char *fnname ATTRIBUTE_UNUSED, 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 ASM_OUTPUT_POOL_EPILOGUE (asm_out_file, fnname, fndecl, pool->offset); #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. */ int @@ -5064,6 +5100,7 @@ init_varasm_once (void) const_desc_eq, NULL); const_alias_set = new_alias_set (); + shared_constant_pool = create_constant_pool (); #ifdef TEXT_SECTION_ASM_OP text_section = get_unnamed_section (SECTION_CODE, output_section_asm_op, -- 2.30.2