From: Alexandre Oliva <aoliva@redhat.com>
To: Bernd Schmidt <bernds_cb1@t-online.de>
Cc: Daniel Berlin <dberlin@dberlin.org>,
GCC Patches <gcc-patches@gcc.gnu.org>,
Diego Novillo <dnovillo@redhat.com>,
Andrew Pinski <pinskia@gmail.com>
Subject: Re: Reload bug & SRA oddness
Date: Mon, 30 Apr 2007 19:08:00 -0000 [thread overview]
Message-ID: <ork5vtu5ev.fsf@free.oliva.athome.lsd.ic.unicamp.br> (raw)
In-Reply-To: <or4pmxvkv1.fsf@free.oliva.athome.lsd.ic.unicamp.br> (Alexandre Oliva's message of "Mon\, 30 Apr 2007 14\:21\:38 -0300")
[-- Attachment #1: Type: text/plain, Size: 523 bytes --]
On Apr 30, 2007, Alexandre Oliva <aoliva@redhat.com> wrote:
> On Apr 30, 2007, Bernd Schmidt <bernds_cb1@t-online.de> wrote:
>> As a consequence of all these problems, I'd like to see this patch
>> reverted for now until it we know how to do it properly.
> Sounds like a reasonable trade-off. I'm sorry that I haven't had time
> to look into this throughout the past two weeks. I was finally able
> to start looking into this yesterday, but I haven't got anywhere so
> far.
Here's the reversal patch I'm checking in.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: gcc-sra-bit-field-ref-revert.patch --]
[-- Type: text/x-patch, Size: 27508 bytes --]
Index: gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
PR middle-end/22156
Temporarily revert:
2007-04-06 Andreas Tobler <a.tobler@schweiz.org>
* tree-sra.c (sra_build_elt_assignment): Initialize min/maxshift.
2007-04-05 Alexandre Oliva <aoliva@redhat.com>
* tree-sra.c (try_instantiate_multiple_fields): Needlessly
initialize align to silence bogus warning.
2007-04-05 Alexandre Oliva <aoliva@redhat.com>
* tree-sra.c (struct sra_elt): Add in_bitfld_block. Remove
all_no_warning.
(struct sra_walk_fns): Remove use_all parameter from use.
(sra_hash_tree): Handle BIT_FIELD_REFs.
(sra_elt_hash): Don't hash bitfld blocks.
(sra_elt_eq): Skip them in parent compares as well. Handle
BIT_FIELD_REFs.
(sra_walk_expr): Don't maintain or pass down use_all_p.
(scan_use): Remove use_all parameter.
(scalarize_use): Likewise. Re-expand assignment to
BIT_FIELD_REF of gimple_reg. De-scalarize before input or
output, and re-scalarize after output. Don't mark anything
for no warning.
(scalarize_ldst): Adjust.
(scalarize_walk_gimple_modify_statement): Likewise.
(build_element_name_1): Handle BIT_FIELD_REFs.
(instantiate_element): Don't warn for any element whose parent
is used as a whole.
(instantiate_missing_elements_1): Return the sra_elt.
(canon_type_for_field): New.
(try_instantiate_multiple_fields): New.
(instantiate_missing_elemnts): Use them.
(mark_no_warning): Removed.
(generate_one_element_ref): Handle BIT_FIELD_REFs.
(REPLDUP, sra_build_elt_assignment): New.
(generate_copy_inout): Use them.
(generate_element_copy): Likewise. Handle bitfld differences.
(generate_element_zero): Don't recurse for blocks. Use
sra_build_elt_assignment.
(generate_one_element_int): Take elt instead of var. Use
sra_build_elt_assignment.
(generate_element_init_1): Adjust.
(scalarize_use, scalarize_copy): Use REPLDUP.
(scalarize_ldst): Move assert before dereference.
(dump_sra_elt_name): Handle BIT_FIELD_REFs.
Index: gcc/tree-sra.c
===================================================================
--- gcc/tree-sra.c (revision 124300)
+++ gcc/tree-sra.c (working copy)
@@ -147,10 +147,6 @@
/* True if there is BIT_FIELD_REF on the lhs with a vector. */
bool is_vector_lhs;
-
- /* 1 if the element is a field that is part of a block, 2 if the field
- is the block itself, 0 if it's neither. */
- char in_bitfld_block;
};
#define IS_ELEMENT_FOR_GROUP(ELEMENT) (TREE_CODE (ELEMENT) == RANGE_EXPR)
@@ -465,12 +461,6 @@
h = iterative_hash_expr (DECL_FIELD_BIT_OFFSET (t), h);
break;
- case BIT_FIELD_REF:
- /* Don't take operand 0 into account, that's our parent. */
- h = iterative_hash_expr (TREE_OPERAND (t, 1), 0);
- h = iterative_hash_expr (TREE_OPERAND (t, 2), h);
- break;
-
default:
gcc_unreachable ();
}
@@ -489,14 +479,12 @@
h = sra_hash_tree (e->element);
- /* Take into account everything except bitfield blocks back up the
- chain. Given that chain lengths are rarely very long, this
- should be acceptable. If we truly identify this as a performance
- problem, it should work to hash the pointer value
- "e->parent". */
+ /* Take into account everything back up the chain. Given that chain
+ lengths are rarely very long, this should be acceptable. If we
+ truly identify this as a performance problem, it should work to
+ hash the pointer value "e->parent". */
for (p = e->parent; p ; p = p->parent)
- if (!p->in_bitfld_block)
- h = (h * 65521) ^ sra_hash_tree (p->element);
+ h = (h * 65521) ^ sra_hash_tree (p->element);
return h;
}
@@ -509,17 +497,8 @@
const struct sra_elt *a = x;
const struct sra_elt *b = y;
tree ae, be;
- const struct sra_elt *ap = a->parent;
- const struct sra_elt *bp = b->parent;
- if (ap)
- while (ap->in_bitfld_block)
- ap = ap->parent;
- if (bp)
- while (bp->in_bitfld_block)
- bp = bp->parent;
-
- if (ap != bp)
+ if (a->parent != b->parent)
return false;
ae = a->element;
@@ -554,11 +533,6 @@
return false;
return fields_compatible_p (ae, be);
- case BIT_FIELD_REF:
- return
- tree_int_cst_equal (TREE_OPERAND (ae, 1), TREE_OPERAND (be, 1))
- && tree_int_cst_equal (TREE_OPERAND (ae, 2), TREE_OPERAND (be, 2));
-
default:
gcc_unreachable ();
}
@@ -697,9 +671,10 @@
/* Invoked when ELT is required as a unit. Note that ELT might refer to
a leaf node, in which case this is a simple scalar reference. *EXPR_P
points to the location of the expression. IS_OUTPUT is true if this
- is a left-hand-side reference. */
+ is a left-hand-side reference. USE_ALL is true if we saw something we
+ couldn't quite identify and had to force the use of the entire object. */
void (*use) (struct sra_elt *elt, tree *expr_p,
- block_stmt_iterator *bsi, bool is_output);
+ block_stmt_iterator *bsi, bool is_output, bool use_all);
/* Invoked when we have a copy between two scalarizable references. */
void (*copy) (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
@@ -753,6 +728,7 @@
tree expr = *expr_p;
tree inner = expr;
bool disable_scalarization = false;
+ bool use_all_p = false;
/* We're looking to collect a reference expression between EXPR and INNER,
such that INNER is a scalarizable decl and all other nodes through EXPR
@@ -773,7 +749,7 @@
if (disable_scalarization)
elt->cannot_scalarize = true;
else
- fns->use (elt, expr_p, bsi, is_output);
+ fns->use (elt, expr_p, bsi, is_output, use_all_p);
}
return;
@@ -860,6 +836,7 @@
use_all:
expr_p = &TREE_OPERAND (inner, 0);
inner = expr = *expr_p;
+ use_all_p = true;
break;
default:
@@ -907,14 +884,11 @@
sra_walk_tree_list (ASM_OUTPUTS (expr), bsi, true, fns);
}
-static void sra_replace (block_stmt_iterator *bsi, tree list);
-static tree sra_build_elt_assignment (struct sra_elt *elt, tree src);
-
/* Walk a GIMPLE_MODIFY_STMT and categorize the assignment appropriately. */
static void
sra_walk_gimple_modify_stmt (tree expr, block_stmt_iterator *bsi,
- const struct sra_walk_fns *fns)
+ const struct sra_walk_fns *fns)
{
struct sra_elt *lhs_elt, *rhs_elt;
tree lhs, rhs;
@@ -937,7 +911,7 @@
if (!rhs_elt->is_scalar && !TREE_SIDE_EFFECTS (lhs))
fns->ldst (rhs_elt, lhs, bsi, false);
else
- fns->use (rhs_elt, &GIMPLE_STMT_OPERAND (expr, 1), bsi, false);
+ fns->use (rhs_elt, &GIMPLE_STMT_OPERAND (expr, 1), bsi, false, false);
}
/* If it isn't scalarizable, there may be scalarizable variables within, so
@@ -984,9 +958,7 @@
/* Otherwise we're being used in some context that requires the
aggregate to be seen as a whole. Invoke USE. */
else
- {
- fns->use (lhs_elt, &GIMPLE_STMT_OPERAND (expr, 0), bsi, true);
- }
+ fns->use (lhs_elt, &GIMPLE_STMT_OPERAND (expr, 0), bsi, true, false);
}
/* Similarly to above, LHS_ELT being null only means that the LHS as a
@@ -1097,7 +1069,7 @@
static void
scan_use (struct sra_elt *elt, tree *expr_p ATTRIBUTE_UNUSED,
block_stmt_iterator *bsi ATTRIBUTE_UNUSED,
- bool is_output ATTRIBUTE_UNUSED)
+ bool is_output ATTRIBUTE_UNUSED, bool use_all ATTRIBUTE_UNUSED)
{
elt->n_uses += 1;
}
@@ -1205,15 +1177,6 @@
sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (t));
obstack_grow (&sra_obstack, buffer, strlen (buffer));
}
- else if (TREE_CODE (t) == BIT_FIELD_REF)
- {
- sprintf (buffer, "B" HOST_WIDE_INT_PRINT_DEC,
- tree_low_cst (TREE_OPERAND (t, 2), 1));
- obstack_grow (&sra_obstack, buffer, strlen (buffer));
- sprintf (buffer, "F" HOST_WIDE_INT_PRINT_DEC,
- tree_low_cst (TREE_OPERAND (t, 1), 1));
- obstack_grow (&sra_obstack, buffer, strlen (buffer));
- }
else
{
tree name = DECL_NAME (t);
@@ -1246,12 +1209,9 @@
{
struct sra_elt *base_elt;
tree var, base;
- bool nowarn = TREE_NO_WARNING (elt->element);
for (base_elt = elt; base_elt->parent; base_elt = base_elt->parent)
- if (!nowarn)
- nowarn = base_elt->parent->n_uses
- || TREE_NO_WARNING (base_elt->parent->element);
+ continue;
base = base_elt->element;
elt->replacement = var = make_rename_temp (elt->type, "SR");
@@ -1280,7 +1240,9 @@
DECL_DEBUG_EXPR_IS_FROM (var) = 1;
DECL_IGNORED_P (var) = 0;
- TREE_NO_WARNING (var) = nowarn;
+ TREE_NO_WARNING (var) = TREE_NO_WARNING (base);
+ if (elt->element && TREE_NO_WARNING (elt->element))
+ TREE_NO_WARNING (var) = 1;
}
else
{
@@ -1375,7 +1337,7 @@
static void instantiate_missing_elements (struct sra_elt *elt);
-static struct sra_elt *
+static void
instantiate_missing_elements_1 (struct sra_elt *elt, tree child, tree type)
{
struct sra_elt *sub = lookup_element (elt, child, type, INSERT);
@@ -1386,268 +1348,8 @@
}
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)
-{
- unsigned HOST_WIDE_INT align, oalign, word, bit, size, alchk;
- enum machine_mode mode;
- tree first = f, prev;
- tree type, var;
- struct sra_elt *block;
-
- 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;
-
- /* Taking the alignment of elt->element is not enough, since it
- might be just an array index or some such. We shouldn't need to
- initialize align here, but our optimizers don't always realize
- that, if we leave the loop without initializing align, we'll fail
- the assertion right after the loop. */
- align = (unsigned HOST_WIDE_INT)-1;
- for (block = elt; block; block = block->parent)
- if (DECL_P (block->element))
- {
- align = DECL_ALIGN (block->element);
- break;
- }
- gcc_assert (block);
-
- oalign = DECL_OFFSET_ALIGN (f);
- word = tree_low_cst (DECL_FIELD_OFFSET (f), 1);
- bit = tree_low_cst (DECL_FIELD_BIT_OFFSET (f), 1);
- size = tree_low_cst (DECL_SIZE (f), 1);
-
- if (align > oalign)
- align = oalign;
-
- 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)
- && (HOST_WIDE_INT)word == tree_low_cst (DECL_FIELD_OFFSET (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_BIT_OFFSET (f), 1);
- nsize = tree_low_cst (DECL_SIZE (f), 1);
-
- if (bit + size == nbit)
- {
- if ((bit & alchk) != ((nbit + nsize - 1) & alchk))
- break;
- size += nsize;
- }
- else if (nbit + nsize == bit)
- {
- if ((nbit & alchk) != ((bit + size - 1) & alchk))
- break;
- bit = nbit;
- size += nsize;
- }
- else
- break;
- }
-
- f = prev;
-
- if (f == first)
- return f;
-
- gcc_assert ((bit & alchk) == ((bit + size - 1) & alchk));
-
- /* Try to widen the bit range so as to cover padding bits as well. */
-
- if ((bit & ~alchk) || size != align)
- {
- unsigned HOST_WIDE_INT mbit = bit & alchk;
- unsigned HOST_WIDE_INT msize = align;
-
- for (f = TYPE_FIELDS (elt->type);
- f; f = TREE_CHAIN (f))
- {
- unsigned HOST_WIDE_INT fword, fbit, fsize;
-
- /* Skip the fields from first to prev. */
- if (f == first)
- {
- f = prev;
- continue;
- }
-
- if (!(TREE_CODE (f) == FIELD_DECL
- && host_integerp (DECL_FIELD_OFFSET (f), 1)
- && host_integerp (DECL_FIELD_BIT_OFFSET (f), 1)))
- continue;
-
- fword = tree_low_cst (DECL_FIELD_OFFSET (f), 1);
- /* If we're past the selected word, we're fine. */
- if (word < fword)
- continue;
-
- fbit = tree_low_cst (DECL_FIELD_BIT_OFFSET (f), 1);
-
- if (host_integerp (DECL_SIZE (f), 1))
- fsize = tree_low_cst (DECL_SIZE (f), 1);
- else
- /* Assume a variable-sized field takes up all space till
- the end of the word. ??? Endianness issues? */
- fsize = align - fbit;
-
- if (fword < word)
- {
- /* A large field might start at a previous word and
- extend into the selected word. Exclude those
- bits. ??? Endianness issues? */
- HOST_WIDE_INT diff = fbit + fsize
- - (HOST_WIDE_INT)((word - fword) * BITS_PER_UNIT + mbit);
-
- if (diff <= 0)
- continue;
-
- mbit += diff;
- msize -= diff;
- }
- else
- {
- gcc_assert (fword == word);
-
- /* Non-overlapping, great. */
- if (fbit + fsize <= mbit
- || mbit + msize <= fbit)
- continue;
-
- if (fbit <= mbit)
- {
- unsigned HOST_WIDE_INT diff = fbit + fsize - mbit;
- mbit += diff;
- msize -= diff;
- }
- else if (fbit > mbit)
- msize -= (mbit + msize - fbit);
- else
- gcc_unreachable ();
- }
- }
-
- bit = mbit;
- size = msize;
- }
-
- /* Now we know the bit range we're interested in. Find the smallest
- machine mode we can use to access it. */
-
- for (mode = smallest_mode_for_size (size, MODE_INT);
- ;
- mode = GET_MODE_WIDER_MODE (mode))
- {
- gcc_assert (mode != VOIDmode);
-
- alchk = GET_MODE_PRECISION (mode) - 1;
- alchk = ~alchk;
-
- if ((bit & alchk) == ((bit + size - 1) & alchk))
- break;
- }
-
- gcc_assert (~alchk < align);
-
- /* Create the field group as a single variable. */
-
- type = lang_hooks.types.type_for_mode (mode, 1);
- gcc_assert (type);
- var = build3 (BIT_FIELD_REF, type, NULL_TREE,
- bitsize_int (size),
- bitsize_int (word * BITS_PER_UNIT + bit));
- BIT_FIELD_REF_UNSIGNED (var) = 1;
-
- block = instantiate_missing_elements_1 (elt, var, type);
- gcc_assert (block && block->is_scalar);
-
- var = block->replacement;
-
- if (((word * BITS_PER_UNIT + bit) & ~alchk)
- || (HOST_WIDE_INT)size != tree_low_cst (DECL_SIZE (var), 1))
- {
- block->replacement = build3 (BIT_FIELD_REF,
- TREE_TYPE (block->element), var,
- bitsize_int (size),
- bitsize_int ((word * BITS_PER_UNIT
- + bit) & ~alchk));
- BIT_FIELD_REF_UNSIGNED (block->replacement) = 1;
- TREE_NO_WARNING (block->replacement) = 1;
- }
-
- block->in_bitfld_block = 2;
-
- /* Add the member fields to the group, such that they access
- portions of the group variable. */
-
- for (f = first; f != TREE_CHAIN (prev); f = TREE_CHAIN (f))
- {
- tree field_type = canon_type_for_field (f, elt->element);
- struct sra_elt *fld = lookup_element (block, f, field_type, INSERT);
-
- gcc_assert (fld && fld->is_scalar && !fld->replacement);
-
- fld->replacement = build3 (BIT_FIELD_REF, field_type, var,
- DECL_SIZE (f),
- bitsize_int
- ((word * BITS_PER_UNIT
- + (TREE_INT_CST_LOW
- (DECL_FIELD_BIT_OFFSET (f))))
- & ~alchk));
- BIT_FIELD_REF_UNSIGNED (fld->replacement) = TYPE_UNSIGNED (field_type);
- TREE_NO_WARNING (block->replacement) = 1;
- fld->in_bitfld_block = 1;
- }
-
- return prev;
-}
-
static void
instantiate_missing_elements (struct sra_elt *elt)
{
@@ -1661,17 +1363,21 @@
for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
if (TREE_CODE (f) == FIELD_DECL)
{
- tree last = try_instantiate_multiple_fields (elt, f);
+ tree field_type = TREE_TYPE (f);
- if (last != f)
- {
- f = last;
- continue;
- }
+ /* 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,
+ elt->element,
+ f, NULL_TREE),
+ NULL_TREE));
- instantiate_missing_elements_1 (elt, f,
- canon_type_for_field
- (f, elt->element));
+ instantiate_missing_elements_1 (elt, f, field_type);
}
break;
}
@@ -1983,16 +1689,6 @@
{
tree field = elt->element;
- /* We can't test elt->in_bitfld_blk here because, when this is
- called from instantiate_element, we haven't set this field
- yet. */
- if (TREE_CODE (field) == BIT_FIELD_REF)
- {
- tree ret = copy_node (field);
- TREE_OPERAND (ret, 0) = base;
- return ret;
- }
-
/* Watch out for compatible records with differing field lists. */
if (DECL_FIELD_CONTEXT (field) != TYPE_MAIN_VARIANT (TREE_TYPE (base)))
field = find_compatible_field (TREE_TYPE (base), field);
@@ -2045,126 +1741,6 @@
return build_gimple_modify_stmt (dst, src);
}
-/* BIT_FIELD_REFs must not be shared. sra_build_elt_assignment()
- takes care of assignments, but we must create copies for uses. */
-#define REPLDUP(t) (TREE_CODE (t) != BIT_FIELD_REF ? (t) : copy_node (t))
-
-static tree
-sra_build_elt_assignment (struct sra_elt *elt, tree src)
-{
- tree dst = elt->replacement;
- tree var, type, tmp, tmp2, tmp3;
- tree list, stmt;
- tree cst, cst2, mask;
- tree minshift = NULL, maxshift = NULL;
-
- if (TREE_CODE (dst) != BIT_FIELD_REF
- || !elt->in_bitfld_block)
- return sra_build_assignment (REPLDUP (dst), src);
-
- var = TREE_OPERAND (dst, 0);
-
- /* Try to widen the assignment to the entire variable.
- We need the source to be a BIT_FIELD_REF as well, such that, for
- BIT_FIELD_REF<d,sz,dp> = BIT_FIELD_REF<s,sz,sp>,
- if sp >= dp, we can turn it into
- d = BIT_FIELD_REF<s,sp+sz,sp-dp>. */
- if (elt->in_bitfld_block == 2
- && TREE_CODE (src) == BIT_FIELD_REF
- && !tree_int_cst_lt (TREE_OPERAND (src, 2), TREE_OPERAND (dst, 2)))
- {
- src = fold_build3 (BIT_FIELD_REF, TREE_TYPE (var),
- TREE_OPERAND (src, 0),
- size_binop (PLUS_EXPR, TREE_OPERAND (src, 1),
- TREE_OPERAND (dst, 2)),
- size_binop (MINUS_EXPR, TREE_OPERAND (src, 2),
- TREE_OPERAND (dst, 2)));
- BIT_FIELD_REF_UNSIGNED (src) = 1;
-
- return sra_build_assignment (var, src);
- }
-
- if (!is_gimple_reg (var))
- return sra_build_assignment (REPLDUP (dst), src);
-
- list = alloc_stmt_list ();
-
- cst = TREE_OPERAND (dst, 2);
- if (WORDS_BIG_ENDIAN)
- {
- cst = size_binop (MINUS_EXPR, DECL_SIZE (var), cst);
- maxshift = cst;
- }
- else
- minshift = cst;
-
- cst2 = size_binop (PLUS_EXPR, TREE_OPERAND (dst, 1),
- TREE_OPERAND (dst, 2));
- if (WORDS_BIG_ENDIAN)
- {
- cst2 = size_binop (MINUS_EXPR, DECL_SIZE (var), cst2);
- minshift = cst2;
- }
- else
- maxshift = cst2;
-
- type = TREE_TYPE (var);
-
- mask = build_int_cst_wide (type, 1, 0);
- cst = int_const_binop (LSHIFT_EXPR, mask, maxshift, 1);
- cst2 = int_const_binop (LSHIFT_EXPR, mask, minshift, 1);
- mask = int_const_binop (MINUS_EXPR, cst, cst2, 1);
- mask = fold_build1 (BIT_NOT_EXPR, type, mask);
-
- if (!WORDS_BIG_ENDIAN)
- cst2 = TREE_OPERAND (dst, 2);
-
- tmp = make_rename_temp (type, "SR");
- stmt = build_gimple_modify_stmt (tmp,
- fold_build2 (BIT_AND_EXPR, type,
- var, mask));
- append_to_statement_list (stmt, &list);
-
- if (is_gimple_reg (src))
- tmp2 = src;
- else
- {
- tmp2 = make_rename_temp (TREE_TYPE (src), "SR");
- stmt = sra_build_assignment (tmp2, src);
- append_to_statement_list (stmt, &list);
- }
-
- if (!TYPE_UNSIGNED (TREE_TYPE (tmp2))
- || TYPE_MAIN_VARIANT (TREE_TYPE (tmp2)) != TYPE_MAIN_VARIANT (type))
- {
- tmp3 = make_rename_temp (type, "SR");
- tmp2 = fold_build3 (BIT_FIELD_REF, type, tmp2, TREE_OPERAND (dst, 1),
- bitsize_int (0));
- if (TREE_CODE (tmp2) == BIT_FIELD_REF)
- BIT_FIELD_REF_UNSIGNED (tmp2) = 1;
- stmt = sra_build_assignment (tmp3, tmp2);
- append_to_statement_list (stmt, &list);
- tmp2 = tmp3;
- }
-
- if (!integer_zerop (minshift))
- {
- tmp3 = make_rename_temp (type, "SR");
- stmt = build_gimple_modify_stmt (tmp3,
- fold_build2 (LSHIFT_EXPR, type,
- tmp2, minshift));
- append_to_statement_list (stmt, &list);
- tmp2 = tmp3;
- }
-
- stmt = build_gimple_modify_stmt (var,
- fold_build2 (BIT_IOR_EXPR, type,
- tmp, tmp2));
- append_to_statement_list (stmt, &list);
-
- return list;
-}
-
/* Generate a set of assignment statements in *LIST_P to copy all
instantiated elements under ELT to or from the equivalent structure
rooted at EXPR. COPY_OUT controls the direction of the copy, with
@@ -2195,9 +1771,9 @@
else if (elt->replacement)
{
if (copy_out)
- t = sra_build_elt_assignment (elt, expr);
+ t = sra_build_assignment (elt->replacement, expr);
else
- t = sra_build_assignment (expr, REPLDUP (elt->replacement));
+ t = sra_build_assignment (expr, elt->replacement);
append_to_statement_list (t, list_p);
}
else
@@ -2222,19 +1798,6 @@
FOR_EACH_ACTUAL_CHILD (dc, dst)
{
sc = lookup_element (src, dc->element, NULL, NO_INSERT);
- if (!sc && dc->in_bitfld_block == 2)
- {
- struct sra_elt *dcs;
-
- FOR_EACH_ACTUAL_CHILD (dcs, dc)
- {
- sc = lookup_element (src, dcs->element, NULL, NO_INSERT);
- gcc_assert (sc);
- generate_element_copy (dcs, sc, list_p);
- }
-
- continue;
- }
gcc_assert (sc);
generate_element_copy (dc, sc, list_p);
}
@@ -2245,7 +1808,7 @@
gcc_assert (src->replacement);
- t = sra_build_elt_assignment (dst, REPLDUP (src->replacement));
+ t = sra_build_assignment (dst->replacement, src->replacement);
append_to_statement_list (t, list_p);
}
}
@@ -2266,9 +1829,8 @@
return;
}
- if (!elt->in_bitfld_block)
- FOR_EACH_ACTUAL_CHILD (c, elt)
- generate_element_zero (c, list_p);
+ FOR_EACH_ACTUAL_CHILD (c, elt)
+ generate_element_zero (c, list_p);
if (elt->replacement)
{
@@ -2277,7 +1839,7 @@
gcc_assert (elt->is_scalar);
t = fold_convert (elt->type, integer_zero_node);
- t = sra_build_elt_assignment (elt, t);
+ t = sra_build_assignment (elt->replacement, t);
append_to_statement_list (t, list_p);
}
}
@@ -2286,10 +1848,10 @@
Add the result to *LIST_P. */
static void
-generate_one_element_init (struct sra_elt *elt, tree init, tree *list_p)
+generate_one_element_init (tree var, tree init, tree *list_p)
{
/* The replacement can be almost arbitrarily complex. Gimplify. */
- tree stmt = sra_build_elt_assignment (elt, init);
+ tree stmt = sra_build_assignment (var, init);
gimplify_and_add (stmt, list_p);
}
@@ -2318,7 +1880,7 @@
{
if (elt->replacement)
{
- generate_one_element_init (elt, init, list_p);
+ generate_one_element_init (elt->replacement, init, list_p);
elt->visited = true;
}
return result;
@@ -2477,7 +2039,7 @@
static void
scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi,
- bool is_output)
+ bool is_output, bool use_all)
{
tree list = NULL, stmt = bsi_stmt (*bsi);
@@ -2486,27 +2048,8 @@
/* If we have a replacement, then updating the reference is as
simple as modifying the existing statement in place. */
if (is_output)
- {
- if (TREE_CODE (elt->replacement) == BIT_FIELD_REF
- && is_gimple_reg (TREE_OPERAND (elt->replacement, 0))
- && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && &GIMPLE_STMT_OPERAND (stmt, 0) == expr_p)
- {
- tree newstmt = sra_build_elt_assignment
- (elt, GIMPLE_STMT_OPERAND (stmt, 1));
- if (TREE_CODE (newstmt) != STATEMENT_LIST)
- {
- tree list = alloc_stmt_list ();
- append_to_statement_list (newstmt, &list);
- newstmt = list;
- }
- sra_replace (bsi, newstmt);
- return;
- }
-
- mark_all_v_defs (stmt);
- }
- *expr_p = REPLDUP (elt->replacement);
+ mark_all_v_defs (stmt);
+ *expr_p = elt->replacement;
update_stmt (stmt);
}
else
@@ -2524,24 +2067,18 @@
This optimization would be most effective if sra_walk_function
processed the blocks in dominator order. */
- generate_copy_inout (elt, false, generate_element_ref (elt), &list);
- if (list)
+ generate_copy_inout (elt, is_output, generate_element_ref (elt), &list);
+ if (list == NULL)
+ return;
+ mark_all_v_defs (list);
+ if (is_output)
+ sra_insert_after (bsi, list);
+ else
{
- mark_all_v_defs (list);
sra_insert_before (bsi, list);
- mark_no_warning (elt);
+ if (use_all)
+ mark_no_warning (elt);
}
-
- if (is_output)
- {
- list = NULL;
- generate_copy_inout (elt, true, generate_element_ref (elt), &list);
- if (list)
- {
- mark_all_v_defs (list);
- sra_insert_after (bsi, list);
- }
- }
}
}
@@ -2564,7 +2101,7 @@
gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
GIMPLE_STMT_OPERAND (stmt, 0) = lhs_elt->replacement;
- GIMPLE_STMT_OPERAND (stmt, 1) = REPLDUP (rhs_elt->replacement);
+ GIMPLE_STMT_OPERAND (stmt, 1) = rhs_elt->replacement;
update_stmt (stmt);
}
else if (lhs_elt->use_block_copy || rhs_elt->use_block_copy)
@@ -2706,7 +2243,7 @@
{
/* Since ELT is not fully instantiated, we have to leave the
block copy in place. Treat this as a USE. */
- scalarize_use (elt, NULL, bsi, is_output);
+ scalarize_use (elt, NULL, bsi, is_output, false);
}
else
{
@@ -2718,8 +2255,8 @@
mark_all_v_defs (stmt);
generate_copy_inout (elt, is_output, other, &list);
- gcc_assert (list);
mark_all_v_defs (list);
+ gcc_assert (list);
/* Preserve EH semantics. */
if (stmt_ends_bb_p (stmt))
@@ -2815,10 +2352,6 @@
fputc ('.', f);
print_generic_expr (f, elt->element, dump_flags);
}
- else if (TREE_CODE (elt->element) == BIT_FIELD_REF)
- fprintf (f, "$B" HOST_WIDE_INT_PRINT_DEC "F" HOST_WIDE_INT_PRINT_DEC,
- tree_low_cst (TREE_OPERAND (elt->element, 2), 1),
- tree_low_cst (TREE_OPERAND (elt->element, 1), 1));
else if (TREE_CODE (elt->element) == RANGE_EXPR)
fprintf (f, "["HOST_WIDE_INT_PRINT_DEC".."HOST_WIDE_INT_PRINT_DEC"]",
TREE_INT_CST_LOW (TREE_OPERAND (elt->element, 0)),
[-- Attachment #3: Type: text/plain, Size: 249 bytes --]
--
Alexandre Oliva http://www.lsd.ic.unicamp.br/~oliva/
FSF Latin America Board Member http://www.fsfla.org/
Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org}
next prev parent reply other threads:[~2007-04-30 17:40 UTC|newest]
Thread overview: 104+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-04-20 0:29 Bernd Schmidt
2007-04-20 3:19 ` Andrew Pinski
2007-04-20 3:53 ` Daniel Berlin
2007-04-20 4:30 ` Bernd Schmidt
2007-04-20 4:48 ` Andrew Pinski
2007-04-20 7:32 ` Alexandre Oliva
2007-04-20 12:57 ` Bernd Schmidt
2007-04-20 18:28 ` Alexandre Oliva
2007-04-20 18:40 ` Alexandre Oliva
2007-04-30 10:09 ` Bernd Schmidt
2007-04-30 19:04 ` Alexandre Oliva
2007-04-30 19:08 ` Alexandre Oliva [this message]
2007-05-01 15:38 ` Alexandre Oliva
2007-05-01 15:45 ` Eric Botcazou
2007-05-04 0:19 ` Alexandre Oliva
2007-05-01 15:53 ` Diego Novillo
2007-05-01 16:03 ` Eric Botcazou
2007-05-01 16:51 ` Arnaud Charlet
2007-05-01 16:54 ` Arnaud Charlet
2007-05-01 17:31 ` Andreas Schwab
2007-05-01 16:24 ` Roman Zippel
2007-05-04 4:07 ` Alexandre Oliva
2007-05-04 5:24 ` Alexandre Oliva
2007-05-05 18:19 ` Roman Zippel
2007-05-06 5:13 ` Alexandre Oliva
2007-05-06 12:13 ` Bernd Schmidt
2007-05-06 14:27 ` Alexandre Oliva
2007-05-06 15:01 ` Alexandre Oliva
2007-05-06 23:44 ` Alexandre Oliva
2007-05-06 23:51 ` Diego Novillo
2007-05-07 0:14 ` Alexandre Oliva
2007-05-07 2:21 ` Andrew Pinski
2007-05-09 12:25 ` Bernd Schmidt
2007-05-10 7:47 ` Alexandre Oliva
2007-05-10 11:00 ` Bernd Schmidt
2007-05-22 7:09 ` Alexandre Oliva
2007-05-22 17:34 ` Roman Zippel
2007-05-22 20:49 ` Alexandre Oliva
2007-05-23 13:07 ` Roman Zippel
2007-05-22 21:23 ` Alexandre Oliva
2007-05-09 18:32 ` Roman Zippel
2007-05-10 7:49 ` Alexandre Oliva
2007-05-15 17:39 ` Alexandre Oliva
2007-05-17 21:17 ` Andrew Pinski
2007-05-28 10:49 ` Bernd Schmidt
2007-05-31 20:57 ` Alexandre Oliva
2007-06-02 17:41 ` Bernd Schmidt
2007-06-06 3:18 ` Alexandre Oliva
2007-06-25 18:48 ` Alexandre Oliva
2007-06-26 23:01 ` Bernd Schmidt
2007-06-28 4:50 ` Alexandre Oliva
2007-07-03 0:52 ` Roman Zippel
2007-07-06 9:21 ` Alexandre Oliva
2007-08-24 7:28 ` SRA bit-field optimization (was: Re: Reload bug & SRA oddness) Alexandre Oliva
2007-09-28 9:17 ` SRA bit-field optimization Alexandre Oliva
2007-10-02 17:15 ` Richard Guenther
2007-10-03 8:38 ` Richard Sandiford
2007-10-03 16:50 ` Alexandre Oliva
2007-10-03 18:23 ` Richard Sandiford
2007-10-04 19:56 ` Richard Sandiford
2007-10-05 17:43 ` Alexandre Oliva
2007-10-06 8:02 ` Richard Sandiford
2007-10-06 21:06 ` John David Anglin
2007-10-06 22:12 ` Richard Sandiford
2007-10-07 23:44 ` Alexandre Oliva
2007-10-08 21:14 ` John David Anglin
2007-10-08 23:51 ` Alexandre Oliva
2007-10-09 0:31 ` John David Anglin
2007-10-09 4:41 ` Alexandre Oliva
2007-10-09 4:45 ` Alexandre Oliva
2007-10-06 16:01 ` David Daney
2007-10-03 14:37 ` Daniel Berlin
2007-10-03 14:44 ` Diego Novillo
2007-10-05 15:03 ` Richard Guenther
2007-10-05 16:20 ` Alexandre Oliva
2007-10-05 16:24 ` Richard Guenther
2007-10-05 16:26 ` Diego Novillo
2007-10-05 20:08 ` Alexandre Oliva
2007-10-09 4:55 ` Alexandre Oliva
2007-10-03 7:45 ` Eric Botcazou
2007-10-03 21:36 ` Eric Botcazou
2007-10-08 20:28 ` Alexandre Oliva
2007-10-05 6:24 ` Eric Botcazou
2007-10-05 16:03 ` Alexandre Oliva
2007-10-07 9:01 ` Eric Botcazou
2007-10-07 23:58 ` Alexandre Oliva
2007-10-08 5:13 ` Eric Botcazou
2007-10-08 20:29 ` Alexandre Oliva
2007-10-08 21:00 ` Eric Botcazou
2007-10-08 23:56 ` Alexandre Oliva
2007-09-29 17:52 ` Reload bug & SRA oddness Diego Novillo
2007-04-20 17:07 ` Daniel Berlin
2007-04-28 20:48 ` Bernd Schmidt
2007-04-28 21:26 ` Richard Guenther
2007-04-28 21:49 ` Daniel Berlin
2007-04-29 10:04 ` Richard Guenther
2007-04-29 10:27 ` Richard Guenther
2007-04-29 10:31 ` Richard Guenther
2007-04-29 11:16 ` Richard Guenther
2007-04-20 14:01 ` Bernd Schmidt
2007-04-20 22:00 ` Eric Botcazou
2007-04-28 16:25 ` Bernd Schmidt
2007-04-28 17:46 ` Eric Botcazou
2007-04-29 6:42 ` Bernd Schmidt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ork5vtu5ev.fsf@free.oliva.athome.lsd.ic.unicamp.br \
--to=aoliva@redhat.com \
--cc=bernds_cb1@t-online.de \
--cc=dberlin@dberlin.org \
--cc=dnovillo@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=pinskia@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).