This is the mail archive of the gcc-bugs@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]

Casting results in useless instructions



Hello there.

I was examining the assembler output of some C++ code, to see how well egcs
optimizes templates. The result was pretty darn impressive, except for one
thing: my templates had some reinterpret_casts in them, and although I have
always thought that reinterpret_casting is an absolutely costless operation,
I noticed that the resulting code allocated lotsa space for local variables,
and then it stored individual temporary values (apparently "results of
casts") to this local space, and never used it. Thus the function code was
interspersed with actual computing, and some useless instructions.

I cannot really give the complete templates in question here, but this is a
really minimal piece of code which shows what happens:

typedef struct _Scm{
	long a;
}Scm;

Scm fooble(Scm b){
	b=*(Scm*)(b.a);
	b=*(Scm*)(b.a);
	b=*(Scm*)(b.a);
	return b;
}

I use C syntax here, because I also tried to compile this as C. On an i386
machine (well, a Cyrix 6x86 really), this is the assembler output:

	.file	"tst.C"
	.version	"01.01"
/ GNU C++ version egcs-2.90.29 980515 (egcs-1.0.3 release) (i586-pc-linux-gnu) compiled by GNU C version egcs-2.90.27 980315 (egcs-1.0.2 release).
/ options passed:  -O3 -freg-struct-return -fomit-frame-pointer
/ options enabled:  -fdefer-pop -fomit-frame-pointer -fcse-follow-jumps
/ -fcse-skip-blocks -fexpensive-optimizations -fthread-jumps
/ -fstrength-reduce -fpeephole -fforce-mem -ffunction-cse
/ -finline-functions -finline -fkeep-static-consts -fcaller-saves
/ -freg-struct-return -frerun-cse-after-loop -frerun-loop-opt
/ -fschedule-insns2 -fexceptions -fcommon -fverbose-asm -fgnu-linker
/ -fregmove -falias-check -fargument-alias -m80387 -mhard-float
/ -mno-soft-float -mieee-fp -mfp-ret-in-387 -mschedule-prologue
/ -mcpu=pentium -march=pentium

gcc -freg-struct-return -fomit-frame-pointer -O3 -S tst.C

gcc2_compiled.:
.text
	.align 4
.globl fooble__FG4_Scm
	.type fooble__FG4_Scm,@function
fooble__FG4_Scm:
.LFB1:
	movl 4(%esp),%eax
	movl (%eax),%eax
	movl %eax,4(%esp)
	movl (%eax),%eax
	movl %eax,4(%esp)
	movl (%eax),%eax
	movl %eax,4(%esp)
	ret
.LFE1:
.Lfe1:
	.size fooble__FG4_Scm,.Lfe1-fooble__FG4_Scm
	.ident"GCC: (GNU) egcs-2.90.29 980515 (egcs-1.0.3 release)"

You see something bogus here?

Then again, compiling with the same flags, except with -x c:

gcc2_compiled.:
.text
	.align 4
.globl fooble
	.type fooble,@function
fooble:
	movl 4(%esp),%eax
	movl (%eax),%eax
	movl (%eax),%eax
	movl (%eax),%eax
	ret
.Lfe1:
	.size fooble,.Lfe1-fooble
	.ident"GCC: (GNU) egcs-2.90.29 980515 (egcs-1.0.3 release)"

And this is of course how it should be. Note that this only seems to happen
with assignments. If I put all those casts into one expression and return
that directly, everything seems to be okay. Likewise, if an Scm object is
initialized with such a result.

This is really a problem. In one of my functions, compiled with maximum
optimizations, the assembly code has 56 lines, 18 of which are of the form:

	movl %e?x, ?(%esp)

And none of these stored values are used for anything. Rather annoying,
considering that the rest of the code is really brilliantly optimized. I was
wondering if this could have been the result of some obscure flag, but I've
tried about everything..

So could someone have a look into this? Thankee..


Lauri Alanko
la@iki.fi

P.S. As a side note, why is -freg-struct-return not the default default?


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