Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Теория языков программирования и методы трансляции..pdf
Скачиваний:
28
Добавлен:
05.02.2023
Размер:
3.41 Mб
Скачать

52

2.8 ОПТИМИЗАЦИЯ КОДА

Во многих случаях желательно иметь компилятор, который бы созда-

вал эффективно работающие объектные программы.

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

Термином «оптимизация кода» обозначаются способы сделать объектные программы более «эффективными», т.е.

быстрее работающими или более компактными.

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

Для оптимизации кода существует широкий спектр возможностей. На одном конце находятся истинно оптимизирующие алгоритмы. В этом случае компилятор пытается составить представление о функции, определяемой ал-

горитмом, программа которого записана на исходном языке. Если он «дога-

дается», что это за функция, то может попытаться заменить прежний алго-

ритм новым, более эффективным алгоритмом, вычисляющим ту же функ-

цию, и уже для этого алгоритма генерировать машинный код.

К сожалению, оптимизация этого типа чрезвычайно трудна, т.к. нет ал-

горитмического способа нахождения самой короткой или самой быстрой программы, эквивалентной данной. Поэтому в общем случае термин «опти-

мизация» совершенно неправильный – на практике мы должны довольство-

ваться улучшением кода. На разных стадиях процесса компиляции применя-

ются различные приемы улучшения кода.

В общем случае мы должны выполнить над данной программой после-

довательность преобразований в надежде повысить ее эффективность. Эти преобразования должны, разумеется, сохранить эффект, создаваемый во внешнем мире исходной программой. Преобразования можно проводить в различные моменты компиляции, начиная от входной программы, заканчивая фазой генерации кода. Более подробно оптимизацией кода мы займемся да-

53

лее. Сейчас рассмотрим лишь те приемы, которые делают код более корот-

ким:

1)Если «+» – коммутативная операция, то можно заменить последова-

тельность команд LOAD α; ADD β; последовательностью LOAD β; ADD α. Требуется, однако, чтобы в других местах не было перехода к оператору ADD β.

2)Подобным же образом, если «*» – коммутативная операция, то можно заменить LOAD α; MPY β; на LOAD β; MPY α.

3)Последовательность операторов типа STORE α; LOAD α; можно удалить из программы при условии, что или ячейка α не будет ис-

пользоваться далее, или перед использованием ячейка α будет за-

полнена заново.

4)Последовательность LOAD α; STORE β; можно удалить, если за ней следует другой оператор LOAD и нет перехода к оператору STORE

β, а последующие вхождения β будут заменены на α вплоть до того места, где появится другой оператор STORE β.

· · · · · · · · · · · · · · · · · · · · · · · ·

 

Пример · · · · · · · · · · · · · · · · · · · · · · ·

 

 

 

Рассмотрим наш пример и получим оптимизированную программу

(табл. 2.3).

Таблица 2.3 – Оптимизация кода

 

Этап 1

Этап 2

 

Этап 3

 

 

 

Применяем правило 1 к

Применяем правило 3 и

К последовательности

последовательности

удаляем последователь-

LOAD

=0.98

LOAD

PRICE

ность

STORE $2

ADD

$1

STORE $1

применяем правило 4 и

Заменяем ее последова-

LOAD $1

удаляем ее. В команде

тельностью

 

MPY

$2

 

 

 

 

 

54

LOAD

$1

 

 

заменяем $2 на =0.98

ADD

PRICE

 

 

 

 

 

 

 

 

 

 

LOAD

=0.98

LOAD

=0.98

LOAD

TAX

STORE

$2

STORE

$2

ADD

PRICE

LOAD

TAX

LOAD

TAX

MPY

=0.98

STORE

$1

ADD

PRICE

STORE COST

LOAD

$1

MPY

$2

 

 

ADD

PRICE

STORE COST

 

 

MPY

$2

 

 

 

 

STORE

COST

 

 

 

 

 

 

 

 

 

 

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

2.9 ИСПРАВЛЕНИЕ ОШИБОК

Предположим, что входом компилятора служит правильно построенная программа (однако на практике очень часто это не так). Компилятор имеет возможность обнаружить ошибки в программе, по крайней мере, на трех эта-

пах компиляции:

лексического анализа;

синтаксического анализа;

генерации кода.

Если встретилась ошибка, то компилятору трудно по неправильной программе решить, что имел в виду ее автор. Но в некоторых случаях легко сделать предположение о возможном исправлении программы.

· · · · · · · · · · · · · · · · · · · · · · · ·

 

Пример · · · · · · · · · · · · · · · · · · · · · · ·

 

 

 

Например, если A = B*2C, то вполне правдоподобно допустить

A = B*2*C. В общем случае компилятор зафиксирует эту ошибку и остано-

55

вится. Однако некоторые компиляторы стараются провести минимальные изменения во входной цепочке, чтобы продолжить работу.

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

Перечислим несколько возможных изменений:

Замена одного знака. Если лексический анализатор выдает синтак-

сическое слово INTEJER в неподходящем для появления идентифи-

катора месте программы, то компилятор может догадаться, что под-

разумевается слово INTEGER.

Вставка одной лексемы, т.е., например, заменить 2C на 2*C.

Устранение одной лексемы. Например, в операторе DO 10 I=1,20, –

убрать лишнюю запятую.

Простая перестановка лексем. Например, заменить I INTEGER на

INTEGER I.

Далее мы подробно остановимся на реализации таких компиляторов.

2.10 РЕЗЮМЕ

На рис. 2.7 приведена принципиальная модель компилятора, которая является лишь первым приближением к реальному компилятору. В реально-

сти фаз может быть значительно больше, т.к. компиляторы должны занимать как можно меньший объем памяти.

56

Работа с таблицей

Исход-

 

 

 

 

 

 

 

 

 

ная про-

 

 

 

 

 

 

 

 

 

Лексичес-

 

Синтакси-

 

 

 

 

 

 

грамма

 

 

Генерация

 

Оптимиза-

 

Ассембли-

кий анали-

 

ческий

 

 

 

 

 

 

 

 

 

 

 

кода

 

ция кода

 

рование

 

затор

 

анализатор

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Анализ ошибок

Рисунок 2.7 – Модель компилятора

Мы будем интересоваться фундаментальными проблемами, возникаю-

щими при построении компиляторов и других устройств, предназначенных для обработки языков.

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

Контрольные вопросы по главе 2

·· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

1.Задание языков программирования.

2.Синтаксис и семантика.

3.Процесс компиляции.

4.Лексический анализ.

5.Работа с таблицами.

6.Синтаксический анализ.

7.Генерация кода.

8.Алгоритм генерации кода.

9.Оптимизация кода.

10.Исправление ошибок.