Свертка объектного кода — это выполнение во время компиляции тех операций исходной программы, для которых значения операндов уже известны. Нет необходимости многократно выполнять эти операции в результирующей программе — вполне достаточно один раз выполнить их при компиляции программы.
Алгоритм свертки для линейного участка программы работает со специальной таблицей Т, которая содержит пары (<переменная>,<константа>) для всех переменных, значения которых уже известны.
Рассмотрим выполнение алгоритма свертки объектного кода для триад. Для пометки операций, не требующих порождения объектного кода, будем использовать триады специального вида С (k, 0).
Алгоритм свертки триад последовательно просматривает триады линейного участка и для каждой триады делает следующее:
1 Если операнд есть переменная, которая содержится в таблице Т, то операнд
заменяется на соответствующее значение константы.
2 Если операнд есть ссылка на особую триаду типа С(k, 0), то операнд заменяется на значение константы k.
|
|
3 Если все операнды триады являются константами, то триада может быть
свернута. Тогда данная триада выполняется и вместо нее помещается особая
триада вида С(k,0), где k — константа, являющаяся результатом выполнения
свернутой триады. (При генерации кода для особой триады объектный код не
порождается, а потому она в дальнейшем может быть просто исключена.)
Если триада является присваиванием типа А:=В, тогда:
- если В — константа, то А со значением константы заносится в таблицу Т
(если там уже было старое значение для А, то это старое значение исключается);
- если В — не константа, то А вообще исключается из таблицы Т, если оно
там есть.
Рассмотрим пример выполнения алгоритма.
Пусть фрагмент исходной программы (записанной на языке типа Pascal) имеет вид:
I:=1+1;
I:=3;
J:=6*I+I
Ее внутреннее представление в форме триад будет иметь вид:
1 +(1,1);
2:=(I,^1);
3:= (I,3);
4 *(6,I);
5 +(^4, I);
6:=(J,^5).
Процесс выполнения алгоритма свертки показан в табл. 4.7.
Таблица 4.7 Пример работы алгоритма свертки
Триада | Шаг 1 | Шаг 2 | ШагЗ | Шаг 4 | Шаг 5 | Шаг 6 |
С (2, 0) | С (2, 0) | С (2, 0) | С (2, 0) | С (2, 0) | С (2, 0) | |
:= (I, ^1) | :=(I,2) | :=(I,2) | :=(I,2) | :=(I,2) | :=(I,2) | |
:=(I,3) | :=(I,3) | :=(I,3) | :=(I,3) | :=(I,3) | :=(I,3) | |
*(6,I) | * (6,I) | *(6,I) | С (18, 0) | С (18, 0) | С (18, 0) | |
+ (^4, I) | + (^4, I) | + (^4, I) | + (^4, I) | С (21,0) | С (21, 0) | |
:=(J,^5) | :=(J,^5) | :=(J,^5) | :=(J,^5) | :=(J,^5) | :=(J,21) | |
Т | (,) | (I, 2) | (I,3) | (I, 3) | (I, 3) | (I, 3) (J,21) |
Если исключить особые триады типа С(k,0) (которые не порождают объектного кода), то в результате выполнения свертки получим следующую последовательность триад:
1:= (I, 2)
2:= (I, 3)
3:= (J, 21)