Recently, i was searching for a way to find out if the function was really inlined by the compiler. I thought that this approach could work:
1 2 3 4 5 6 7 8 9 10 11
staticinline result_t InlineFunction(param_t arg1, param_t arg2)
{
void *address = getCS_IP();
if (approximatelyEqual(currentAddress, (void *) &InlineFunction)) {
// Function was inlined
} else {
// Function was not inlined
}
// Function code
}
But i don't know how to get the address of the last executed instruction. I don't know if this is possible to get using c (but i think that it can be done via assembly). I am looking for a solution, which will work with gcc compiler and gas assembly.
Not as far as I know. At least, not with x86 Assembly. You could do
1 2 3
call label
label:
pop eax
but that would just get you the value of ip at 'label'.
At the very least, I figure you'd need a custom calling convention that implicitly passes some kind of information about the stack or the program counter just before the call, so you have something to work with.
I figure you'd need a custom calling convention that implicitly passes some
kind of information about the stack or the program counter just before the call
You could also pass that information explicitly. Example on windows:
[forcedInlineFunction] was inlined
[notInlineFunction] was not inlined
[inlineFunction] was not inlined
[impossibleInlineFunction] was not inlined
[forcedInlineFunction] was inlined
[notInlineFunction] was not inlined
[inlineFunction] was not inlined
[impossibleInlineFunction] was not inlined
And this messages matched the real situation about inlines. However i don't see any reasons why the compiler didn't inlined the [inlineFunction]. As for me this is very strange.
It would be very interesting to hear your opinion about how i check whether the function was inlined and that you check this implementation on your platform
You're not compiling with optimizations enabled, so inlining will normally not happen. Compile with -O2 or -O3.
Even so, the compiler will only inline if the gains appear to outweigh the costs. The fact that all functions are called twice each combined with the fact that inlining provides no advantage here other than saving the call itself are probably the reasons why the compiler decides against inlining in this case.
You're not compiling with optimizations enabled, so inlining will normally not happen.
It seems that it is the reason why the function was not inlined.
With optimization levels 1 and 2 i've got next results:
1 2 3 4 5 6 7 8
[forcedInlineFunction] was inlined
[notInlineFunction] was not inlined
[inlineFunction] was inlined
[impossibleInlineFunction] was inlined
[forcedInlineFunction] was inlined
[notInlineFunction] was not inlined
[inlineFunction] was inlined
[impossibleInlineFunction] was inlined
And with the third level, even the function which i didn't declared inlined was inlined by the compiler (I've also checked assembly code and really was inlined))):
1 2 3 4 5 6 7 8
[forcedInlineFunction] was inlined
[notInlineFunction] was inlined
[inlineFunction] was inlined
[impossibleInlineFunction] was inlined
[forcedInlineFunction] was inlined
[notInlineFunction] was inlined
[inlineFunction] was inlined
[impossibleInlineFunction] was inlined
So it seems that compiler directives affect on the result code very much. I'm wondering, are there any standart of c++ on optimization levels or compiler directives (and their affects), or they are compiler dependent and there is no any standart on this.