I currently have inline functions calling another inline function (a simple 4 lines big getAbs() function). However, I discovered by looking to the assembler code that the "big" inline functions are well inlined, but the compiler use a bl jump to call the getAbs() function.

Is it not possible to inline a function in another inline function? By the way, this is embedded code, we are not using the standard libraries.

Edit : The compiler is WindRiver, and I already checked that inlining would be beneficial (4 instructions instead of +-40).

What compiler are you using? There are often ways to force inlining. I presume you've already profiled your code and are pretty confident that inlining will be beneficial. In GCC this can be done with __attribute__((always_inline)).
–
stinky472Jun 30 '10 at 8:30

Can I ask why you care about what decisions the compiler has made? Have you profiled the code and found the overhead of that one jump instruction is killing performance?
–
JeremyPJun 30 '10 at 8:44

5 Answers
5

Depending on what compiler you are using you may be able to encourage the compiler to be less reluctant to inline, e.g. with gcc you can use __attribute__ ((always_inline)), with Intel ICC you can use icc -inline-level=1 -inline-forceinline, and with Apple's gcc you can use gcc -obey-inline.

The inline keyword is a suggestion to the compiler, nothing more. It's free to take that suggestion on board, totally ignore it or even lie to you and tell that it's doing it while it's really not.

The only way to force code to be inline is to, well, write it inline. But, even, then the compiler may decide it knows better and decide to shift it out to another function. It has a lot of leeway in generating executable code for your particular source, provided it doesn't change the semantics of it.

Modern compilers are more than capable of generating better code than most developers would hand-craft in assembly. I think the inline keyword should go the same path as the register keyword.

If you've seen the output of gcc at its insane optimisation level, you'll understand why. It has produced code that I wouldn't have dreamed possible, and that took me a long time to understand.

As an aside, check this out for what optimisations that gcc actually has, including a great many containing the text "inline" or "inlining".

I'd venture a guess and say that the keyword was added when the task of figuring out if the function could be inlined was a bit too big for the compiler (either functionality-wise or time-wise), but todays compiler is probably capable of figuring out this by themselves, even if the inline keyword is not present. Just a guess though.
–
Lasse V. KarlsenJun 30 '10 at 8:08

Does gcc support profile-based optimizations? When not using those, it makes a lot of sense to hint at gcc where inline might help. This is based on knowledge of whether the function will be called a lot or not, something that the smartest compiler still cannot tell.
–
PeakerJun 30 '10 at 9:47

The inline keyword is still useful, because it allows you to define the same function in multiple translation units, as long as you use an identical definition (the practical upshot of this being that you can put inline function definitions into header files, allowing cross-module inlining).
–
cafJul 1 '10 at 0:30

@gramm: There's quite a few scenarios in which inline isn't necessarily to your benefit. Most compilers use some very advanced heuristics to determine when to inline. When discussing inlining, the simplest idea is, trust your compiler to produce the fastest code.

I have recently had a very similar problem, reading this post has given me a wackky idea. Why not Have a simple pre-compilation (a simple reg ex should do the job ) code parser that parses out the function call to actually put the source code in-line. use a tag such as /inline/ /*end_of_inline*/ so that you can use normal ide features (if you are or might use an ide.
Include this in your build process, that way you have the readability advantage as well as removing the compilers assumption that you are only as good a developer as most and do not understand when to in-line.

Nonetheless before trying this you should probably go through the compilers command line options.

I would suggest that if your getAbs() function (sounds like absolute value but you really should be showing us code with the question...) is 4 lines long, then you have much bigger optimizations to worry about than whether the code gets inlined or not.

Either you're saying that any overhead of calling a function is less important for short functions, or you're saying that having short functions is a generally bad thing, either way you get -1
–
Pete KirkhamJun 30 '10 at 8:30

No, I'm saying that a poor implementation of abs() is a much bigger performance hit than the compiler failing to inline it. (And in fact the compiler may be doing the right thing by not inlining it..)
–
R..Jun 30 '10 at 9:46

Same than Pete. Having 50 instructions instead of 5 is a huge overhead, and it usually becomes noticeable when used in a loop. I'm not sure if you're used to work with microcontrollers.
–
grammJun 30 '10 at 9:47

let's see - one line function decl, one line {, one line return x < 0 ? -x : x; one line } = 4 lines. Write an abs with fewer than four lines if you can.
–
Pete KirkhamJun 30 '10 at 17:19