- •Генерация кода
- •Алгоритм перевода опз в машинные команды
- •1. Назначение и распределение регистров.
- •2. Переупорядочение четверок
- •3. Использование специфических особенностей платформы
- •Машинно-независимая оптимизация кода
- •1. Удаление общих подвыражений
- •2. Удаление инвариантов цикла
- •3. Замена операций на более эффективные
- •4. Свёртка операндов
- •5. Короткое вычисление выражений
- •6. Сдвиг вместо умножения
2. Переупорядочение четверок
Другая возможность оптимизации кода состоит в переупорядочивании четверок перед преобразованием их в машинный код.
Рассмотрим, например, четверки (17) – (20). Им соответствует код:
MOV AX, SUMSQ ┐
DIV AX, 100 ├17
MOV T1, AX ┘
MOV AX, MEAN ┐
MUL MEAN ├18
MOV T2, AX ┘
MOV AX, T1 ┐19
SUB AX, T2 ┘
MOV VARIANCE, AX ]20
Сначала вычисляется промежуточное значение i6 и записывается в рабочую переменную T1. Далее вычисляется значение i7. В (19) из i6 вычитается i7.
Поскольку значение i7 только что вычислено оно находится в регистре AX. Однако это никак не удается использовать, поскольку для операции вычитания в AX должен находиться первый операнд, а не второй. Поэтому необходимо запомнить значение i7 в рабочей переменной T2 и перед вычитанием загрузить значение i6 из рабочей переменной T1 в регистр AX. Компилятор может распознать такую ситуацию и переставить четверки таким образом, чтобы второй операнд вычислялся перед первым.
Получаем:
18 |
* |
MEAN |
MEAN |
i7 |
17 |
DIV |
SUMSQ |
#100 |
i6 |
19 |
- |
i6 |
i7 |
i8 |
20 |
:= |
i8 |
|
VARIANCE |
MOV AX, MEAN ┐
MUL MEAN ├18
MOV T1, AX ┘
MOV AX, SUMSQ ┐17
DIV AX, 100 ┘
SUB AX, T1 ]19
MOV VARIANCE, AX ]20
В результате машинный код содержит на две инструкции меньше и использована только одна рабочая переменная T1 вместо двух.
Подобные действия могут применяться для перестановки четвёрок, вычисляющих операнды операции деления.
3. Использование специфических особенностей платформы
Ещё одна возможность машинно-зависимой оптимизации состоит в использовании специфических характеристик и инструкций данного компьютера.
Например, на ней могут существовать специальные инструкции для организации циклов или способы адресации, позволяющие сгенерировать более эффективный объектный код.
Для многопроцессорных компьютеров на скорость выполнения программы сильно влияет порядок расположения инструкций. Последовательно расположенные инструкции, предназначенные для различных функциональных устройств могут выполняться в некоторых случаях одновременно. Чтобы воспользоваться этой особенностью компилятор может переставить машинные инструкции объектного кода.
Машинно-независимая оптимизация кода
1. Удаление общих подвыражений
Общие подвыражения – это подвыражения, которые встречаются в нескольких местах программы и вычисляют одно и то же значение.
Пример:
X, Y: ARRAY [1..10, 1..10] OF INTEGER
…
FOR I:=1 TO 10 DO
X[I, 2*J-1] := Y[I, 2*J]
Терм 2*J является общим подвыражением. Оптимизирующий компилятор должен только один раз сгенерировать код, вычисляющий его, и использовать результат в обоих местах.
Общие подвыражения обычно обнаруживаются при анализе промежуточной формы представления программы.
Примеру соответствует следующая последовательность четверок:
(1) := #1 I {инициализация цикла}
(2) JGT I #10 (20)
(3) - I #1 i1 {вычисление индексов для X}
(4) * i1 #10 i2
(5) * #2 J i3
(6) - i3 #1 i4
(7) - i4 #1 i5
(8) + i2 i5 i6
(9) * i6 #2 i7
(10) - I #1 i8 {вычисление индексов для Y}
(11) * i8 #10 i9
(12) * #2 J i10
(13) - i10 #1 i11
(14) + i9 i11 i12
(15) * i12 #2 i13
(16) := Y[i13] X[i7]
(17) + #1 I i14 {конец цикла}
(18) := i14 I
(19) J (2)
(20) {следующее предложение}
Четверки (5) и (12) совпадают, за исключением имени получаемого промежуточного результата. Операнд J не меняет своего значения между четверками (5) и (12). Таким образом, четверки (5) и (12) вычисляют одно и то же значение. Это означает, что мы можем удалить четверку (12) и заменить любые обращения к ее результату (i10) на обращение к переменной i3.
После замены i10 на i3 мы обнаружим, что четверки (6) и (13) также совпадают, за исключением имени результата. Следовательно, мы можем удалить четверку (13) и заменить i11 на i4.
Аналогично четверки (10) и (11) также могут быть удалены, поскольку они эквивалентны четверкам (3) и (4).
