Re: Optimisation puzzle

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

 



On 3/16/07, Erik <sigra@xxxxxxx> wrote:
Ian Lance Taylor skrev:
> Erik <sigra@xxxxxxx> writes:
>
>
>>  From man:puts I see that it is declared "int puts(const char
>> *)". This means that puts does not promise to leave its argument
>> unchanged. Therefore the caller must push the argument anew before
>> each call. If it had been declared "int puts(const char * const)"
>> instead, the push should be moved outside the loop. Unfortunately this
>> does not seem to work. I tried with the following program:
>> void q(const unsigned int);
>> void f() {for (unsigned int x = 0; x != 10; x++) q(77);}
>>
>> and built it with "gcc -std=c99 -Os -Wall -Wextra -Werror -S":
>> .L2:
>>         subl    $12, %esp
>>         incl    %ebx
>>         pushl   $77
>>         call    q
>>         addl    $16, %esp
>>         cmpl    $10, %ebx
>>         jne     .L2
>>
>> As you can see, "pushl   $77" is still inside the loop even though q
>> promises to not change its argument. This must be a bug.
>
> This is not a bug.  const on an automatic variable in C is more
> advisory than anything else.  You are not permitted to change a const
> object, but you can cast its address to a non-const pointer.

The "lost optimization" in this case has nothing to do with const
versus non-const.  The issue is that the call deallocates the
parameters. The pushl is allocating the argument.

While it is possible to avoid the deallocation and reallocation,
doing so requires either changing the calling convention or doing
"whole program" optimization.  In either event, all of the tools
that understand the calling convention, like the debugger, would
need to be modified.  Again, this can be done, but not without
investment and a period of "bugs".

Note that in C++, you are not permitted to modify a const parameter.
The compiler can optimize on that basis, but in this case, the code
would be unaffected because of the allocation issue.

It is a bug. If not in gcc, then in C, that allows the programmers to do
such strange things, preventing the compiler from optimizing the code.
The right thing for gcc to do would be to enable such optimizations and
warn when the code casts away constness, that it could break optimized
code. I believe that is what gcc already does for some stupidities; gcc
performs some optimizations that are broken by reinterpret_cast and
gives "warning: dereferencing type-punned pointer will break
strict-aliasing rules". So gcc should be modified to be useful for users
who need the optimization but not the bizarre misfeatures of C.

Given the need for compatibility with existing programs at the
time that const was introduced, I don't think it is possible to
have the kind of const safety that you seem to want.

Anyway, it is surely a bug that gcc does not optimize away the "pushl
$77" inside the loop from the Ada program.

I think the Ada behavior is correct as well, because of the argument
allocation.  Skipping that would change the ABI, which should not
be done lightly.

Unlike C, Ada was not designed for ugly hacks, but for clarity
and for letting compilers perform optimizations.

I think that is an unfair characterization of C.  The C language was
designed to let programmers do the kinds of optimizations that most
compilers of the day were not doing.  It enabled many programmers
get out of assembly coding.

Ada had the advantage of being designed some ten years after C,
when compilers could be relied upon to do optimizations.  Even so,
it was a bit of a stretch, and Ada lost many of its potential users
because of poor initial performance.  I am not saying that the Ada
designers made a mistake, just that there were consequences.

So a promise is a promise. If a function says it will not touch
something, it won't.

But, as I've shown, this notion does not apply to the example.

--
Lawrence Crowl

[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