Related articles |
---|
Question about MS C code generation ruicui@sohu.com (2003-11-21) |
Re: Question about MS C code generation joachim.durchholz@web.de (Joachim Durchholz) (2003-12-03) |
Re: Question about MS C code generation tmk@netvision.net.il (2003-12-03) |
Re: Question about MS C code generation vbdis@aol.com (2003-12-03) |
Re: Question about MS C code generation bonzini@gnu.org (2003-12-03) |
From: | bonzini@gnu.org (Paolo Bonzini) |
Newsgroups: | comp.compilers |
Date: | 3 Dec 2003 20:32:23 -0500 |
Organization: | http://groups.google.com |
References: | 03-11-090 |
Keywords: | code, optimize |
Posted-Date: | 03 Dec 2003 20:32:22 EST |
> if(a<0) b=-5;
> else if(a>=0) b=5;
> else b=0;
I guess that you meant a>0 in the second line.
> [which the compiler rewrites to]
>
> if(a>=0) {
> if(a<=0) b=0;
> else b=5;
> } else b=-5;
The compiler is only inverting the conditions (either according to
what it thinks the branch probabilities are, or just because it likes
it better this way).
Now, let's look at the second snippet. The compiler is trying to
remove a jump, so it does this:
> xor eax, eax
> cmp [ebp+nA], 0
> setle al
AL = (a <= 0) ? 1 : 0;
> dec eax
AL = (a <= 0) ? 0 : -1;
> and eax, 5
AL = (a <= 0) ? 0 : 5;
that is, AL = (a > 0) ? 5 : 0. As I said, this is a transformation
with which the compiler tries to avoid unnecessary jumps; there are a
number of these hardcoded in the optimizer (in the case of gcc, they
call it "if conversion").
On to the next question:
> mov [ebp+nTmp], ecx
> mov edx, [ebp+nTmp]
>
> WHY USE A TEMPORARY VARIABLE ?
Are you using the top optimization level? It does not seem very smart
indeed.
> 4) if asked, how would you write this program in assembly ?
xor ecx, ecx ;We need the top 24 bits cleared
xor edx, edx
cmp [var], 0
setg cl ;ECX=1 if EAX>0
setl dl ;EDX=1 if EAX<0
sub ecx, edx ;ECX=sign of EAX
lea [ecx*4+ecx],ecx ;ECX=sign of EAX * -5
or
cmp [var], 0
setg cl ;CL=1 if EAX>0
setl dl ;DL=1 if EAX<0
sub cl, dl ;CL=sign of EAX
movsx ecx, cl ;ECX=sign of EAX
lea [ecx*4+ecx],ecx ;ECX=sign of EAX * -5
But I do not expect a compiler to recognize this. It corresponds to
another way to express your expression: 5 * ((a > 0) - (a < 0))
Also note that if you need an 8-bit result you can drop the first two
instructions (the XORs), or the MOVSX in the second example.
Finally, if you are testing a register, I'd suggest OR EAX, EAX
instead of a compare with zero (a byte smaller). And if you are on a
PII or later, what about
xor ecx, ecx
cmp [var], 0
cmovl ecx, -5
cmovg cl, 5
This *is* something I'd expect out of a smart compiler, if told to
generate CMOV instructions.
Paolo
Return to the
comp.compilers page.
Search the
comp.compilers archives again.