- DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (base);
- DECL_ARTIFICIAL (var) = 1;
-
- if (TREE_THIS_VOLATILE (elt->type))
- {
- TREE_THIS_VOLATILE (var) = 1;
- TREE_SIDE_EFFECTS (var) = 1;
- }
-
- if (DECL_NAME (base) && !DECL_IGNORED_P (base))
- {
- char *pretty_name = build_element_name (elt);
- DECL_NAME (var) = get_identifier (pretty_name);
- obstack_free (&sra_obstack, pretty_name);
-
- SET_DECL_DEBUG_EXPR (var, generate_element_ref (elt));
- DECL_DEBUG_EXPR_IS_FROM (var) = 1;
-
- DECL_IGNORED_P (var) = 0;
- TREE_NO_WARNING (var) = nowarn;
- }
- else
- {
- DECL_IGNORED_P (var) = 1;
- /* ??? We can't generate any warning that would be meaningful. */
- TREE_NO_WARNING (var) = 1;
- }
-
- /* Zero-initialize bit-field scalarization variables, to avoid
- triggering undefined behavior. */
- if (TREE_CODE (elt->element) == BIT_FIELD_REF
- || (var != elt->replacement
- && TREE_CODE (elt->replacement) == BIT_FIELD_REF))
- {
- gimple_seq init = sra_build_assignment (var,
- fold_convert (TREE_TYPE (var),
- integer_zero_node)
- );
- insert_edge_copies_seq (init, ENTRY_BLOCK_PTR);
- mark_all_v_defs_seq (init);
- }
-
- if (dump_file)
- {
- fputs (" ", dump_file);
- dump_sra_elt_name (dump_file, elt);
- fputs (" -> ", dump_file);
- print_generic_expr (dump_file, var, dump_flags);
- fputc ('\n', dump_file);
- }
-}
-
-/* Make one pass across an element tree deciding whether or not it's
- profitable to instantiate individual leaf scalars.
-
- PARENT_USES and PARENT_COPIES are the sum of the N_USES and N_COPIES
- fields all the way up the tree. */
-
-static void
-decide_instantiation_1 (struct sra_elt *elt, unsigned int parent_uses,
- unsigned int parent_copies)
-{
- if (dump_file && !elt->parent)
- {
- fputs ("Initial instantiation for ", dump_file);
- dump_sra_elt_name (dump_file, elt);
- fputc ('\n', dump_file);
- }
-
- if (elt->cannot_scalarize)
- return;
-
- if (elt->is_scalar)
- {
- /* The decision is simple: instantiate if we're used more frequently
- than the parent needs to be seen as a complete unit. */
- if (elt->n_uses + elt->n_copies + parent_copies > parent_uses)
- instantiate_element (elt);
- }
- else
- {
- struct sra_elt *c, *group;
- unsigned int this_uses = elt->n_uses + parent_uses;
- unsigned int this_copies = elt->n_copies + parent_copies;
-
- /* Consider groups of sub-elements as weighing in favour of
- instantiation whatever their size. */
- for (group = elt->groups; group ; group = group->sibling)
- FOR_EACH_ACTUAL_CHILD (c, group)
- {
- c->n_uses += group->n_uses;
- c->n_copies += group->n_copies;
- }
-
- for (c = elt->children; c ; c = c->sibling)
- decide_instantiation_1 (c, this_uses, this_copies);
- }
-}
-
-/* Compute the size and number of all instantiated elements below ELT.
- We will only care about this if the size of the complete structure
- fits in a HOST_WIDE_INT, so we don't have to worry about overflow. */
-
-static unsigned int
-sum_instantiated_sizes (struct sra_elt *elt, unsigned HOST_WIDE_INT *sizep)
-{
- if (elt->replacement)
- {
- *sizep += TREE_INT_CST_LOW (TYPE_SIZE_UNIT (elt->type));
- return 1;
- }
- else
- {
- struct sra_elt *c;
- unsigned int count = 0;
-
- for (c = elt->children; c ; c = c->sibling)
- count += sum_instantiated_sizes (c, sizep);
-
- return count;
- }
-}
-
-/* Instantiate fields in ELT->TYPE that are not currently present as
- children of ELT. */
-
-static void instantiate_missing_elements (struct sra_elt *elt);
-
-static struct sra_elt *
-instantiate_missing_elements_1 (struct sra_elt *elt, tree child, tree type)
-{
- struct sra_elt *sub = lookup_element (elt, child, type, INSERT);
- if (sub->is_scalar)
- {
- if (sub->replacement == NULL)
- instantiate_element (sub);
- }
- else
- instantiate_missing_elements (sub);
- return sub;
-}
-
-/* Obtain the canonical type for field F of ELEMENT. */
-
-static tree
-canon_type_for_field (tree f, tree element)
-{
- tree field_type = TREE_TYPE (f);
-
- /* canonicalize_component_ref() unwidens some bit-field types (not
- marked as DECL_BIT_FIELD in C++), so we must do the same, lest we
- may introduce type mismatches. */
- if (INTEGRAL_TYPE_P (field_type)
- && DECL_MODE (f) != TYPE_MODE (field_type))
- field_type = TREE_TYPE (get_unwidened (build3 (COMPONENT_REF,
- field_type,
- element,
- f, NULL_TREE),
- NULL_TREE));
-
- return field_type;
-}
-
-/* Look for adjacent fields of ELT starting at F that we'd like to
- scalarize as a single variable. Return the last field of the
- group. */
-
-static tree
-try_instantiate_multiple_fields (struct sra_elt *elt, tree f)
-{
- int count;
- unsigned HOST_WIDE_INT align, bit, size, alchk;
- enum machine_mode mode;
- tree first = f, prev;
- tree type, var;
- struct sra_elt *block;
-
- /* Point fields are typically best handled as standalone entities. */
- if (POINTER_TYPE_P (TREE_TYPE (f)))
- return f;
-
- if (!is_sra_scalar_type (TREE_TYPE (f))
- || !host_integerp (DECL_FIELD_OFFSET (f), 1)
- || !host_integerp (DECL_FIELD_BIT_OFFSET (f), 1)
- || !host_integerp (DECL_SIZE (f), 1)
- || lookup_element (elt, f, NULL, NO_INSERT))
- return f;
-
- block = elt;
-
- /* For complex and array objects, there are going to be integer
- literals as child elements. In this case, we can't just take the
- alignment and mode of the decl, so we instead rely on the element
- type.
-
- ??? We could try to infer additional alignment from the full
- object declaration and the location of the sub-elements we're
- accessing. */
- for (count = 0; !DECL_P (block->element); count++)
- block = block->parent;
-
- align = DECL_ALIGN (block->element);
- alchk = GET_MODE_BITSIZE (DECL_MODE (block->element));
-
- if (count)
- {
- type = TREE_TYPE (block->element);
- while (count--)
- type = TREE_TYPE (type);
-
- align = TYPE_ALIGN (type);
- alchk = GET_MODE_BITSIZE (TYPE_MODE (type));
- }
-
- if (align < alchk)
- align = alchk;
-
- /* Coalescing wider fields is probably pointless and
- inefficient. */
- if (align > BITS_PER_WORD)
- align = BITS_PER_WORD;
-
- bit = tree_low_cst (DECL_FIELD_OFFSET (f), 1) * BITS_PER_UNIT
- + tree_low_cst (DECL_FIELD_BIT_OFFSET (f), 1);
- size = tree_low_cst (DECL_SIZE (f), 1);
-
- alchk = align - 1;
- alchk = ~alchk;
-
- if ((bit & alchk) != ((bit + size - 1) & alchk))
- return f;
-
- /* Find adjacent fields in the same alignment word. */
-
- for (prev = f, f = TREE_CHAIN (f);
- f && TREE_CODE (f) == FIELD_DECL
- && is_sra_scalar_type (TREE_TYPE (f))
- && host_integerp (DECL_FIELD_OFFSET (f), 1)
- && host_integerp (DECL_FIELD_BIT_OFFSET (f), 1)
- && host_integerp (DECL_SIZE (f), 1)
- && !lookup_element (elt, f, NULL, NO_INSERT);
- prev = f, f = TREE_CHAIN (f))
- {
- unsigned HOST_WIDE_INT nbit, nsize;
-
- nbit = tree_low_cst (DECL_FIELD_OFFSET (f), 1) * BITS_PER_UNIT
- + tree_low_cst (DECL_FIELD_BIT_OFFSET (f), 1);
- nsize = tree_low_cst (DECL_SIZE (f), 1);
-
- if (bit + size == nbit)
- {
- if ((bit & alchk) != ((nbit + nsize - 1) & alchk))
- {
- /* If we're at an alignment boundary, don't bother
- growing alignment such that we can include this next
- field. */
- if ((nbit & alchk)
- || GET_MODE_BITSIZE (DECL_MODE (f)) <= align)
- break;
-
- align = GET_MODE_BITSIZE (DECL_MODE (f));
- alchk = align - 1;
- alchk = ~alchk;
-
- if ((bit & alchk) != ((nbit + nsize - 1) & alchk))
- break;
- }
- size += nsize;
- }
- else if (nbit + nsize == bit)
- {
- if ((nbit & alchk) != ((bit + size - 1) & alchk))