Почему оптимизация глазка выполняется для ассемблерного кода, а не для ИК-кода?

Я не понимаю, зачем нужна оптимизация глазка? Потому что компилятор достаточно умен, чтобы оптимизировать код? Не могли бы вы привести несколько примеров, где необходима оптимизация глазка?

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).

Видеть

Другие вопросы по тегам