Re: Re: Integral conversions in C/C++

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue 22/04/08  5:35 PM , Christian Böhme monodhs@xxxxxx sent:
> Optimizers aren't part of the standard.  If the standard(s) were to
> allow for much more explicit expressions, many optimizers would do a
> much better job.  Writing optimizers around standards is what since
> the 90ies characterizes ``good'' compilers.  Here's where the kewl
> stuff happens.

I think you're not giving the compiler enough credit, for example:

.L13:
        movl    (%ebx), %eax
        mull    (%ecx)
        addl    %eax, 16(%esp)
        adcl    %edx, 20(%esp)
        addl    $1, %esi
        addl    $4, %ebx
        subl    $4, %ecx
        cmpl    %edi, %esi
        jne     .L13

is produced from (omitting the loop entirely...):

     _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);

Where mp_word in this case is a "unsigned long long" and so is _W.  What I'm
asking for is a 64-bit MULADD and the compiler does it with a 32x32=>64 mul and
an add/adc chain.  Not too bad for a "standards comforming" compiler if you ask
me.  It realizes that both operands are actually 32-bits but that I want the
product to be 64-bit.  So it does the fast 32x32 mult AND keeps the upper product
[EDX in this case].

BTW that's a snippet from my LibTomMath library.  In case you're wondering ... I
write performance portable C cryptographic code for a living, so I know a bit
about what I'm talking...

The trick is to comply with the standard (such that the compiler is worth beans)
but to then really take a hard look at what the user is actually doing.  If you
interpret the standard naively the code above "requires" a 64x64 mult.  However,
the spec only says that the code generated must emulate the standard, not follow
it naively.  So as long as the correct result occurs the compiler is correct.  In
this case, GCC is smart about the operands and simplifies the operation to a
32x32 mult.  

Again, you're inability to understand the way things are doesn't mean you're
correct.  GCC does a very good job at optimizing C code all while following the
specs fairly well in my opinion (have yet to really bump into a gcc-bug of my own
in a long time).  

I think once you figure out that both

(unsigned)-1

and 

unsigned a = 1; -(a)

Result in the same expression type, the better off you'll be. 

The C spec is actually very strict about the type of expressions (I mean data
type).  so when I say 

unsigned char = (unsigned long)((int) + (unsigned)) * (double)

I can follow the precedence tree and know what the data types are at each stage.
 If we allowed the types to be assigned out of order the expressions and the
statement as a whole become undefined and meaningless.  

Assuming you're not a complete troll just trying to cause noise on the list ... I
suggest you read a good book about compiler theory.  When I say statement or
"expression," it might help if you understand what I'm talking about.  That way
you'll fully get the value of my emails, ideally acknowledge that I'm right, go
away, lead a productive life, marry, have kids, and tell them the story about how
some guy who was bored between guitar and piano practice at home after a hard
days of work decided to drop a message and help clear things up.

just saying ...

Tom



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux