This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]