Генерация кода компилятора - распределение регистров внутри условных блоков

Я пишу компилятор для курса. Я столкнулся с некоторыми проблемами оптимизации, с которыми я не уверен, как с ними справиться. Предположим, что есть цикл while из языка ввода, который использует N локальных переменных, которые должны храниться в регистрах (или должны быть для быстрых вычислений). Предположим, N> K, количество регистров. Существует вероятность изменения условного регистра ближе к концу цикла while.

Например, предположим, что регистр для x (скажем,% eax на i386) был определен до следующего оператора:

while ( x ) { x = x - 1 ; /* more statements */ }

В коде операторов more, x может быть передан обратно в стек. Когда код возвращается к началу цикла while для переоценки x, он пытается использовать% eax, но он может даже не удерживать значение x сейчас. Таким образом, у нас может быть что-то вроде

        movl -8(%ebp), %eax        # eax <- x
        ....                       # do stuff but let x stay in %eax
_LOOP1: cmpl $0, %eax
        ....
        movl -12(%ebp), %eax       #eax now holds something else
        ....
        jmp _LOOP1 

. Одно из решений, которое я использую, - заставить код пролить все измененные регистры перед оператором while (чтобы регистры рассматривались как пустые с точки зрения генератора кода). После метки цикла while код должен загрузить все в регистр по мере необходимости.

Мое решение выглядит примерно так:

        movl -8(%ebp), %eax        # eax <- x
        ....                       # do stuff but let x stay in %eax
        movl %eax, -8(%ebp)        # spilling and clearing all registers
_LOOP1: movl -8(%ebp), %eax        # get a register for x again
        cmpl $0, %eax
        ....
        movl -12(%ebp), %eax       # eax now holds something else
        ....
        movl %eax, -8(%ebp)        # spill to prevent overwrite
        jmp _LOOP1 

Похоже, мое решение немного постороннее или ненужное. Есть ли какой-то трюк с общей оптимизацией, который я здесь забыл?

РЕДАКТИРОВАТЬ: Я также хотел бы отметить, что нечто подобное происходит с условными выражениями, такими как if и if else. Это происходит для них, потому что регистр может быть выделен для переменной внутри блока для условного выражения, но генератор кода предполагает, что он был перемещен туда для всего остального после. У меня почти такой же подход к этому делу.

6
задан Kizaru 22 September 2010 в 03:13
поделиться