static GTY(()) section *unnamed_sections;
/* Return a nonzero value if DECL has a section attribute. */
+#ifndef IN_NAMED_SECTION
#define IN_NAMED_SECTION(DECL) \
((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \
&& DECL_SECTION_NAME (DECL) != NULL_TREE)
+#endif
/* Hash table of named sections. */
static GTY((param_is (section))) htab_t section_htab;
/* Note that we use the hash of the decl's name, rather than a hash
of the decl's pointer. In emutls_finish we iterate through the
hash table, and we want this traversal to be predictable. */
- in.hash = IDENTIFIER_HASH_VALUE (name);
+ in.hash = htab_hash_string (IDENTIFIER_POINTER (name));
in.base.from = decl;
loc = htab_find_slot_with_hash (emutls_htab, &in, in.hash, INSERT);
h = (struct tree_map *) *loc;
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));
if (name[0] != '*' && TREE_CODE (decl) != FUNCTION_DECL
if (flag_syntax_only)
return;
+ app_disable ();
+
if (! dont_output_data
&& ! host_integerp (DECL_SIZE_UNIT (decl), 1))
{
gcc_assert (MEM_P (decl_rtl));
gcc_assert (GET_CODE (XEXP (decl_rtl, 0)) == SYMBOL_REF);
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);
if (TREE_PUBLIC (decl) && DECL_NAME (decl))
notice_global_symbol (decl);
{
if (TREE_CODE (target) == COMPONENT_REF
&& host_integerp (byte_position (TREE_OPERAND (target, 1)), 0))
+
{
offset += int_byte_position (TREE_OPERAND (target, 1));
target = TREE_OPERAND (target, 0);
* tree_low_cst (TREE_OPERAND (target, 1), 0));
target = TREE_OPERAND (target, 0);
}
- else if (TREE_CODE (target) == INDIRECT_REF
- && TREE_CODE (TREE_OPERAND (target, 0)) == NOP_EXPR
- && TREE_CODE (TREE_OPERAND (TREE_OPERAND (target, 0), 0))
- == ADDR_EXPR)
- target = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (target, 0), 0), 0);
else
break;
}
static GTY((param_is (struct constant_descriptor_tree)))
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);
/* Constant pool accessor function. */
return (const_hash_1 (TREE_REALPART (exp)) * 5
+ const_hash_1 (TREE_IMAGPART (exp)));
- case VECTOR_CST:
- {
- tree link;
-
- hi = 7 + TYPE_VECTOR_SUBPARTS (TREE_TYPE (exp));
-
- for (link = TREE_VECTOR_CST_ELTS (exp); link; link = TREE_CHAIN (link))
- hi = hi * 563 + const_hash_1 (TREE_VALUE (link));
-
- return hi;
- }
-
case CONSTRUCTOR:
{
unsigned HOST_WIDE_INT idx;
return (compare_constant (TREE_REALPART (t1), TREE_REALPART (t2))
&& compare_constant (TREE_IMAGPART (t1), TREE_IMAGPART (t2)));
- case VECTOR_CST:
- {
- tree link1, link2;
-
- if (TYPE_VECTOR_SUBPARTS (TREE_TYPE (t1))
- != TYPE_VECTOR_SUBPARTS (TREE_TYPE (t2)))
- return 0;
-
- link2 = TREE_VECTOR_CST_ELTS (t2);
- for (link1 = TREE_VECTOR_CST_ELTS (t1);
- link1;
- link1 = TREE_CHAIN (link1))
- {
- if (!compare_constant (TREE_VALUE (link1), TREE_VALUE (link2)))
- return 0;
- link2 = TREE_CHAIN (link2);
- }
-
- return 1;
- }
-
case CONSTRUCTOR:
{
VEC(constructor_elt, gc) *v1, *v2;
case FDESC_EXPR:
{
struct addr_const value1, value2;
- enum rtx_code code;
- int ret;
decode_addr_const (t1, &value1);
decode_addr_const (t2, &value2);
-
- if (value1.offset != value2.offset)
- return 0;
-
- code = GET_CODE (value1.base);
- if (code != GET_CODE (value2.base))
- return 0;
-
- switch (code)
- {
- case SYMBOL_REF:
- ret = (strcmp (XSTR (value1.base, 0), XSTR (value2.base, 0)) == 0);
- break;
-
- case LABEL_REF:
- ret = (CODE_LABEL_NUMBER (XEXP (value1.base, 0))
- == CODE_LABEL_NUMBER (XEXP (value2.base, 0)));
- break;
-
- default:
- gcc_unreachable ();
- }
- return ret;
+ return (value1.offset == value2.offset
+ && strcmp (XSTR (value1.base, 0), XSTR (value2.base, 0)) == 0);
}
case PLUS_EXPR:
return build1 (TREE_CODE (exp), TREE_TYPE (exp),
copy_constant (TREE_OPERAND (exp, 0)));
- case VECTOR_CST:
- return build_vector (TREE_TYPE (exp),
- copy_list (TREE_VECTOR_CST_ELTS (exp)));
-
case CONSTRUCTOR:
{
tree copy = copy_node (exp);
}
}
\f
+/* 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. */
static section *
-get_constant_section (tree exp, unsigned int align)
+get_constant_section (tree exp)
{
- return targetm.asm_out.select_section (exp,
- compute_reloc_for_constant (exp),
- align);
+ if (IN_NAMED_SECTION (exp))
+ return get_named_section (exp, NULL, compute_reloc_for_constant (exp));
+ else
+ return targetm.asm_out.select_section (exp,
+ compute_reloc_for_constant (exp),
+ get_constant_alignment (exp));
}
/* Return the size of constant EXP in bytes. */
static struct constant_descriptor_tree *
build_constant_desc (tree exp)
{
- struct constant_descriptor_tree *desc;
- rtx symbol, rtl;
+ rtx symbol;
+ rtx rtl;
char label[256];
int labelno;
- tree decl;
+ struct constant_descriptor_tree *desc;
desc = GGC_NEW (struct constant_descriptor_tree);
desc->value = copy_constant (exp);
labelno = const_labelno++;
ASM_GENERATE_INTERNAL_LABEL (label, "LC", labelno);
- /* 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. */
+ /* We have a symbol name; construct the SYMBOL_REF and the MEM. */
if (use_object_blocks_p ())
{
- section *sect = get_constant_section (exp, DECL_ALIGN (decl));
+ section *sect = get_constant_section (exp);
symbol = create_block_symbol (ggc_strdup (label),
get_block_for_section (sect), -1);
}
else
symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label));
SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LOCAL;
- SET_SYMBOL_REF_DECL (symbol, decl);
+ SET_SYMBOL_REF_DECL (symbol, desc->value);
TREE_CONSTANT_POOL_ADDRESS_P (symbol) = 1;
rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)), symbol);
ASM_OUTPUT_LABELREF will have to know how to strip this
information. This call might invalidate our local variable
SYMBOL; we can't use it afterward. */
+
targetm.encode_section_info (exp, rtl, true);
desc->rtl = rtl;
static void
output_constant_def_contents (rtx symbol)
{
- tree decl = SYMBOL_REF_DECL (symbol);
- tree exp = DECL_INITIAL (decl);
+ tree exp = SYMBOL_REF_DECL (symbol);
unsigned int align;
/* Make sure any other constants whose addresses appear in EXP
place_block_symbol (symbol);
else
{
- align = DECL_ALIGN (decl);
- switch_to_section (get_constant_section (exp, align));
+ switch_to_section (get_constant_section (exp));
+ align = get_constant_alignment (exp);
if (align > BITS_PER_UNIT)
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
assemble_constant_contents (exp, XSTR (symbol, 0), align);
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;
-}
\f
/* Used in the hash tables to avoid outputting the same constant
twice. Unlike 'struct constant_descriptor_tree', RTX constants
}
else if (TREE_CONSTANT_POOL_ADDRESS_P (x))
{
- tree decl = SYMBOL_REF_DECL (x);
- if (!TREE_ASM_WRITTEN (DECL_INITIAL (decl)))
+ tree exp = SYMBOL_REF_DECL (x);
+ if (!TREE_ASM_WRITTEN (exp))
{
n_deferred_constants--;
output_constant_def_contents (x);
else if (vnode)
{
varpool_mark_needed_node (vnode);
- vnode->force_output = 1;
return vnode->decl;
}
else
else if (TREE_CONSTANT_POOL_ADDRESS_P (symbol))
{
decl = SYMBOL_REF_DECL (symbol);
- alignment = DECL_ALIGN (decl);
- size = get_constant_size (DECL_INITIAL (decl));
+ alignment = get_constant_alignment (decl);
+ size = get_constant_size (decl);
}
else
{
else if (TREE_CONSTANT_POOL_ADDRESS_P (symbol))
{
decl = SYMBOL_REF_DECL (symbol);
- assemble_constant_contents (DECL_INITIAL (decl), XSTR (symbol, 0),
- DECL_ALIGN (decl));
- offset += get_constant_size (DECL_INITIAL (decl));
+ assemble_constant_contents (decl, XSTR (symbol, 0),
+ get_constant_alignment (decl));
+ offset += get_constant_size (decl);
}
else
{
maybe_assemble_visibility (decl);
}
-/* Create a DEBUG_EXPR_DECL / DEBUG_EXPR pair from RTL expression
- EXP. */
-rtx
-make_debug_expr_from_rtl (const_rtx exp)
-{
- tree ddecl = make_node (DEBUG_EXPR_DECL), type;
- enum machine_mode mode = GET_MODE (exp);
- rtx dval;
-
- DECL_ARTIFICIAL (ddecl) = 1;
- if (REG_P (exp) && REG_EXPR (exp))
- type = TREE_TYPE (REG_EXPR (exp));
- else if (MEM_P (exp) && MEM_EXPR (exp))
- type = TREE_TYPE (MEM_EXPR (exp));
- else
- type = NULL_TREE;
- if (type && TYPE_MODE (type) == mode)
- TREE_TYPE (ddecl) = type;
- else
- TREE_TYPE (ddecl) = lang_hooks.types.type_for_mode (mode, 1);
- DECL_MODE (ddecl) = mode;
- dval = gen_rtx_DEBUG_EXPR (mode);
- DEBUG_EXPR_TREE_DECL (dval) = ddecl;
- SET_DECL_RTL (ddecl, dval);
- return dval;
-}
-
#include "gt-varasm.h"