Compiler code optimization: see code below

Discussion in 'C Programming' started by joshc, Jan 13, 2005.

  1. joshc

    joshc Guest

    I'm writing some C to be used in an embedded environment and the code
    needs to be optimized. I have a question about optimizing compilers in
    general. I'm using GCC for the workstation and Diab compiler for the
    embedded target.

    My question is about how compilers optimize certain code sequences.

    As an example, take the code below. Will the compiler eliminate the
    actual function call to foo() in the object code generated and just
    store the value '3' in temp(obviously somewhere on stack)? I think
    based on my experiments with GCC the value '3' actually wont' be stored
    at all since it's obviously not being used anywhere. My tests showed
    that no function call is made in the object code and neither is any
    value being stored in temp.

    int main() {
    int temp;

    temp = foo(3);

    return 0;

    int foo(int x) {
    return x;

    Now as a general question, if I have function calls in my code in which
    the arguments I am passing to the function are known at compile time,
    will these function calls be eliminated by the compiler?

    I guess since I don't have much of a background in compilers I'm not
    sure what exactly a good optimizing compiler can optimize away. Please
    point me to any references on this topic as well if you have some.
    joshc, Jan 13, 2005
    1. Advertisements

  2. joshc

    Neil Kurzman Guest

    The compiler can do whatever it wants as look as it generates a working
    different compilers (or different versions) may do different things.
    The compiler Docs should tell you what types of optimization it can do.
    Neil Kurzman, Jan 13, 2005
    1. Advertisements

  3. Yes, if the function definition is visible to the compiler.
    To be safe, you should probably write

    inline static
    int foo(int x) {
    return x;

    int main(int argc, char* argv[]) {
    int temp = foo(3);
    // stuff
    return 0;

    It should also work for standard math functions:
    #include <math.h>

    double f(double x) {
    return sqrt(2.0);
    .file "f.c"
    .section .rodata.cst8,"aM",@progbits,8
    .align 8
    .long 1719614413
    .long 1073127582
    .p2align 4,,15
    .globl f
    .type f, @function
    pushl %ebp // superfluous
    movl %esp, %ebp // superfluous
    popl %ebp // superfluous
    fldl .LC0
    .size f, .-f
    .section .note.GNU-stack,"",@progbits
    .ident "GCC: (GNU) 3.4.1"

    The pair of long data words at LC0 represent sqrt(2.0).
    I'm not sure either.
    Optimization is always at the cutting edge of compiler technology.
    It is one of the ways that compiler developers compete with each other.
    I always test for the optimizations that I think are important.
    Sometimes, my compiler fails to perform the optimization that I expect
    so I run benchmarks to determine whether or not my optimization
    actually result in faster code -- they usually don't.
    For example, in the above code,
    there appear to be three superfluous instructions
    but I doubt that the function f(double) would be any faster
    if I removed them -- it might actually run slower.
    Sometimes compilers leave superfluous instructions
    in the code to serve as no-ops to prevent pipeline stalls
    or to align the instruction stream properly,
    I would be interested in any such references as well.
    E. Robert Tisdale, Jan 13, 2005
  4. joshc

    Jack Klein Guest

    The C standard does not define how compilers optimize certain code
    sequences, nor does it require them to do so. It is entirely up to
    the compiler and the options with which you invoke it.
    would probably be a good reference to what "a good
    optimizing compiler can optimize away", but that won't necessarily do
    you any good at all. Note also that the issue is off-topic here, as
    optimization is always an implementation issue, not a language issue.

    The simple fact is that if it is important to you know what your
    compiler does to your code, then compile your code with your compiler
    and examine the generated object code or its assembly language
    equivalent. That will give you exact answers, as opposed to
    hypothetical indications of what a compiler might do.

    Optimization with a specific compiler like gcc will vary greatly with
    version, target architecture, and compiler options.

    Neither optimization nor efficiency is defined by the C standard.
    Only the observable output of a strictly conforming program. An
    implementation that generated a Perl script from your source code and
    invoked a Perl interpreter to execute the script could be a strictly
    conforming C implementation if the observable output of the Perl
    script was correct.
    Jack Klein, Jan 13, 2005
  5. That is certainly all true but I don't think that's the issue here.
    It isn't about any particular implementation
    but implementations in general.

    Too many C programmers write bad code
    while attempting to out-wit their compilers
    or appease deficient optimizing compilers.
    The result is code that is unreliable,
    hard to read, understand and maintain
    and that frustrates optimizing C compilers
    when C programmers attempt to port the code.

    Perhaps it would have been better if Josh Curtz had asked,
    "What optimizations do the ANSI/ISO standards allow?"

    My personal approach is to write code assuming that
    my C compiler or some C compiler for my target platform(s)
    will [eventually] perform *all* of the optimizations
    that the ANSI/ISO C standards allow.
    That is to say that, "I avoid premature optimization."
    E. Robert Tisdale, Jan 13, 2005
  6. joshc

    Taran Guest

    I am not sure about gcc compiler. All that I say is regarding the diab
    5.1.2 compiler.

    Also compiler can do anything, what I say is based on my observation.

    The dcc did not generate any code for foo except for blr. The main
    doesn't have call to foo and it just returns. BUT I had maximum
    optimization switch on. So this does make sense. If you set the
    optimization switch to least or no optimization the results would be as

    As of what I have seen, knowing the arguments to be passed doesn't say
    anything. Its whether your processing something and returning it.

    If I have say
    /**/ void some(int temp)
    /**/ {
    /**/ int local=temp;
    /**/ return local; /* or return temp*/
    /**/ }

    /**/ int main(void)
    /**/ {
    /**/ some(9);
    /**/ }

    The _some would be optimized as it doesn't makes sense there.
    Parameters passed by value, do something but not return. The function
    as such doesn't do anything. Remove it. And that's what the compiler

    But if I have
    /**/ int some(int temp)
    /**/ {
    /**/ return temp*2;
    /**/ }

    The some would not be optimized and instructions will be there for it.
    To force the compiler to not optimize the code use volatile.

    For simple C instructions like implicit cast:
    int ia;
    int fa=25.27;
    /*some code*/
    /*some more code*/

    For same compiler options the compiler can either
    A) addi rx,r0,25; where rx holds ia
    B) or else have a set of instructions to cast fa to it.

    For diab read the dcc user manual chapter on optimization.

    I would again reiterate that what a compiler can do anything it deems
    necessary to optimize the code and also it depends heavily on the
    values of optimizations switches given when compiling.
    Taran, Jan 13, 2005
  7. joshc

    Taran Guest

    One more thing:

    Passing pointers to functions, the compilers understands it differently
    as against passing params by value and it doesn't optimize and remove
    the function or some of its C source (all or some).

    Declaring varaibles as volatile doesn't optimize the function. the
    function call is still there and all the C level code translates to
    identifiable assembly level instruction. But this particular to dcc.
    Diab removed the call to the function.

    Taran, Jan 13, 2005
  8. On Wed, 12 Jan 2005 22:10:34 -0800, E. Robert Tisdale wrote:

    Th answer to that is anything at all as lon as the program produces
    correct output. At that point it is a case of understanding what behaviour
    the standard does and doesn't require for particular constructs.

    Lawrence Kirby, Jan 13, 2005
  9. Including, if the compiler knows all the information it needs, producing
    a program which doesn't do anything. This can be a problem if the
    optimisation has bugs, on the first system I used professionally when I
    looked at the assembler output to try to issue a patch (in those days it
    was a lot cheaper to patch machine instructions than to send out a tape
    with the complete binary) I found that the optimiser had deleted a whole
    function because it thought that it wasn't used...

    Chris C
    Chris Croughton, Jan 13, 2005
  10. joshc

    joshc Guest

    Hey guys,

    THanks for all your replies. Yes, I realized this was probably better
    suited for comp.compilers and that's why minutes after I posted I tried
    to use the "remove" option but I guess somehow my message was still
    posted to the group. The reason I posted in this forum was casue I saw
    a similar question on comp.lang.c from a few days ago and no one seemed
    to complain.

    I realize that the optimizations that I asked about have nothing to do
    with the standard. I simply wanted to see whether or not any compilers
    out there do what I was asking about more as a question to educate
    myself about compilers. I definitely will end up looking at my compiler

    Just in case anyone is interested, the reason I asked the question
    initially was because when I was reading the GCC manual regarding the
    inline keyword it said that if I had something like:

    inline static int foo(int x) {
    if (x > THRESHOLD)
    return foo1(x);
    return foo2(x);

    then it said that GCC could optmize foo() if the argument 'x' was known
    at compile time and you would end up with just a function call foo1()
    or foo2() without the if-else conditional. It seemed to imply that
    this happened because of using the 'inline' keyword so I was wondering
    if I picked up on that correctly or if that kind of optimization also
    happened in functions that are _not_ inlined.

    joshc, Jan 13, 2005
  11. joshc

    Chris Torek Guest

    (Newsgroup postings are generally not cancel-able at all anymore,
    because vandals used to use the feature to remove everything from
    some or all newsgroups.)
    Many compilers do various kinds of optimizations. :)
    In general, this kind of optimization can only happen if the
    body of the function is expanded in line in the caller (because
    the constraints on the operands are not known at compile time
    in the other case). But gcc will sometimes do in-line expansion
    of functions even when they are *not* declared "inline"; and as
    it happens, Diab does even-more-aggressive function inlining than
    gcc, in general.

    Even in C90 (which has no "inline" keyword), you can "encourage"
    a compiler to in-line-expand a short function by defining it before
    calling it:

    /* the "static" here is optional but generally good */
    static int f(int x) {
    return x + 1;
    void g(args) {
    result = f(1);

    A practical C compiler *has* to read source code "top to bottom", as
    it were, starting at the beginning of the source file and ending at
    the end. Because of this, it will have "seen" all of f() by the time
    it gets to compiling g(). If f() is small (as here), and the compiler
    does this kind of optimization at all, there is a good chance it will
    remove the call and, in this case, just do "result = 2".

    Note that by making f() static, f() becomes invisible to other
    translation units (roughly, "source files"), so not only can the
    compiler expand calls to f() in line, it can also not bother
    generating any actual function f() in the first place. This also
    allows you to violate the usual rules about C code, and put the
    entire function f() in a header file that gets included in multiple
    translation units. (If the compiler does *not* do inline expansion
    and optimizations, this will waste code space in the final executable,
    but still *work* OK.)
    Chris Torek, Jan 13, 2005
  12. joshc

    joshc Guest


    Thanks for your reply. Yeah, I know about the inlining details since I
    investigated that a while back as I noticed the object code for the
    inline function was emited even though I had my compiler options set to
    force inlining. Obviously it turned out it had to be declared as inline
    static and defined before it's use.
    joshc, Jan 13, 2005
  13. joshc

    joshc Guest


    Thanks for your reply. Yeah, I know about the inlining details since I
    investigated that a while back as I noticed the object code for the
    inline function was emited even though I had my compiler options set to
    force inlining. Obviously it turned out it had to be declared as inline
    static and defined before it's use.
    joshc, Jan 13, 2005
  14. joshc

    joshc Guest


    Thanks for your reply. Yeah, I know about the inlining details since I
    investigated that a while back as I noticed the object code for the
    inline function was emited even though I had my compiler options set to
    force inlining. Obviously it turned out it had to be declared as inline
    static and defined before it's use.
    joshc, Jan 13, 2005
  15. Josh, you're obviously being bitten by the flawed
    posting interface. I presume you didn't mean to post that same
    article 3 times. We see a lot of Google users doing that kind of
    thing; I'm not quite sure why. You also didn't provide any context or
    attribution. Don't use the "Reply" link at the bottom of the article;
    instead, click on "show options" and then on the "Reply" link just
    under the article's headers.

    For more information, search for my article in comp.lang.c, subject
    " indentation bugs [semi-OT]" (that's one thing that
    Google is still reasonably good at).

    And you might want to complain to Google if you're so inclined.
    Keith Thompson, Jan 14, 2005
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.