ClearTreeInfo; { Заполняем операнды триады типа «CONST» }
Ops[1].OpType:= OP_CONST;
Ops[2].OpType:= OP_CONST;
Ops[2].ConstVal:= 0;
iCnt:= listTriad.Count-1;
for i:=0 to iCnt do { Для всех триад списка }
begin { выполняем алгоритм }
Trd:= listTriad[i];
if Trd.TrdType in TriadLineSet then
begin { Если любой операнд линейной триады ссылается
на триаду «CONST», берем и запоминаем ее значение }
for j:=1 to 2 do
if (Trd[j].OpType = OP_LINK)
and (listTriad[Trd.Links[j]].TrdType = TRD_CONST)
then begin
Trd.OpTypes[j]:= OP_CONST;
Trd.Values[j]:=
listTriad[Trd.Links[j]][1].ConstVal;
end;
end
else
if Trd.TrdType = TRD_IF then
begin { Если первый операнд условной триады ссылается
на триаду «CONST», берем и запоминаем ее значение }
if (Trd[1].OpType = OP_LINK)
and (listTriad[Trd.Links[1]].TrdType = TRD_CONST)
then begin
Trd.OpTypes[1]:= OP_CONST;
Trd.Values[1]:=
listTriad[Trd.Links[1]][1].ConstVal;
end;
end
else
if Trd.TrdType = TRD_ASSIGN then
begin { Если второй операнд триады присвоения ссылается
на триаду «CONST», берем и запоминаем ее значение }
if (Trd[2].OpType = OP_LINK)
and (listTriad[Trd.Links[2]].TrdType = TRD_CONST)
then begin
Trd.OpTypes[2]:= OP_CONST;
Trd.Values[2]:=
listTriad[Trd.Links[2]][1].ConstVal;
end;
end;{ Если триада помечена ссылкой, то линейный участок
кода закончен – очищаем информационные структуры идентификаторов}
if Trd.IsLinked then ClearTreeInfo;
if Trd.TrdType = TRD_ASSIGN then { Если триада имеет }
begin { тип «присвоение» }
{ и если ее второй операнд – константа, }
if TestOperConst(Trd[2],listTriad,iOp2) then
{запоминаем его значение в информационной структуре переменной}
Trd[1].VarLink.Info:= TConstInfo.Create(iOp2);
end
else { Если триада – одна из линейных операций, }
if Trd.TrdType in TriadLineSet then
begin { и если оба ее операнда – константы, }
if TestOperConst(Trd[1],listTriad,iOp1)
and TestOperConst(Trd[2],listTriad,iOp2) then
begin { тогда вычисляем значение операции, }
Ops[1].ConstVal:=
CalcTriad(Trd.TrdType,iOp1,iOp2);
{ запоминаем его в триаде «CONST», которую
записываем в список вместо прежней триады }
listTriad.Items[i]:= TTriad.Create(TRD_CONST,Ops);
{Если на прежнюю триаду была ссылка, сохраняем ее}
listTriad[i].IsLinked:= Trd.IsLinked;
Trd.Free; { Уничтожаем прежнюю триаду }
end;
end;
end;
end;
constructor TDepInfo.Create(iInfo: longint);
{ Создание информационной структуры для чисел зависимости }
begin
inherited Create; {Вызываем конструктор базового класса}
iDep:= iInfo; { Запоминаем число зависимости }
end;
procedure TDepInfo.SetInfo(iIdx: integer; iInfo: longint);
{ Функция записи числа зависимости }
begin iDep:= iInfo; end;
function TDepInfo.GetInfo(iIdx: integer): longint;
{ Функция чтения числа зависимости }
begin Result:= iDep; end;
function CalcDepOp(listTriad: TTriadList;
Op: TOperand): longint;
{Функция вычисления числа зависимости для операнда триады}
begin
Result:= 0;
case Op.OpType of { Выборка по типу операнда }
OP_VAR: { Если это переменная – смотрим ее информационную
структуру, и если она есть, берем число зависимости }
if Op.VarLink.Info <> nil then Result:=
Op.VarLink.Info.Info[0];
OP_LINK: { Если это ссылка на триаду,
то берем число зависимости триады }
Result:= listTriad[Op.TriadNum].Info;
end{case};
end;
function CalcDep(listTriad: TTriadList;
Trd: TTriad): longint;
{ Функция вычисления числа зависимости триады }
var iDepTmp: longint;
begin
Result:= CalcDepOp(listTriad,Trd[1]);
iDepTmp:= CalcDepOp(listTriad,Trd[2]);
{ Число зависимости триады есть число на единицу большее,
чем максимальное из чисел зависимости ее операндов }
if iDepTmp > Result then Result:= iDepTmp+1
else Inc(Result);
Trd.Info:= Result;
end;
procedure OptimizeSame(listTriad: TTriadList);
{ Процедура оптимизации путем исключения лишних операций }
var
i,j,iStart,iCnt,iNum: integer;
Ops: TOpArray;
Trd: TTriad;
begin { Начало линейного участка – начало списка триад }
iStart:= 0;
ClearTreeInfo; { Очищаем информационные структуры
таблицы идентификаторов }
Ops[1].OpType:= OP_LINK; { Заполняем операнды }
Ops[2].OpType:= OP_CONST; { для триады типа «SAME» }
Ops[2].ConstVal:= 0;
iCnt:= listTriad.Count-1;
for i:=0 to iCnt do { Для всех триад списка }
begin { выполняем алгоритм }
Trd:= listTriad[i];
if Trd.IsLinked then {Если триада помечена ссылкой, }
begin { то линейный участок кода закончен – очищаем }
ClearTreeInfo; { информационные структуры идентификаторов и }
iStart:= i; { запоминаем начало линейного участка }
end;
for j:=1 to 2 do { Если любой операнд триады ссылается
if Trd[j].OpType = OP_LINK then { на триаду «SAME», }
begin { то переставляем ссылку на предыдущую, }
iNum:= Trd[j].TriadNum;{ совпадающую с ней триаду }
if listTriad[iNum].TrdType = TRD_SAME then
Trd.Links[j]:= listTriad[iNum].Links[1];
end;
if Trd.TrdType = TRD_ASSIGN then { Если триада типа }
begin { «присвоение» – запоминаем число зависимости
связанной с нею переменной }
Trd[1].VarLink.Info:= TDepInfo.Create(i+1);
end
else { Если триада – одна из линейных операций }
if Trd.TrdType in TriadLineSet then
begin { Вычисляем число зависимости триады }
CalcDep(listTriad,Trd);
for j:=iStart to i-1 do { На всем линейном участке }