Я играю с простым кодом, пытающимся понять, как я могу сделать компилятор, чтобы оптимизировать распределение и виртуальные вызовы. Я использую лязг. У меня есть следующий код:
// external functions
int acquire();
int do_something(int id);
namespace {
struct bar {
virtual int exec() = 0;
};
struct poof: bar {
poof() {
//id = acquire();
}
virtual int exec() {
return do_something(id);
}
int id = 0;
};
struct foo {
bar *b;
int operator()() {
return b->exec();
}
};
}
int main() {
foo e{new poof};
return e();
}
При компиляции с использованием clang-trunk и -O3 я получаю следующую, хорошо оптимизированную сборку:
main: # @main
xor edi, edi
jmp do_something(int) # TAILCALL
Теперь, раскомментируя строку id = acquire();
Я ожидаю, что xor edi,edi
будет заменено чем-то вроде call acquire(); mov edi, rax
. Вместо этого я вижу, что компилятор внезапно больше не может оптимизировать ни динамическое размещение, ни виртуальный вызов.
В чем причина и как я могу сделать компилятор для их оптимизации?