Questions tagged [devirtualization]

program compilation or interpretation optimizations in which a base-class pointer or reference points to a known subclass.

In programming languages in which object classes have an inheritance hierarchy or formal interfaces, it is common to work with pointers or references to base class or an interface, where the actual class can be anything inheriting or implementing the base class or interface - and its specific behavior will be executed.

This functionality often involves procedures such as looking up a class method's implementation memory address in a virtual table ("vtable") of the base class, whose memory location is common to all inheriting/implementing subclasses.

Also, at times, a base-class or interface reference or pointer is speculatively converted to the specific subclass or implementation class - a type conversion which may fail if the converter gets the information wrong or makes invalid assumptions.

When a compiler or interpreter works on a piece of code doing one of the above (or some other work) through a base class or an interface, but knows at compilation/interpretation time which class these procedure are applied to, it can skip them and let the execution proceed as if the specific class was being used directly: A type conversion with no checks, or a call to the specific class' known method without going through a virtual table.

which can in fact point to any subclass of the base class. A program uses the base class interface, and the specific implementation or concretization

A optimization in which a base-class pointer points to a known subclass, and the subclass' methods can be used directly rather than through a vtable lookup at run-time.

11 questions
13
votes
2 answers

Does Rust devirtualize trait object function calls?

devirtualize: to change a virtual/polymorphic/indirect function call into a static function call due to some guarantee that the change is correct -- source: myself Given a simple trait object, &dyn ToString, created with a statically known type,…
kmdreko
  • 42,554
  • 6
  • 57
  • 106
8
votes
1 answer

Why don't compilers devirtualize calls for a final class when inlining?

struct base { virtual void vcall() = 0; }; struct foo final : base { void vcall() final; }; void call_base(base& b) { b.vcall(); } void call_foo(foo& f) { call_base(f); } void call_foo_directly(foo& f) { f.vcall(); } clang…
Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
7
votes
3 answers

Why doesn't this simple function get de-virtualized?

Consider the following code: struct A { virtual A& operator+=(const A& other) noexcept = 0; }; void foo_inner(int *p) noexcept { *p += *p; } void foo_virtual_inner(A *p) noexcept { *p += *p; } void foo(int *p) noexcept { return…
einpoklum
  • 118,144
  • 57
  • 340
  • 684
3
votes
0 answers

Trying to skip vtable and inline call in a case where type is known

Update: This seems to be specific to gcc < 4.9, which improved devirtualization. On a polymorphic class hierarchy I have a non-virtual interface function (let's call her algorithm) that calls some (here for simplicity just one) virtual method…
mbschenkel
  • 1,865
  • 1
  • 18
  • 40
3
votes
0 answers

Why compiler is not able to optimize out vtable in this case (static keyword / singleton pattern)

By using godbolt, I can verify that clang++ and gcc++ are able to optimize out vtable when single type pattern is not used with static keyword. #include class ISquare { public: virtual int square(int num) const; int…
ckain
  • 383
  • 5
  • 13
2
votes
0 answers

How to achieve total devirtualization of custom pmr allocators?

Compare the following compiling draft for a project that uses C++ polymorphic memory sources. To see what's going on I overlayed a std::pmr::monotonic_buffer_resource with my LoggingResource: LiveDemo #include #include…
glades
  • 3,778
  • 1
  • 12
  • 34
1
vote
2 answers

GCC de-virtualization of simple class

The following code does not get devirtualized by gcc. Any ideas what I can do to convince gcc to devirtualize? struct B /* final */ { virtual int foo() { return 3; } }; struct C { B& b; __attribute__((noinline)) C( B& b ) : b(b) { …
Kojo
  • 21
  • 2
0
votes
0 answers

why android compiler generate different MethodRef for same code

i happened to encounter some wired compiled bytecode which i believe both sharing the same source code like below class SomeWebView extends WebView { SomeWebView() { this.getSettings(); } } version 1 (above code write in app a)…
Minami
  • 963
  • 6
  • 21
0
votes
1 answer

GCC Devirtualization and Inlining only first Interface

i found a problem in the following code: It looks like GCC can only devirtualize the first Interface I_Udc. The Interface GCC is not able to devirtualize the second interface I_Uac. If I write I_Uac first, the I_Uac call will be inlined. Here is the…
Tobias
  • 3
  • 2
0
votes
0 answers

Why doesn't gcc devirtualize through a pair of related CRTP hierarchies?

I have a pair of types sharing a loose client/server relationship. The types are nontrivial, so to make them unit testable, I've split them along aspects using decorator. Each decorator adds one aspect of functionality, like locking APIs with a…
Frank Secilia
  • 124
  • 1
  • 9
0
votes
2 answers

Is this manual devirtualization legal / viable?

For a project of mine, I finally need to work with my first polymorphic class (except std::cout). I am researching how to be sure I have 100% devirtualized calls at least in some cases. Is this code legal and viable? How slow will be the…
Nick
  • 9,962
  • 4
  • 42
  • 80