When are functions inlined within the compilation process [duplicate] - c++

This question already has answers here:
How will i know whether inline function is actually replaced at the place where it is called or not?
(10 answers)
Closed 9 years ago.
In gcc, using
-E gives the preprocessed code;
-S, the assembly code;
-c, the code compiled, but not linked.
Is there anything close to a -I, that would allow me to see whether a function has been inlined or not, i.e., to see the code expanded, as though inline functions were preporcessed macros?
If not, should I get my way through the assembly code, or are the inline applications performed later?

I think examining the assembly code is the best (and pretty much the only) way to see what's been inlined.
Bear in mind that, in certain circumstances, some inlining can take place at link time. See Can the linker inline functions?

You can use the -Winline option to see whether a function can not be inlined and it was declared as inline.
Quoted from http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#Warning-Options
-Winline
Warn if a function that is declared as inline cannot be inlined. Even with this option, the compiler does not warn about failures to inline functions declared in system headers.
The compiler uses a variety of heuristics to determine whether or not to inline a function. For example, the compiler takes into account the size of the function being inlined and the amount of inlining that has already been done in the current function. Therefore, seemingly insignificant changes in the source program can cause the warnings produced by -Winline to appear or disappear.
However, inline is not a command, whether inline a function or not(though declared as inline) is decided by the compiler. It may consider the size of the function being inlined and how many times inline already been done in the current function.
The best way to see whether a function has really been inlined is to check the assembly code. For example, you can use
gcc -O2 -S -c foo.c
to generate assembly code for foo.c and output assembly code file foo.s.

The issue here is that generally inlining is a link time optimaztion (when there are multiple object files) as the compiler simply doesn't see the implementation of functions in other object files, until link time.
Hence in multi object file compiles your best shot is to inspect the generated assembly, however within every single object file, the inlining is possible, assuming the function to be inlined is in the same compilation unit, however most compilers do not do inlining at this point, as it doesnt know where this function may be called from, and whether it should itself be inlined.
So in general inlining is performed on linking, however for very small functions, it can and should be done at compilation time.
Also I do believe that if you compile your code with clang/llvm, you'll get a c output file with inlining, tho I haven't tried it.
Do note that in order to get GCC to do the link time optimization (including inlining) you'll have to provide it with an argument, I think its -flto.
An alternative is to have all your inline functions visible in your all of your compilation units (e.g. In the header files), this will actually usually ensure inlining in order to avoid multiple declarations of the same function, in different object files.
Also an easy way to check the assembly for inlining is to compare the number of calls to the function in the source code to the number of calls in the assembly.

Related

Will compilers inline functions without bodies?

Let's imagine a blah.h header file that contains:
// A declaration without any code. We force inline
__attribute__((always_inline)) void inline_func();
And a blah.cpp source file that contains:
#include "blah.h"
// The code of the inline function
void inline_func() {
...
}
// Use the inline function
void foo() {
inline_func();
}
The question is, will the compiler actually inline the inline_func()? Should the code be with the declaration or they can be separate?
Assume no LTO
Note the (GCC) force inline decoration in inline_func()
Inlining is a two-step process:
* Is it possible?
* Is it worthwhile?
The first step is fairly trivially decided by the compiler, the second is a far more complex heuristic. Thus it makes sense to only consider the benefits of possible optimizations.
always_inline means that the second step is ignored. It does not affect the first consideration. Now, you've also stated that LTO is disabled, which means that first consideration, the ability for inlining, is restricted. This shows that LTO and always_inline are pretty unrelated since they affect two different inlining considerations.
Not that LTO matters for your example anyway. The two functions under consideration are in the same Translation Unit. There appear to be no other restrictions such as recursion, library calls, or other observable side effects. That means it should be possible to inline, and since that's the only consideration, it should be inlined.
You need to have the body available at the time the inlining is supposed to happen.
I.e. if you have the following files:
inlineFunc.h
inlineFunc.c
main.c
And you compile with:
compile inline.c
compile main.c
link innline.o mcompile inline.c
compile main.c
link innline.o main.o yourCoookProgramain.o yourCoookProgram
there is no way that inlineFunc gets inlined in main.c however calls to inlineFunc in inlineFunc.c can be inlined.
As Paolo mentioned, inline is only a hint to a compiler however some compilers also have ways to force the inining, i.e. for gcc you can use __attribute__(always_inline). Take alook here for a discussion on how gcc handles inlining.
An interesting sitenote:
The warning is issued in this case as the definition of foo() is not
available when main() is compiled. However, with -O2 or better
optimizations, gcc performs a kind of "backward inlining", meaning
that even function definitions that are further ahead in the source
file can be embedded into a caller. Consequently, the warning
disappears as soon as one uses at least -O2 optimizations. Is there
any specific option responsible for this behavior? I would like to
enable "backward inlining" even with -O1 or -O0.
Well, it depends. In your example, it will be inlined, because the definition of the function is in the same translation unit where it is used.
Otherwise, if no LTO is possible, and at compile time the definition of the function is not available to the compiler, then no, the function will not be inlined.
Prior answer
The answer is: it depends. It depends on the compiler, and it may depend on compiler's configuration(1)(2) too.
See also inline description at cppreference.com (quoted below):
The intent of the inline keyword is to serve as an indicator to the optimizer that inline substitution of the function is preferred over function call, that is, instead of executing the call CPU instruction to transfer control to the function body, a copy of the function body is executed without generating the call. This avoids extra overhead created by the function call (copying the arguments and retrieving the result) but it may result in a larger executable as the code for the function has to be repeated multiple times.
Since this meaning of the keyword inline is non-binding, compilers are free to use inline substitution for any function that's not marked inline, and are free to generate function calls to any function marked inline. Those choices do not change the rules regarding multiple definitions and shared statics listed above.

how to check an inline function was automatically converted to a regular function by the compiler?

I know in some cases, the explicitly defined inline function will be converted to the regular function with calling stacks by the compiler. By how do I know this is the case? (for my C++ code)
BTW, in what circumstances will the compiler transform an inline function to a regular function?
You run nm or otool on the executable, and if you see the name of the function, then it has been defined. That doesn't mean that it hasn't indeed been inlined at all (it's possible that the compiler inlines a function but also generates an independent function body because for example one assigns a function pointer to it). For that, you need to examine the actual generated assembly code.
The keyword inline does not mean that the function will be inlined (or not). It means allow for multiple definitions in different translation units of the same program. The compiler will not transform an inline into a non-inline, it will follow the rules set in the standard and (almost) orthogonally determine whether to inline or not your functions.
As of whether to determine if a function was inlined or not, the guaranteed way to do so is checking the generated object code (or assembly). Checking whether there is an out-of-line definition of the function won't help, as many compilers will generate that out-of-line definition even if the code was actually inlined.
The compiler will DEFINITELY produce a regular function if the inline function has it's address taken (that is, you are making a function pointer to it, or something similar). And of course, if the function is virtual, it also has to exist as a standalone function since a virtual function call is not always possible to inline.
Other than that, it's entirely up to the compiler - it uses all manner of heuristics, such as "How big is the function?", "how many times is it called?", "how much 'gain' is there from inlining it?". If a function is called many times, and is quite large, it is probably left as a standalone function. If the function is only called a few times, or it's tiny, then it's inlined [assuming the compiler actually CAN inline it, of course - as described above, it may not be able to]. Also, nearly all compilers need to "see" the source code of the function to inline the function, but both GCC/G++ and MSVC do have otions for "whole program optimisation" that is intended to overcome this issue.
In other words, you can only "know" by reading the resulting machine code - in some cases, there are also extended "warning" or "notes" messages that you can enable to tell the compiler to give you information about "I did not inline function Func1 because ...insert some reason here...".

When can i not inline a function? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
When to use inline function and when not to use it?
Under what conditions can (not should) a function not be inlined (C++ Only) ?
Two conditions that i know of are :
1 . If the function has a recursive call
2 . If there are static variables in the function
inline is a keyword of C++, but inlining is a generic process performed by a compiler backend, usually after instruction sequences are already generated.
A C compiler will also inline functions, and a C++ compiler will inline functions that aren't inline. A C++ compiler can also fail to inline an inline function for any arbitrary reason. The keyword actually exists to specify that a function may have multiple, identical definitions in different translation units (source files).
Static variables have no special bearing on whether something can be inlined. Perhaps some compilers have difficulty linking the resulting structure of global variable references, but that's more of a bug than a rule of thumb.
Recursive functions can be inlined, too. The recursive call should be translated to a branch. The branch could then be targeted by loop unrolling.
A function that compiles to more than a kilobyte of code will usually not be inlined. But a compiler may provide #pragma directives or platform-specific attributes to force inlining in such a case.
The biggest factor that would stop a function from being inlined is if its source isn't available to the compiler at the time of code generation. Link-time optimization opens the possibility of inlining functions that are extern and not inline but a function supplied by a DLL is certainly off limits. But then, you could still run it through a JIT style execution engine and that could inline (splice together) any random fragments it likes.
The only situation in which a function cannot be inlined is if there is no definition for the function in the compilation unit. Even that will not prevent link-time inlining by a link-time optimizer.
Note that the inline keyword is really just a hint -- a compiler may choose not to inline functions with it and choose to inline functions without it.

C++ Inline methods for performance

I was told long ago to make short functions/methods that are called often inline, by using the keyword inline and writing the body in the header file.
This was to optimize the code so there would be no overhead for the actual function call.
How does it look with that today? Does modern compilers (Visual Studio 2010's in this case) inline such short functions automatically or is it still "necessary" to do so yourself?
inline has always been a hint to the compiler, and these days compilers for the most part make their own decisions in this regard (see register).
In order to expand a function inline, the compiler has to have seen the definition of that function. For functions that are defined and used in only one translation unit, that's no problem: put the definition somewhere before it's used, and the compiler will decide whether to inline the function.
For functions that are used in more than one translation unit, in order for the compiler to see the definition of the function, the definition has to go in a header file. When you do that, you need to mark the function inline to tell the compiler and linker that it's okay that there's more than one definition of that function. (well, I suppose you could make the function static, but then you could end up wasting space with multiple copies)
Enable warning C4710, this will warn you if a function which you define as inline is not inlined by the compiler.
Enable warning C4711, this will warn you if the compiler inlines a function not designated for inlining.
The combination of these two warnings will give you a better understanding of what the compiler is actually doing with your code and possibly whether it is worth designating inline functions manually or not.
Generally speaking, the inline keyword is used more now to allow you to "violate" the one definition rule when you define a function in a header than to give the compiler a hint about inlining. Many compilers are getting really good at deciding when to inline functions or not, as long as the function body is visible at th4e point of call.
Of course if you define the function only in a source file non-inline, the compiler will be able to inline it in that one source file but not in any other translation unit.
Inlining may be done by a compiler in the following situations:
You marked the function as inline and
it's defined in a current translation unit or in file that it's included in it;
compiler decides that it's worth doing so. According to the MSDN
The inline keyword tells the compiler that inline expansion is preferred.
The compiler treats the inline expansion options and keywords as suggestions.
You used the __forceinline keyword (or __ attribute __((always_inline)) in gcc). This will make compiler to skip some checks and do the inlining for you.
The __forceinline keyword overrides the cost/benefit analysis and relies on the judgment of the programmer instead.
Microsoft compiler can also perform cross module inlining if you have turned on link time code generation by passing /GL flag to the compiler or /LTCG to the linker. It's quite clever in making such optimizations: try to examine the assembly code of modules compiled with /LTCG.
Please note, that inlining will never happen if your function is:
a recursive one;
called through a pointer to it.
Yes, modern compilers will (depending on various configuration options) automatically choose to inline functions, even if they're in the source (not header) file. Using the inline directive can give a hint.
Aside from your main point (what amount of placing inline instructions in code is useful as of compilers today), keep in mind that inline functions are just a hint to the compiler, and are not necessarily being compiled as inline.
In short, yes, compilers will decide whether or not your function becomes inline. You can check this question:
Does the compiler decide when to inline my functions (in C++)?

Can getters and setters be inlined when definition and declaration are seperated in .h and .cpp files?

I have searched and have been unable to verify how the GCC compiler will handle inlining getters and setters when declaration is in .h file and definition is in .cpp file.
Most seem to say that GCC can't see across these source file barriers and won't be able to inline these at all, while others disagree. I have looked at the documentation and I can't find the answer there either. Did I miss it?
I do realize that inlining is a choice made by the compiler and is not always guaranteed, but assuming optimal situations, is it at least possible?
(What you really meant to ask is about the situation where the definition is in a different .cpp file to the one you're currently compiling, and then linked in later. The compiler doesn't care about .hpp or .cpp, but about translation units.)
Anyway, on http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html, scroll down to "flno":
This option runs the standard link-time optimizer.
[...]
The first two invocations to GCC will save a bytecode representation of GIMPLE into special ELF sections inside foo.o and bar.o. The final invocation will read the GIMPLE bytecode from foo.o and bar.o, merge the two files into a single internal image, and compile the result as usual. Since both foo.o and bar.o are merged into a single image, this causes all the inter-procedural analyses and optimizations in GCC to work across the two files as if they were a single one. This means, for example, that the inliner will be able to inline functions in bar.o into functions in foo.o and vice-versa.
So, yes, it's possible to optimise inlines across module boundaries.
However, C++ still makes its requirement of:
An inline function shall be defined in every translation unit in which it is used. [3.2/3, C++03]
So in fact you may not write your code to take advantage of this if you used the inline keyword; you are instead reliant on the linker "just deciding" to inline your function if it sees fit. So it's not an option that's going to allow you to move your code around.
Remember, writing inline in your code does not have a one-to-one relationship with a function actually getting physically inlined; it's only a hint to the compiler (or linker, if you have the above mentioned link-time optimisations turned on).
1/ Functions declared inline must be defined in all compilation units where they are used.
2/ Assuming the correct arguments, gcc will always be able to inline functions as long as it sees the definitions, they don't need to be declared inline. (But declaring them inline will help to make the definitions available in all compilation units, and you may need an higher level of optimization to inline functions not declared inline.)
3/ Recent versions of gcc have the possibility to do link time optimisations. IIRC, one of the possible optimisations at link time is inlining.