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.
    Thanks.
     
    joshc, Jan 13, 2005
    #1
    1. Advertising

  2. joshc

    Neil Kurzman Guest

    joshc wrote:

    > 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.
    > Thanks.


    The compiler can do whatever it wants as look as it generates a working
    binary.
    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
    #2
    1. Advertising

  3. joshc wrote:

    > 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 [emitted] object code
    > and just store the value '3' in temp(obviously somewhere on stack)?
    > I think [that], based on my experiments with GCC,
    > the value '3' actually won't 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 argc, char* argv[]) {
    > int 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?


    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:

    > cat f.c

    #include <math.h>

    double f(double x) {
    return sqrt(2.0);
    }

    > gcc -Wall -std=c99 -pedantic -O2 -S f.c
    > cat f.s

    .file "f.c"
    .section .rodata.cst8,"aM",@progbits,8
    .align 8
    .LC0:
    .long 1719614413
    .long 1073127582
    .text
    .p2align 4,,15
    .globl f
    .type f, @function
    f:
    pushl %ebp // superfluous
    movl %esp, %ebp // superfluous
    popl %ebp // superfluous
    fldl .LC0
    ret
    .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 guess [that], since I don't have much of a background in compilers,
    > I'm not sure exactly what a good optimizing compiler can optimize away.


    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,

    > Please point me to any references on this topic as well
    > if you have some.


    I would be interested in any such references as well.
     
    E. Robert Tisdale, Jan 13, 2005
    #3
  4. joshc

    Jack Klein Guest

    On 12 Jan 2005 19:59:05 -0800, "joshc" <> wrote in
    comp.lang.c:

    > 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.


    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.

    > 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.
    > Thanks.


    news:comp.compilers 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
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Jan 13, 2005
    #4
  5. Jack Klein wrote:

    > joshc wrote:
    >
    >>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.

    >
    > 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.
    >
    >>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.
    >>Thanks.

    >
    >
    > news:comp.compilers 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.


    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
    #5
  6. joshc

    Taran Guest

    Neil Kurzman wrote:
    > joshc wrote:
    >
    > > 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;
    > > }


    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
    expected.

    > > 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?


    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
    does.

    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*/
    ia=fa;
    /*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.


    > > 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.
    > > Thanks.


    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.
    HTH
    Regards,
    Taran
     
    Taran, Jan 13, 2005
    #6
  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.

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

    ....

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


    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
     
    Lawrence Kirby, Jan 13, 2005
    #8
  9. On Thu, 13 Jan 2005 10:02:46 +0000, Lawrence Kirby
    <> wrote:

    > On Wed, 12 Jan 2005 22:10:34 -0800, E. Robert Tisdale wrote:
    >
    > ...
    >
    >> Perhaps it would have been better if Josh Curtz had asked,
    >> "What optimizations do the ANSI/ISO standards allow?"

    >
    > 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.


    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
    #9
  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
    manual.

    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);
    else
    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.

    THanks.
     
    joshc, Jan 13, 2005
    #10
  11. joshc

    Chris Torek Guest

    In article <>
    joshc <> wrote:
    >... 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.


    (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.)

    >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.


    Many compilers do various kinds of optimizations. :)

    >... when I was reading the GCC manual regarding the inline keyword
    >it [noted aspects of optimizing inline-expanded functions]. ... 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.


    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.)
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Jan 13, 2005
    #11
  12. joshc

    joshc Guest

    Chris,

    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
    #12
  13. joshc

    joshc Guest

    Chris,

    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
  14. joshc

    joshc Guest

    Chris,

    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
  15. "joshc" <> writes:
    > Chris,
    >
    > 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.


    Josh, you're obviously being bitten by the flawed groups.google.com
    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
    "groups.google.com 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 (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Jan 14, 2005
    #15
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Flip
    Replies:
    3
    Views:
    1,002
    Tony Morris
    Feb 9, 2004
  2. Steve Kershaw
    Replies:
    1
    Views:
    390
    Brennan Stehling
    Sep 26, 2006
  3. DeltaOne
    Replies:
    31
    Views:
    905
    S.Tobias
    May 20, 2005
  4. Ravikiran

    Zero Optimization and Sign Optimization???

    Ravikiran, Nov 17, 2008, in forum: C Programming
    Replies:
    22
    Views:
    903
    Thad Smith
    Nov 24, 2008
  5. kiran
    Replies:
    12
    Views:
    1,216
    Scott Sauyet
    Dec 7, 2011
Loading...

Share This Page