Оптимизатор СПФ.

  Инлайн подстановщик.
 Оптимизатор вызывается инлайн подстановщиком INLINE, . Вернее,  _INLINE,.
Инлайн подстановщик представляет собой M_WL цикл:
: M_WL  CS-DUP POSTPONE WHILE ; IMMEDIATE
метод шага _INLINE, определяется подбором кода. Некоторая оптимизация инлайн подстановщиком,
он обеспечивает отложением модификации регистра указателя на верщину стека данных. Вернее,
на оставшуюся часть стека, так как EAX истользуется в качестве ТОСа. С помощью -EVEN-EBP
удаляет инструкцию LEA  ebp,  OFF-EBP [EBP], а индекс при [EBP] заносится в переменную +>OFF-EBP. В конце
инлайн подстановщики, процедура EVEN-EBP восстанавливает эту инструкцию. В процессе инлайн подстановки,
индекс при [EBP] модифицируется в соответствии с переменной +>OFF-EBP. Инструкция LEA  ebp, OFF-EBP [EBP]
воспринимается инлайном как модификация переменой +>OFF-EBP. Функция INLINE? оценивает CFA на возможность
инлайн подстановки аналогичным методом подбора кода. Если все инструкции от CFA до машинного кода RET
прописаны в цепочки сравнений и размер фрагмента от CFA до RET менще значения переменной MM_SIZE
то функция INLINE? возвращает разрешение для инлайн-подстановки. 
 Определение COMPILE, имеет вид:

: COMPILE,  \ 94 CORE EXT
\ Интерпретация: семантика не определена.
\ Выполнение: ( xt -- )
\ Добавить семантику выполнения определения, представленого xt, к
\ семантике выполнения текущего определения.
    CON>LIT
    IF  INLINE?
      IF     INLINE,
      ELSE   _COMPILE,
      THEN
    THEN
;

  CON>LIT пытается некоторые CFA (типа константы) представить в виде литерала.
  Оптимизация OPT_ вызывается на каждом шаге инлайн подстановки. 
В свою очередь OPT_ вызывает в цикле OPT-RULES. 
OPT-RULES представляет собой последовательность правил. Правила состоят из анализатора и модификатора.
Модификатор модифицирует последний фрагмент компилируемого кода. Аанализатор проверяет возможность
применения правила. OPT-RULES возыращвет FALSE если проебразование было
и есть смысл попробывать еще раз выполнить OPT-RULES. Т.о. крупное
преобразование может быть выражено множеством иелких.


 Наблюдение работы оптимизатора.
 
 Для этой задачи, потребуется экземпляр СПФ системы использующий векторное слово DTST.
Для этого надо файле src\tc_spf.F определить M\ как пустое слово
: M\ ( POSTPONE \) ; IMMEDIATE
и пересобрать систему. 
 В качестве параметра на вход DTST подается номер правила. По умолчанию,
к качестве заглушки, DTST инициализирован командой DROP .
Включение наблюдения производится путем инициализации слова DTST словом DoDTST:

REQUIRE DoDTST ~mak\OptTr.f 
: ZZZ [ ' DoDTST TO DTST ]
5 < 0= IF THEN
;

 Клавиша 'Q' - ABORT
 'D' - вызов файла по имени DDD.F
 остальнве -  шаг трассировки.

  Добавление жёстких правил.

  Жёсткие правила представляет собой обднозначную занену одного кода на эквивалентный.

На пример:

DUP C@ C3 XOR
OP1 @ W@ CA8B XOR OR \ 582148 8BCA              MOV     ECX , EDX
OP0 @ W@ C12B XOR OR \ 58214A 2BC1              SUB     EAX , ECX
0= IF  M\ 180 DTST
       C22B  OP1 @ W! \    SUB     EAX , EDX
       OP0 OPexcise
       FALSE  M\ 181 DTST
       EXIT
   THEN

Выработка условия перед IF является анализатором данного правила.
На входе анализатора на стеке лежит текущий указатель на
источник кода инлайн подстановки. Указание на код 0xC3 (RET)
означает что мы в конце инлайн подстановки и значение в ECX не
подлежит дальнейшему использованию.
OP0 и OP1 указатели на 0й и 1й элементы массива ссылок на инструкции .
0й элемент указывает на последнюю инструкцию, 1й на предпоследнюю и т.д.
Массива ссылок на инструкции введен ради отличия кода команды от операндов
при рассмотрении машинного кода задом на перед.
Указатель с максимальным номером в анализаторе определяет размер
фрагмента в количестве инструкций. При этом, мы абстрагируемся
от реального размера (в байтах). Правила в программе OPT-RULES
распределены по размеру фрагментов кода с которыми они работаю.
Сначала идут правила для коротких фрагментов потом для длинных.
Строки вида:
OP1 @ :-SET U< IF TRUE EXIT THEN
OP2 @ :-SET U< IF TRUE EXIT THEN
OP3 @ :-SET U< IF TRUE EXIT THEN
OP4 @ :-SET U< IF TRUE EXIT THEN
(без разделителей в начале строки)
являются границами между группами правил объединенных по размеру фрагментов,
которые они обрабатывают. Новое правило следует занести в конец своей группы.
Где :-SET переменная содержащая указатель ограничивающий область оптимизации.
Тут надо учесть, что для фрагментов оканчивающихся записью в EAX
существует своя программа содержащая правила - ?EAX=RULES .
Для каждого из фрагментов соответствующих одному из следующих условий:
 OP0 @ W@  ADD|XOR|OR|AND=   \ $  4444  OR
 OP0 @ W@ 558B =    \ MOV     EDX , X [EBP]
    OP1 @ W@   453B   =      \ CMP   EAX , X [EBP]
отведена своя область в теле условного оператора.
 Для генерации анализатора жёстких правил можно
использовать средство наблюдения работы оптимизатора,
по средствам вызова файла DDD.F ( Клавиша 'D' ).
При этом DDD.F должен содержать программу генерации анализатора.
Типа:
CR .( DUP C@ C3 XOR)
.WOP1
.WOP0

 Где .WOP0 .WOP1 генерируют части анализатора для последней и
предпоследней инструкций интересуемого фрагмента кода.
.WOP0 .WOP1 определены в devel\~mak\DOP.F 
префикс W означает 2-байтный шаблон. Для создания преобразователя
мозно использовать уже существующие преобразователи в качестве прототипа.

 Абстрагирование.
 
 Чаще всего используется абстрагированме от глубины стека:

OP1 @ 2 + C@
OP0 @ 2 + C@    XOR  \  ?xx=yy
OP1 @ W@ 4503 XOR OR \  034500            ADD     EAX , yy [EBP]
OP0 @ W@ 558B XOR OR \  8B5500            MOV     EDX , xx [EBP]
0= IF  M\ 288 DTST
	558B OP1 @  W!    \      MOV     EDX , xx [EBP]
        C203 OP0 @  W!    \      ADD     EAX , EDX
        -1 ALLOT
       FALSE  M\ 289 DTST
       EXIT
   THEN

 xx и yy - глубины стека. Для данного правила, должны быть равными.

 можно также абстрагироваться от кода команды:
OP1 @ 2+ C@
OP0 @ 2+ C@   XOR
OP1 @ W@ 5589 XOR OR \  8955F8            MOV     F8 [EBP] , EDX
OP0 @ W@ FFC7 AND 4503 XOR OR \  0B45F8  ADD|OR|ADC|SBB|AND|SUB|XOR|CMP      EAX , F8 [EBP]
0=  IF
        M\ B2 DTST
        C2 OP0 @ 1+ C!      \    OR      EAX , EDX
        -1 ALLOT
        FALSE M\ B3 DTST
        EXIT
    THEN

 в данном случае от 3-х битов кода-команды определяемых маской 0xFFC7
Соответственно, 8 вариантов кода-команд.

 Модификация фрагментов кода неопределенного размера.

 Относительно простым примером является лишнее восстановление регистра EAX
со стеке. При том, что после сохранения EAX на стеке его никто не модифицировал.
Т.е. фрагмент представляет собой пару
  MOV    X [EBP], EAX     MOV     EAX, X [EBP]
проложенных машинным кодом не содержащем модификацию содержимого регистра EAX
Анализатор данного правила представляет собой цикл, который пробегает по массиву
ссылок на инструкции и вызывая XX_STEP . XX_STEP продвигает указатель и проверяет
инструкции на которые этот указатель косвенно указывает. Если очередная инструкция
найдена среди среди допустимых образцов - поиск продолжается иначе завершается
с отказом. Если встречается MOV    X [EBP], EAX - поиск завершается с разрешением
удалить последнюю инструкцию.
 Если между MOV    X [EBP], EAX     MOV     EAX, X [EBP]  встречается
запись в регистр EAX , то в данном промежутке, EAX можно заменить другим регистром.
Программа DO_EAX>ECX производит замену EAX на ECX . С помощью ?EAX>ECX
проверяется возможность произвести данное преобразование. В переменную ?~EAX
заносится флаг необходимости добавления инструкции MOV     EAX , ECX .
Преобразование осуществляется от найденной  MOV    X [EBP], EAX в
направлении исполнения. С помощью EAX>ECX0 пропускаются инструкции не меняющие EAX.
Далее с помощью EAX>ECX производится подмена EAX на ECX во всех последующих инструкциях.
 Перед компиляцией условного перехода используется специальный набор
правил содержащейся в процедуре ?BR-OPT-RULES . При этом, учитывается данная
специфика связанная с созданием флагов условного перехода.
 Есть некоторый забег на оптимизацию нелинейного участка кода RESOLVE_OPT .
Пока замена длинного перехода вперед на короткий (там где это допустимо).
Но по моему, на данном этапе не до этого. 

Hosted by uCoz
FC DTST