Commit d6d26764 by Jakub Jelinek Committed by Jakub Jelinek

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
parent c71541c2
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.
......
...@@ -720,11 +720,39 @@ dw2_asm_output_delta_sleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED, ...@@ -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) ...@@ -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
{
tree id;
if (USE_LINKONCE_INDIRECT)
{
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 else
{ {
extern int const_labelno; extern int const_labelno;
char label[32]; char label[32];
tree id;
ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno); ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
++const_labelno; ++const_labelno;
const_sym = ggc_strdup (label); 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) ...@@ -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,18 +841,7 @@ dw2_output_indirect_constant_1 (node, data) ...@@ -792,18 +841,7 @@ dw2_output_indirect_constant_1 (node, data)
void void
dw2_output_indirect_constants () dw2_output_indirect_constants ()
{ {
if (! indirect_pool) if (indirect_pool)
return;
/* 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); splay_tree_foreach (indirect_pool, dw2_output_indirect_constant_1, NULL);
} }
......
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