Commit 8478130d by Eric Botcazou Committed by Eric Botcazou

Uniquization of constants at the Tree level

	Uniquization of constants at the Tree level
	* tree.h (DECL_IN_CONSTANT_POOL): New macro
	(tree_decl_with_vis): Add in_constant_pool bit, move shadowed_for_var_p
	bit to the end.
	(tree_output_constant_def): Declare.
	* gimplify.c (gimplify_init_constructor): When using block copy,
	uniquize the constant constructor on the RHS.
	* lto-streamer-in.c (unpack_ts_decl_with_vis_value_fields): Deal
	with DECL_IN_CONSTANT_POOL flag.
	* lto-streamer-out.c (pack_ts_decl_with_vis_value_fields): Likewise.
	* varasm.c (make_decl_rtl): Deal with variables belonging to the
	global constant pool.
	(assemble_variable): Deal with symbols belonging to the tree constant
	pool.
	(get_constant_section): Add ALIGN parameter and simplify.
	(build_constant_desc): Build a VAR_DECL and attach it to the symbol.
	(assemble_constant_contents): Use the expression of the VAR_DECL.
	(output_constant_def_contents): Use the alignment of the VAR_DECL.
	(tree_output_constant_def): New global function.
	(mark_constant): Use the expression of the VAR_DECL.
	(place_block_symbol): Use the alignment of the VAR_DECL and the size
	of its expression.
	(output_object_block): Likewise and assemble the expression.
ada/
	* gcc-interface/trans.c (gnat_gimplify_expr) <ADDR_EXPR>: Uniquize
	constant constructors before taking their address.

From-SVN: r158838
parent 331c7fcd
2010-04-28 Eric Botcazou <ebotcazou@adacore.com> 2010-04-28 Eric Botcazou <ebotcazou@adacore.com>
Uniquization of constants at the Tree level
* tree.h (DECL_IN_CONSTANT_POOL): New macro
(tree_decl_with_vis): Add in_constant_pool bit, move shadowed_for_var_p
bit to the end.
(tree_output_constant_def): Declare.
* gimplify.c (gimplify_init_constructor): When using block copy,
uniquize the constant constructor on the RHS.
* lto-streamer-in.c (unpack_ts_decl_with_vis_value_fields): Deal
with DECL_IN_CONSTANT_POOL flag.
* lto-streamer-out.c (pack_ts_decl_with_vis_value_fields): Likewise.
* varasm.c (make_decl_rtl): Deal with variables belonging to the
global constant pool.
(assemble_variable): Deal with symbols belonging to the tree constant
pool.
(get_constant_section): Add ALIGN parameter and simplify.
(build_constant_desc): Build a VAR_DECL and attach it to the symbol.
(assemble_constant_contents): Use the expression of the VAR_DECL.
(output_constant_def_contents): Use the alignment of the VAR_DECL.
(tree_output_constant_def): New global function.
(mark_constant): Use the expression of the VAR_DECL.
(place_block_symbol): Use the alignment of the VAR_DECL and the size
of its expression.
(output_object_block): Likewise and assemble the expression.
2010-04-28 Eric Botcazou <ebotcazou@adacore.com>
* lto-streamer.c [LTO_STREAMER_DEBUG] (tree_htab, tree_hash_entry, * lto-streamer.c [LTO_STREAMER_DEBUG] (tree_htab, tree_hash_entry,
hash_tree, eq_tree): New tree hash table. hash_tree, eq_tree): New tree hash table.
(lto_streamer_init) [LTO_STREAMER_DEBUG]: Initialize it. (lto_streamer_init) [LTO_STREAMER_DEBUG]: Initialize it.
......
2010-04-28 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/trans.c (gnat_gimplify_expr) <ADDR_EXPR>: Uniquize
constant constructors before taking their address.
2010-04-25 Eric Botcazou <ebotcazou@adacore.com> 2010-04-25 Eric Botcazou <ebotcazou@adacore.com>
* exp_dbug.ads: Fix outdated description. Mention link between XVS * exp_dbug.ads: Fix outdated description. Mention link between XVS
......
...@@ -6036,16 +6036,8 @@ gnat_gimplify_expr (tree *expr_p, gimple_seq *pre_p, ...@@ -6036,16 +6036,8 @@ gnat_gimplify_expr (tree *expr_p, gimple_seq *pre_p,
the reference is in an elaboration procedure. */ the reference is in an elaboration procedure. */
if (TREE_CONSTANT (op)) if (TREE_CONSTANT (op))
{ {
tree new_var = create_tmp_var_raw (TREE_TYPE (op), "C"); tree addr = build_fold_addr_expr (tree_output_constant_def (op));
TREE_ADDRESSABLE (new_var) = 1; *expr_p = fold_convert (TREE_TYPE (expr), addr);
gimple_add_tmp_var (new_var);
TREE_READONLY (new_var) = 1;
TREE_STATIC (new_var) = 1;
DECL_INITIAL (new_var) = op;
TREE_OPERAND (expr, 0) = new_var;
recompute_tree_invariant_for_addr_expr (expr);
} }
/* Otherwise explicitly create the local temporary. That's required /* Otherwise explicitly create the local temporary. That's required
......
...@@ -3758,25 +3758,11 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, ...@@ -3758,25 +3758,11 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
&& num_nonzero_elements > 1 && num_nonzero_elements > 1
&& !can_move_by_pieces (size, align)) && !can_move_by_pieces (size, align))
{ {
tree new_tree;
if (notify_temp_creation) if (notify_temp_creation)
return GS_ERROR; return GS_ERROR;
new_tree = create_tmp_var_raw (type, "C"); walk_tree (&ctor, force_labels_r, NULL, NULL);
TREE_OPERAND (*expr_p, 1) = tree_output_constant_def (ctor);
gimple_add_tmp_var (new_tree);
TREE_STATIC (new_tree) = 1;
TREE_READONLY (new_tree) = 1;
DECL_INITIAL (new_tree) = ctor;
if (align > DECL_ALIGN (new_tree))
{
DECL_ALIGN (new_tree) = align;
DECL_USER_ALIGN (new_tree) = 1;
}
walk_tree (&DECL_INITIAL (new_tree), force_labels_r, NULL, NULL);
TREE_OPERAND (*expr_p, 1) = new_tree;
/* This is no longer an assignment of a CONSTRUCTOR, but /* This is no longer an assignment of a CONSTRUCTOR, but
we still may have processing to do on the LHS. So we still may have processing to do on the LHS. So
......
...@@ -1720,6 +1720,7 @@ unpack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr) ...@@ -1720,6 +1720,7 @@ unpack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
{ {
DECL_HARD_REGISTER (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_HARD_REGISTER (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_IN_TEXT_SECTION (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_IN_TEXT_SECTION (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_IN_CONSTANT_POOL (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_TLS_MODEL (expr) = (enum tls_model) bp_unpack_value (bp, 3); DECL_TLS_MODEL (expr) = (enum tls_model) bp_unpack_value (bp, 3);
} }
......
...@@ -468,6 +468,7 @@ pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr) ...@@ -468,6 +468,7 @@ pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
{ {
bp_pack_value (bp, DECL_HARD_REGISTER (expr), 1); bp_pack_value (bp, DECL_HARD_REGISTER (expr), 1);
bp_pack_value (bp, DECL_IN_TEXT_SECTION (expr), 1); bp_pack_value (bp, DECL_IN_TEXT_SECTION (expr), 1);
bp_pack_value (bp, DECL_IN_CONSTANT_POOL (expr), 1);
bp_pack_value (bp, DECL_TLS_MODEL (expr), 3); bp_pack_value (bp, DECL_TLS_MODEL (expr), 3);
} }
......
2010-04-28 Eric Botcazou <ebotcazou@adacore.com>
* gcc.dg/const-uniq-1.c: New test.
* gcc.dg/lto/const-uniq_[01].c: Likewise.
2010-04-28 Xinliang David Li <davidxl@google.com> 2010-04-28 Xinliang David Li <davidxl@google.com>
* gcc.dg/uninit-pred-2_b.c: New test. * gcc.dg/uninit-pred-2_b.c: New test.
......
/* Verify that the 2 constant initializers are uniquized. */
/* { dg-do compile } */
/* { dg-options "-Os -fdump-tree-gimple" } */
int lookup1 (int i)
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
return a[i];
}
int lookup2 (int i)
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
return a[i+1];
}
/* { dg-final { scan-tree-dump-times "LC0" 2 "gimple" } } */
/* { dg-final { cleanup-tree-dump "gimple" } } */
/* The 3 constant initializers should be uniquized. */
/* { dg-lto-do run } */
/* { dg-lto-options {{-Os -flto} {-Os -fwhopr} } } */
int lookup1 (int i)
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
return a[i];
}
int lookup2 (int i)
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
return a[i+1];
}
extern int lookup1 (int i);
extern int lookup2 (int i);
extern void abort (void);
int lookup3 (int i)
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
return a[i+2];
}
int main (void)
{
if (lookup1(2) != 2)
abort ();
if (lookup2(2) != 3)
abort ();
if (lookup3(2) != 4)
abort ();
return 0;
}
...@@ -2963,6 +2963,11 @@ struct GTY(()) tree_parm_decl { ...@@ -2963,6 +2963,11 @@ struct GTY(()) tree_parm_decl {
#define DECL_IN_TEXT_SECTION(NODE) \ #define DECL_IN_TEXT_SECTION(NODE) \
(VAR_DECL_CHECK (NODE)->decl_with_vis.in_text_section) (VAR_DECL_CHECK (NODE)->decl_with_vis.in_text_section)
/* In a VAR_DECL that's static,
nonzero if it belongs to the global constant pool. */
#define DECL_IN_CONSTANT_POOL(NODE) \
(VAR_DECL_CHECK (NODE)->decl_with_vis.in_constant_pool)
/* Nonzero for a given ..._DECL node means that this node should be /* Nonzero for a given ..._DECL node means that this node should be
put in .common, if possible. If a DECL_INITIAL is given, and it put in .common, if possible. If a DECL_INITIAL is given, and it
is not error_mark_node, then the decl cannot be put in .common. */ is not error_mark_node, then the decl cannot be put in .common. */
...@@ -3102,9 +3107,8 @@ struct GTY(()) tree_decl_with_vis { ...@@ -3102,9 +3107,8 @@ struct GTY(()) tree_decl_with_vis {
unsigned thread_local : 1; unsigned thread_local : 1;
unsigned common_flag : 1; unsigned common_flag : 1;
unsigned in_text_section : 1; unsigned in_text_section : 1;
unsigned in_constant_pool : 1;
unsigned dllimport_flag : 1; unsigned dllimport_flag : 1;
/* Used by C++. Might become a generic decl flag. */
unsigned shadowed_for_var_p : 1;
/* Don't belong to VAR_DECL exclusively. */ /* Don't belong to VAR_DECL exclusively. */
unsigned weak_flag : 1; unsigned weak_flag : 1;
...@@ -3117,7 +3121,9 @@ struct GTY(()) tree_decl_with_vis { ...@@ -3117,7 +3121,9 @@ struct GTY(()) tree_decl_with_vis {
/* Belong to FUNCTION_DECL exclusively. */ /* Belong to FUNCTION_DECL exclusively. */
unsigned init_priority_p : 1; unsigned init_priority_p : 1;
/* 15 unused bits. */ /* Used by C++ only. Might become a generic decl flag. */
unsigned shadowed_for_var_p : 1;
/* 14 unused bits. */
}; };
extern tree decl_debug_expr_lookup (tree); extern tree decl_debug_expr_lookup (tree);
...@@ -5184,6 +5190,7 @@ extern void internal_reference_types (void); ...@@ -5184,6 +5190,7 @@ extern void internal_reference_types (void);
extern unsigned int update_alignment_for_field (record_layout_info, tree, extern unsigned int update_alignment_for_field (record_layout_info, tree,
unsigned int); unsigned int);
/* varasm.c */ /* varasm.c */
extern tree tree_output_constant_def (tree);
extern void make_decl_rtl (tree); extern void make_decl_rtl (tree);
extern rtx make_decl_rtl_for_debug (tree); extern rtx make_decl_rtl_for_debug (tree);
extern void make_decl_one_only (tree, tree); extern void make_decl_one_only (tree, tree);
......
...@@ -1354,6 +1354,14 @@ make_decl_rtl (tree decl) ...@@ -1354,6 +1354,14 @@ make_decl_rtl (tree decl)
return; return;
} }
/* If this variable belongs to the global constant pool, retrieve the
pre-computed RTL or recompute it in LTO mode. */
if (TREE_CODE (decl) == VAR_DECL && DECL_IN_CONSTANT_POOL (decl))
{
SET_DECL_RTL (decl, output_constant_def (DECL_INITIAL (decl), 1));
return;
}
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
if (name[0] != '*' && TREE_CODE (decl) != FUNCTION_DECL if (name[0] != '*' && TREE_CODE (decl) != FUNCTION_DECL
...@@ -2198,8 +2206,6 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED, ...@@ -2198,8 +2206,6 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
if (flag_syntax_only) if (flag_syntax_only)
return; return;
app_disable ();
if (! dont_output_data if (! dont_output_data
&& ! host_integerp (DECL_SIZE_UNIT (decl), 1)) && ! host_integerp (DECL_SIZE_UNIT (decl), 1))
{ {
...@@ -2210,6 +2216,19 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED, ...@@ -2210,6 +2216,19 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
gcc_assert (MEM_P (decl_rtl)); gcc_assert (MEM_P (decl_rtl));
gcc_assert (GET_CODE (XEXP (decl_rtl, 0)) == SYMBOL_REF); gcc_assert (GET_CODE (XEXP (decl_rtl, 0)) == SYMBOL_REF);
symbol = XEXP (decl_rtl, 0); symbol = XEXP (decl_rtl, 0);
/* If this symbol belongs to the tree constant pool, output the constant
if it hasn't already been written. */
if (TREE_CONSTANT_POOL_ADDRESS_P (symbol))
{
tree decl = SYMBOL_REF_DECL (symbol);
if (!TREE_ASM_WRITTEN (DECL_INITIAL (decl)))
output_constant_def_contents (symbol);
return;
}
app_disable ();
name = XSTR (symbol, 0); name = XSTR (symbol, 0);
if (TREE_PUBLIC (decl) && DECL_NAME (decl)) if (TREE_PUBLIC (decl) && DECL_NAME (decl))
notice_global_symbol (decl); notice_global_symbol (decl);
...@@ -2790,7 +2809,6 @@ decode_addr_const (tree exp, struct addr_const *value) ...@@ -2790,7 +2809,6 @@ decode_addr_const (tree exp, struct addr_const *value)
{ {
if (TREE_CODE (target) == COMPONENT_REF if (TREE_CODE (target) == COMPONENT_REF
&& host_integerp (byte_position (TREE_OPERAND (target, 1)), 0)) && host_integerp (byte_position (TREE_OPERAND (target, 1)), 0))
{ {
offset += int_byte_position (TREE_OPERAND (target, 1)); offset += int_byte_position (TREE_OPERAND (target, 1));
target = TREE_OPERAND (target, 0); target = TREE_OPERAND (target, 0);
...@@ -2847,7 +2865,6 @@ decode_addr_const (tree exp, struct addr_const *value) ...@@ -2847,7 +2865,6 @@ decode_addr_const (tree exp, struct addr_const *value)
static GTY((param_is (struct constant_descriptor_tree))) static GTY((param_is (struct constant_descriptor_tree)))
htab_t const_desc_htab; htab_t const_desc_htab;
static struct constant_descriptor_tree * build_constant_desc (tree);
static void maybe_output_constant_def_contents (struct constant_descriptor_tree *, int); static void maybe_output_constant_def_contents (struct constant_descriptor_tree *, int);
/* Constant pool accessor function. */ /* Constant pool accessor function. */
...@@ -3236,31 +3253,14 @@ copy_constant (tree exp) ...@@ -3236,31 +3253,14 @@ copy_constant (tree exp)
} }
} }
/* Return the alignment of constant EXP in bits. */
static unsigned int
get_constant_alignment (tree exp)
{
unsigned int align;
align = TYPE_ALIGN (TREE_TYPE (exp));
#ifdef CONSTANT_ALIGNMENT
align = CONSTANT_ALIGNMENT (exp, align);
#endif
return align;
}
/* Return the section into which constant EXP should be placed. */ /* Return the section into which constant EXP should be placed. */
static section * static section *
get_constant_section (tree exp) get_constant_section (tree exp, unsigned int align)
{ {
if (IN_NAMED_SECTION (exp)) return targetm.asm_out.select_section (exp,
return get_named_section (exp, NULL, compute_reloc_for_constant (exp)); compute_reloc_for_constant (exp),
else align);
return targetm.asm_out.select_section (exp,
compute_reloc_for_constant (exp),
get_constant_alignment (exp));
} }
/* Return the size of constant EXP in bytes. */ /* Return the size of constant EXP in bytes. */
...@@ -3286,11 +3286,11 @@ get_constant_size (tree exp) ...@@ -3286,11 +3286,11 @@ get_constant_size (tree exp)
static struct constant_descriptor_tree * static struct constant_descriptor_tree *
build_constant_desc (tree exp) build_constant_desc (tree exp)
{ {
rtx symbol; struct constant_descriptor_tree *desc;
rtx rtl; rtx symbol, rtl;
char label[256]; char label[256];
int labelno; int labelno;
struct constant_descriptor_tree *desc; tree decl;
desc = GGC_NEW (struct constant_descriptor_tree); desc = GGC_NEW (struct constant_descriptor_tree);
desc->value = copy_constant (exp); desc->value = copy_constant (exp);
...@@ -3303,17 +3303,41 @@ build_constant_desc (tree exp) ...@@ -3303,17 +3303,41 @@ build_constant_desc (tree exp)
labelno = const_labelno++; labelno = const_labelno++;
ASM_GENERATE_INTERNAL_LABEL (label, "LC", labelno); ASM_GENERATE_INTERNAL_LABEL (label, "LC", labelno);
/* We have a symbol name; construct the SYMBOL_REF and the MEM. */ /* Construct the VAR_DECL associated with the constant. */
decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (label),
TREE_TYPE (exp));
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
TREE_READONLY (decl) = 1;
TREE_STATIC (decl) = 1;
TREE_ADDRESSABLE (decl) = 1;
/* We don't set the RTL yet as this would cause varpool to assume that the
variable is referenced. Moreover, it would just be dropped in LTO mode.
Instead we set the flag that will be recognized in make_decl_rtl. */
DECL_IN_CONSTANT_POOL (decl) = 1;
DECL_INITIAL (decl) = desc->value;
/* ??? CONSTANT_ALIGNMENT hasn't been updated for vector types on most
architectures so use DATA_ALIGNMENT as well, except for strings. */
if (TREE_CODE (exp) == STRING_CST)
{
#ifdef CONSTANT_ALIGNMENT
DECL_ALIGN (decl) = CONSTANT_ALIGNMENT (exp, DECL_ALIGN (decl));
#endif
}
else
align_variable (decl, 0);
/* Now construct the SYMBOL_REF and the MEM. */
if (use_object_blocks_p ()) if (use_object_blocks_p ())
{ {
section *sect = get_constant_section (exp); section *sect = get_constant_section (exp, DECL_ALIGN (decl));
symbol = create_block_symbol (ggc_strdup (label), symbol = create_block_symbol (ggc_strdup (label),
get_block_for_section (sect), -1); get_block_for_section (sect), -1);
} }
else else
symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label)); symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label));
SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LOCAL; SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LOCAL;
SET_SYMBOL_REF_DECL (symbol, desc->value); SET_SYMBOL_REF_DECL (symbol, decl);
TREE_CONSTANT_POOL_ADDRESS_P (symbol) = 1; TREE_CONSTANT_POOL_ADDRESS_P (symbol) = 1;
rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)), symbol); rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)), symbol);
...@@ -3330,7 +3354,6 @@ build_constant_desc (tree exp) ...@@ -3330,7 +3354,6 @@ build_constant_desc (tree exp)
ASM_OUTPUT_LABELREF will have to know how to strip this ASM_OUTPUT_LABELREF will have to know how to strip this
information. This call might invalidate our local variable information. This call might invalidate our local variable
SYMBOL; we can't use it afterward. */ SYMBOL; we can't use it afterward. */
targetm.encode_section_info (exp, rtl, true); targetm.encode_section_info (exp, rtl, true);
desc->rtl = rtl; desc->rtl = rtl;
...@@ -3437,7 +3460,8 @@ assemble_constant_contents (tree exp, const char *label, unsigned int align) ...@@ -3437,7 +3460,8 @@ assemble_constant_contents (tree exp, const char *label, unsigned int align)
static void static void
output_constant_def_contents (rtx symbol) output_constant_def_contents (rtx symbol)
{ {
tree exp = SYMBOL_REF_DECL (symbol); tree decl = SYMBOL_REF_DECL (symbol);
tree exp = DECL_INITIAL (decl);
unsigned int align; unsigned int align;
/* Make sure any other constants whose addresses appear in EXP /* Make sure any other constants whose addresses appear in EXP
...@@ -3454,8 +3478,8 @@ output_constant_def_contents (rtx symbol) ...@@ -3454,8 +3478,8 @@ output_constant_def_contents (rtx symbol)
place_block_symbol (symbol); place_block_symbol (symbol);
else else
{ {
switch_to_section (get_constant_section (exp)); align = DECL_ALIGN (decl);
align = get_constant_alignment (exp); switch_to_section (get_constant_section (exp, align));
if (align > BITS_PER_UNIT) if (align > BITS_PER_UNIT)
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT)); ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
assemble_constant_contents (exp, XSTR (symbol, 0), align); assemble_constant_contents (exp, XSTR (symbol, 0), align);
...@@ -3480,6 +3504,37 @@ lookup_constant_def (tree exp) ...@@ -3480,6 +3504,37 @@ lookup_constant_def (tree exp)
return (desc ? desc->rtl : NULL_RTX); return (desc ? desc->rtl : NULL_RTX);
} }
/* Return a tree representing a reference to constant data in memory
for the constant expression EXP.
This is the counterpart of output_constant_def at the Tree level. */
tree
tree_output_constant_def (tree exp)
{
struct constant_descriptor_tree *desc, key;
void **loc;
tree decl;
/* Look up EXP in the table of constant descriptors. If we didn't find
it, create a new one. */
key.value = exp;
key.hash = const_hash_1 (exp);
loc = htab_find_slot_with_hash (const_desc_htab, &key, key.hash, INSERT);
desc = (struct constant_descriptor_tree *) *loc;
if (desc == 0)
{
desc = build_constant_desc (exp);
desc->hash = key.hash;
*loc = desc;
}
decl = SYMBOL_REF_DECL (XEXP (desc->rtl, 0));
varpool_finalize_decl (decl);
return decl;
}
/* Used in the hash tables to avoid outputting the same constant /* Used in the hash tables to avoid outputting the same constant
twice. Unlike 'struct constant_descriptor_tree', RTX constants twice. Unlike 'struct constant_descriptor_tree', RTX constants
...@@ -3949,8 +4004,8 @@ mark_constant (rtx *current_rtx, void *data ATTRIBUTE_UNUSED) ...@@ -3949,8 +4004,8 @@ mark_constant (rtx *current_rtx, void *data ATTRIBUTE_UNUSED)
} }
else if (TREE_CONSTANT_POOL_ADDRESS_P (x)) else if (TREE_CONSTANT_POOL_ADDRESS_P (x))
{ {
tree exp = SYMBOL_REF_DECL (x); tree decl = SYMBOL_REF_DECL (x);
if (!TREE_ASM_WRITTEN (exp)) if (!TREE_ASM_WRITTEN (DECL_INITIAL (decl)))
{ {
n_deferred_constants--; n_deferred_constants--;
output_constant_def_contents (x); output_constant_def_contents (x);
...@@ -6912,8 +6967,8 @@ place_block_symbol (rtx symbol) ...@@ -6912,8 +6967,8 @@ place_block_symbol (rtx symbol)
else if (TREE_CONSTANT_POOL_ADDRESS_P (symbol)) else if (TREE_CONSTANT_POOL_ADDRESS_P (symbol))
{ {
decl = SYMBOL_REF_DECL (symbol); decl = SYMBOL_REF_DECL (symbol);
alignment = get_constant_alignment (decl); alignment = DECL_ALIGN (decl);
size = get_constant_size (decl); size = get_constant_size (DECL_INITIAL (decl));
} }
else else
{ {
...@@ -7059,9 +7114,9 @@ output_object_block (struct object_block *block) ...@@ -7059,9 +7114,9 @@ output_object_block (struct object_block *block)
else if (TREE_CONSTANT_POOL_ADDRESS_P (symbol)) else if (TREE_CONSTANT_POOL_ADDRESS_P (symbol))
{ {
decl = SYMBOL_REF_DECL (symbol); decl = SYMBOL_REF_DECL (symbol);
assemble_constant_contents (decl, XSTR (symbol, 0), assemble_constant_contents (DECL_INITIAL (decl), XSTR (symbol, 0),
get_constant_alignment (decl)); DECL_ALIGN (decl));
offset += get_constant_size (decl); offset += get_constant_size (DECL_INITIAL (decl));
} }
else else
{ {
......
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