GCC / Clang 'метки как значения' вычисления смещений во время выполнения - PullRequest
1 голос
/ 05 мая 2019

Я использую Метки в качестве значений (нестандартное расширение) для перехода к меткам перехода.

Ниже приведена реализация конечного автомата, упрощенная для краткости, где состояния кодируются как смещения отсоответствующие метки.

// Processes char c and returns next state
// cur_state = 0 for initial state
int sm_process_char( int cur_state, char c, void *data )
{
    goto *(&&Init + cur_state);
    Init:

    State0:
    switch ( c )
    {
        case 'A': return (&&State_A - &&Init);
        default: return (&&State_Error - &&Init);
    }

    State_A:
    switch ( c )
    {
        case 'A': return (&&State_A - &&Init);
        case 'B': return (&&State_B - &&Init);
        default: return (&&State_Error - &&Init);
    }

    State_B:
    switch ( c )
    {
        case 'A': return (&&State_A - &&Init);
        case 'B': return (&&State_B - &&Init);
        default: return (&&State_Error - &&Init);
    }

    State_Error:
    return cur_state;
}

Сборка, сгенерированная этим кодом, далека от оптимальной с -O3:

sm_process_char:
        movsx   rax, edi
        add     rax, OFFSET FLAT:.L2
        jmp     rax
.L5:
.L9:
        cmp     sil, 65
        je      .L8
        cmp     sil, 66
        je      .L10
.L4:
        mov     edi, OFFSET FLAT:.L7
        sub     rdi, OFFSET FLAT:.L2
        mov     eax, edi
        ret
.L7:
        mov     eax, edi
        ret
.L2:
        cmp     sil, 65
        jne     .L4
.L8:
        mov     edi, OFFSET FLAT:.L5
        sub     rdi, OFFSET FLAT:.L2
        mov     eax, edi
        ret
.L10:
        mov     edi, OFFSET FLAT:.L9
        sub     rdi, OFFSET FLAT:.L2
        mov     eax, edi
        ret

Обратите внимание на инструкции mov и sub, вычисляющие разницу всмещения.Я ожидал, что это можно будет сделать во время компиляции и заменить на отдельные mov инструкции.

Можно ли заставить GCC / Clang вычислять их во время компиляции и получить лучшую сборку?

Годболт ссылка здесь: https://godbolt.org/z/zZdFYo

...