ленточная девиртуализация и оптимизация распределения - PullRequest
1 голос
/ 02 июля 2019

Я играю с простым кодом, пытающимся понять, как я могу сделать компилятор, чтобы оптимизировать распределение и виртуальные вызовы. Я использую лязг. У меня есть следующий код:

    // 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. Вместо этого я вижу, что компилятор внезапно больше не может оптимизировать ни динамическое размещение, ни виртуальный вызов.

В чем причина и как я могу сделать компилятор для их оптимизации?

...