This just came to mind, and not really sure how to search for this.
Let's say you have the following classes
class A
{
public:
virtual void Foo() = 0;
virtual void ManyFoo(int N)
{
for (int i = 0; i < N; ++i) Foo();
}
};
class B : public A
{
public:
virtual void Foo()
{
// Do something
}
};
Do any compilers create a version of ManyFoo()
for B
that inlines the call to B::Foo()
?
If not, does making B
a final class enable this optimization?
Edit:
I was specifically wondering whether this was done anywhere for virtual calls (so, aside from when the whole call to ManyFoo()
is inlined itself).
Best Answer
I believe the term you're looking for is "devirtualization".
Anyway, did you try it? If we put that example in Compiler Explorer:
...GCC is able to produce the following with
-Os
:It will inline through the virtual call when it's 100% sure of the concrete type of the object
b
(n.b. if we change-Os
to-O2
it will also fully inlineb_indirect_foo
). But it can't be sure of the concrete type of an object it can only see by a reference that it can't trace back to an instance, and it doesn't seem to trustfinal
annotations to overrule this (probably because this would be very ABI-fragile; I personally wouldn't want it to). It will trustfinal
annotations on member functions though, but your example precludes that by its structure.GCC has had this optimization for several versions. Clang and MSVC don't seem to do it in this case (but do advertise the feature), so the power clearly varies a lot between examples and compilers.