This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


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

Re: Totally bogus string optimizations


On 28 Oct 2000, Ulrich Drepper wrote:

> Bernd Schmidt <bernds@redhat.co.uk> writes:
> 
> > #include <string.h>
> > char *p;
> > int main ()
> > {
> >   strcpy (p, "Foobar");
> > }
> > 
> > causes _horrendous_ assembly code to be generated.  Apparently, for a machine
> > that does not define _STRING_ARCH_unaligned, /usr/include/bits/string2.h
> > contains totally bogus code.
> 
> Well, maybe you should look then at the compiler.  We just describe
> something in C which the compiler isn't able to optimize.  It's the
> same old story: people are asked to use inline functions but when they
> do they are screwed because the compiler is handling them in a
> horrible way.
> 
> They used to work just fine and is much faster back then.  But in the
> meantime gcc apparently was broken.

I kind of disbelieve this.  It fails to produce decent code with 2.7.2.3,
2.95.2 and current CVS.
And it's not even surprising: you've exchanged something that would be easy for
the compiler to recognize and optimize (a constant string copy) with something
that is much more complex and therefore not nearly as easy to optimize.

> For this case (with _STRING_ARCH_unaligned), why isn't gcc recognizing
> an inline function called with all constant parameters and so does not
> even try to create the parameter list?

Inlining isn't the central problem here, although it probably contributes.  The
main problem is that the code in string2.h expects that the compiler will be
able to do something sane with

	typedef struct
	{
	  unsigned char __arr[7];
	}
	__STRING2_COPY_ARR7 __attribute__ ((packed));
	int
	main ()
	{
	  __STRING2_COPY_ARR7 tmp = __extension__ ((__STRING2_COPY_ARR7){
	  {
	  ((__const char *) ("Foobar"))[0], ((__const char *) ("Foobar"))[1],
	  ((__const char *) ("Foobar"))[2], ((__const char *) ("Foobar"))[3],
	  ((__const char *) ("Foobar"))[4], ((__const char *) ("Foobar"))[5], '\0'}
	  });
	}

and no, gcc is not able to turn the structure initializer into a constant - it
has to go through memory for the single byte stores.  I'd be very surprised if
egcs-1.0 or egcs-1.1 did have the ability to recognize this as a single long long
constant.

> And no, the compiler is not able to optimize as good.  If the compiler
> would work correctly an strcpy() like your example would be
> transformed into something like this
> 
> 
>     ...get dest address in %eax...
>    movl $0x626f6f46, (%eax)
>    movw $0x7261, 4(%eax)
>    movb $0, 6(%eax)
> 
> 
> which is much better since we have no loading, no relocation (this is
> a data relocation which always has to be performed), and not another
> string constant.

Then we should fix gcc to do this rather than hacking around the problem.


Bernd


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