Почему оптимизация глазка выполняется для ассемблерного кода, а не для ИК-кода?
Я не понимаю, зачем нужна оптимизация глазка? Потому что компилятор достаточно умен, чтобы оптимизировать код? Не могли бы вы привести несколько примеров, где необходима оптимизация глазка?
1 ответ
Глазки часто ориентированы на конкретную цель .
Они могут иметь смысл только с точки зрения целевых регистров (RTL), а не IR.
Например например x86
xor eax, eax
вместо
mov eax,0
. (Каков наилучший способ обнулить регистр в сборке x86: xor, mov или and? ). Не было бы причин делать это в IR, и выполнение этого раньше, чем в последний момент (окончательная генерация кода), скрыло бы тот факт, что значение равно нулю для других оптимизаций. Выполнение этого для любой машины, кроме x86, было бы антиоптимизацией (созданием ложной зависимости). OTOH, вы не хотите оставлять это слишком поздно, иначе вы не сможете изменить порядок перед чем-то, что устанавливает ФЛАГИ, например
xor eax,eax
cmp ecx, edx
sete al ; boolean 0 or 1 zero-extended to 64-bit RAX
Вместо
cmp ecx, edx
sete al ; false dependency on old RAX
movzx eax, al ; no mov-elimination, extra critical path latency
или же
cmp ecx, edx
mov eax, 0 ; less efficient instruction to leave FLAGS untouched
sete al ; later reads of RAX will have partial-register stalls on P6-family
Или, в качестве другого примера, x86 может умножать на 3, 5 или 9, используя LEA, чтобы воспользоваться преимуществами 2-битного сдвига и добавить режимы адресации с 2 регистрами. Оптимизатору может быть полезно знать, что это эффективный строительный блок, и стремиться преобразовать вещи в умножение на 9, но на самом деле преобразование умножения на 10 в
(x * 5) * 2
не так, как вы хотели бы сделать это для целей, где
(x<<3) + (x<<1)
эффективнее(
x*10 = x*8 + x*2
).
Видеть
- Использование LEA для значений, которые не являются адресами/указателями?
- Как умножить регистр на 37, используя только 2 последовательные инструкции в x86?- показывает, как некоторые компиляторы иногда пропускают оптимизацию глазка, и обсуждает компромисс между 2x
lea
и как современные процессоры с быстрымиimul
сделать так, чтобы стоило потратить не более 2 инструкций, заменяющих умножение, или только 1, если узким местом является пропускная способность, а не задержка. Если только вы не можете сложить в него дополнение, как это может сделать LEA...