This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Reload bug & SRA oddness
On May 6, 2007, Alexandre Oliva <aoliva@redhat.com> wrote:
> On May 6, 2007, Bernd Schmidt <bernds_cb1@t-online.de> wrote:
>> Alexandre Oliva wrote:
>>> It might make sense to test whether, instead of a DImode variable, a
>>> pair of SImode variables would do (i.e., no bit-fields crossing the
>>> SImode boundary), as long as registers are known to hold SImode but
>>> not DImode. But is there a generic way to test for such "efficiency
>>> boundaries"?
> This is sort of equivalent. Ok to install on top of the other patch?
> * tree-sra.c (try_instantiate_multiple_fields): Clip alignment
> at word size.
And this is something I'm testing now, that will try to implement the
idea of extending the width to fit fields that cross the alignment
boundary, but not other fields that don't. It makes a lot of
difference for a testcase such as this on x86-32:
struct a {
unsigned long long x : 16, y : 15, z : 33;
};
struct a fa(struct a v) {
return v;
}
struct b {
unsigned long long x : 16, y : 16, z : 32;
};
struct b fb(struct b v) {
return v;
}
Without this patch, the code for fa sucks; with it, it's almost
identical to that of fb, except for ordering of operations.
Ok to install on top of the other two, if it survives bootstrapping
and regtesting on x86-32, where it might have more visible effects
than on x86-64, that doesn't regularly use wider-than-word types?
for gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* tree-sra.c (try_instantiate_multiple_fields): Grow alignment
to fit wider fields that start within the same word.
Index: gcc/tree-sra.c
===================================================================
--- gcc/tree-sra.c.orig 2007-05-06 11:52:33.000000000 -0300
+++ gcc/tree-sra.c 2007-05-06 11:52:38.000000000 -0300
@@ -1521,13 +1521,38 @@ try_instantiate_multiple_fields (struct
if (bit + size == nbit)
{
if ((bit & alchk) != ((nbit + nsize - 1) & alchk))
- break;
+ {
+ /* 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_BIT_SIZE (DECL_MODE (f)) <= align)
+ break;
+
+ align = GET_MODE_BIT_SIZE (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))
- break;
+ {
+ if ((bit & alchk)
+ || GET_MODE_BIT_SIZE (DECL_MODE (f)) <= align)
+ break;
+
+ align = GET_MODE_BIT_SIZE (DECL_MODE (f));
+ alchk = align - 1;
+ alchk = ~alchk;
+
+ if ((nbit & alchk) != ((bit + size - 1) & alchk))
+ break;
+ }
bit = nbit;
size += nsize;
}
--
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}