dwarf2asm.c (mark_indirect_pool_entry, [...]): New.

* dwarf2asm.c (mark_indirect_pool_entry, mark_indirect_pool): New.
	(USE_LINKONCE_INDIRECT): Define.
	(dw2_output_indirect_constant_1): Try to output indirect constants
	into linkonce sections if possible.
	(dw2_force_const_mem): Likewise.  Register indirect_pool with GGC.
	(dw2_output_indirect_constants): Likewise.

From-SVN: r46843
This commit is contained in:
Jakub Jelinek 2001-11-08 12:33:32 +01:00 committed by Jakub Jelinek
parent c71541c273
commit d6d2676479
2 changed files with 74 additions and 27 deletions

View File

@ -1,3 +1,12 @@
2001-11-08 Jakub Jelinek <jakub@redhat.com>
* dwarf2asm.c (mark_indirect_pool_entry, mark_indirect_pool): New.
(USE_LINKONCE_INDIRECT): Define.
(dw2_output_indirect_constant_1): Try to output indirect constants
into linkonce sections if possible.
(dw2_force_const_mem): Likewise. Register indirect_pool with GGC.
(dw2_output_indirect_constants): Likewise.
2001-11-07 Aldy Hernandez <aldyh@redhat.com> 2001-11-07 Aldy Hernandez <aldyh@redhat.com>
* config/rs6000/rs6000.h (REG_ALLOC_ORDER): Add vrsave. * config/rs6000/rs6000.h (REG_ALLOC_ORDER): Add vrsave.

View File

@ -720,11 +720,39 @@ dw2_asm_output_delta_sleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
VA_CLOSE (ap); VA_CLOSE (ap);
} }
static int mark_indirect_pool_entry PARAMS ((splay_tree_node, void *));
static void mark_indirect_pool PARAMS ((PTR arg));
static rtx dw2_force_const_mem PARAMS ((rtx)); static rtx dw2_force_const_mem PARAMS ((rtx));
static int dw2_output_indirect_constant_1 PARAMS ((splay_tree_node, void *)); static int dw2_output_indirect_constant_1 PARAMS ((splay_tree_node, void *));
static splay_tree indirect_pool; static splay_tree indirect_pool;
#if defined(HAVE_GAS_HIDDEN) && defined(SUPPORTS_ONE_ONLY)
# define USE_LINKONCE_INDIRECT 1
#else
# define USE_LINKONCE_INDIRECT 0
#endif
/* Mark all indirect constants for GC. */
static int
mark_indirect_pool_entry (node, data)
splay_tree_node node;
void* data ATTRIBUTE_UNUSED;
{
ggc_mark_nonnull_tree ((tree) node->value);
return 0;
}
/* Mark all indirect constants for GC. */
static void
mark_indirect_pool (arg)
PTR arg ATTRIBUTE_UNUSED;
{
splay_tree_foreach (indirect_pool, mark_indirect_pool_entry, NULL);
}
/* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated /* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated
memory. Differs from force_const_mem in that a single pool is used for memory. Differs from force_const_mem in that a single pool is used for
the entire unit of translation, and the memory is not guaranteed to be the entire unit of translation, and the memory is not guaranteed to be
@ -735,35 +763,56 @@ dw2_force_const_mem (x)
rtx x; rtx x;
{ {
splay_tree_node node; splay_tree_node node;
const char *const_sym; tree decl;
if (! indirect_pool) if (! indirect_pool)
indirect_pool = splay_tree_new (splay_tree_compare_pointers, NULL, NULL); {
indirect_pool = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
ggc_add_root (&indirect_pool, 1, sizeof indirect_pool, mark_indirect_pool);
}
if (GET_CODE (x) != SYMBOL_REF) if (GET_CODE (x) != SYMBOL_REF)
abort (); abort ();
node = splay_tree_lookup (indirect_pool, (splay_tree_key) XSTR (x, 0)); node = splay_tree_lookup (indirect_pool, (splay_tree_key) XSTR (x, 0));
if (node) if (node)
const_sym = (const char *) node->value; decl = (tree) node->value;
else else
{ {
extern int const_labelno;
char label[32];
tree id; tree id;
ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno); if (USE_LINKONCE_INDIRECT)
++const_labelno; {
const_sym = ggc_strdup (label); char *ref_name = alloca (strlen (XSTR (x, 0) + sizeof "DW.ref."));
sprintf (ref_name, "DW.ref.%s", XSTR (x, 0));
id = get_identifier (ref_name);
decl = build_decl (VAR_DECL, id, ptr_type_node);
DECL_ARTIFICIAL (decl) = 1;
DECL_INITIAL (decl) = decl;
make_decl_one_only (decl);
}
else
{
extern int const_labelno;
char label[32];
ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
++const_labelno;
id = get_identifier (label);
decl = build_decl (VAR_DECL, id, ptr_type_node);
DECL_ARTIFICIAL (decl) = 1;
DECL_INITIAL (decl) = decl;
}
id = maybe_get_identifier (XSTR (x, 0)); id = maybe_get_identifier (XSTR (x, 0));
if (id) if (id)
TREE_SYMBOL_REFERENCED (id) = 1; TREE_SYMBOL_REFERENCED (id) = 1;
splay_tree_insert (indirect_pool, (splay_tree_key) XSTR (x, 0), splay_tree_insert (indirect_pool, (splay_tree_key) XSTR (x, 0),
(splay_tree_value) const_sym); (splay_tree_value) decl);
} }
return gen_rtx_SYMBOL_REF (Pmode, const_sym); return XEXP (DECL_RTL (decl), 0);
} }
/* A helper function for dw2_output_indirect_constants called through /* A helper function for dw2_output_indirect_constants called through
@ -774,14 +823,14 @@ dw2_output_indirect_constant_1 (node, data)
splay_tree_node node; splay_tree_node node;
void* data ATTRIBUTE_UNUSED; void* data ATTRIBUTE_UNUSED;
{ {
const char *label, *sym; const char *sym;
rtx sym_ref; rtx sym_ref;
label = (const char *) node->value;
sym = (const char *) node->key; sym = (const char *) node->key;
sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym); sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
if (USE_LINKONCE_INDIRECT)
ASM_OUTPUT_LABEL (asm_out_file, label); fprintf (asm_out_file, "\t.hidden DW.ref.%s\n", sym);
assemble_variable ((tree) node->value, 1, 1, 1);
assemble_integer (sym_ref, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); assemble_integer (sym_ref, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
return 0; return 0;
@ -792,19 +841,8 @@ dw2_output_indirect_constant_1 (node, data)
void void
dw2_output_indirect_constants () dw2_output_indirect_constants ()
{ {
if (! indirect_pool) if (indirect_pool)
return; splay_tree_foreach (indirect_pool, dw2_output_indirect_constant_1, NULL);
/* Assume that the whole reason we're emitting these symbol references
indirectly is that they contain dynamic relocations, and are thus
read-write. If there was no possibility of a dynamic relocation, we
might as well have used a direct relocation. */
data_section ();
/* Everything we're emitting is a pointer. Align appropriately. */
assemble_align (POINTER_SIZE);
splay_tree_foreach (indirect_pool, dw2_output_indirect_constant_1, NULL);
} }
/* Like dw2_asm_output_addr_rtx, but encode the pointer as directed. */ /* Like dw2_asm_output_addr_rtx, but encode the pointer as directed. */