
- •Содержание
- •Введение
- •1.3. Множества цепочек
- •1.4. Языки
- •1.5. Алгоритмы
- •1.6. Некоторые понятия теории графов
- •Контрольные вопросы
- •2. Введение в компиляцию
- •2.1. Задание языков программирования
- •2.2. Синтаксис и семантика
- •2.3. Процесс компиляции
- •2.4. Лексический анализ
- •2.5. Работа с таблицами
- •Переменная с плавающей точкой
- •2.6. Синтаксический анализ
- •2.7. Генератор кода
- •2.8. Оптимизация кода
- •2.8. Оптимизация кода
- •2.9. Исправление ошибок
- •2.10. Резюме
- •Контрольные вопросы
- •3. Теория языков
- •3.1. Способы определения языков
- •3.2. Грамматики
- •3.4. Распознаватели
- •3.5. Регулярные множества, их распознавание и порождение
- •5.2. LR(1) - таблица разбора
- •5.3. Построение LR – таблицы разбора
- •5.4. Сравнение LL – и LR – методов разбора
- •Контрольные вопросы
- •6. Оптимизация кода
- •6.1. Оптимизация линейного участка
- •6.1.1. Модель линейного участка
- •6.1.2. Преобразование блока
- •6.1.3. Графическое представление блоков
- •6.1.4. Критерий эквивалентности блоков
- •6.1.5. Оптимизация блоков
- •6.1.6. Алгебраические преобразования
- •6.2. Арифметические выражения
- •6.2.1. Модель машины
- •6.2.2. Разметка дерева
- •6.2.3. Программы с командами STORE
- •6.2.4. Влияние некоторых алгебраических законов
- •6.3. Программы с циклами
- •6.3.1. Модель программы
- •6.3.2. Анализ потока управления
- •Алгоритм вычисления прямого доминирования
- •6.3.3. Примеры преобразования программ
- •Удаления бесполезных операторов
- •Замена сложных операций
- •6.3.4. Оптимизация циклов
- •Перемещение кода
- •Индуктивное перемещение
- •Замена сложных операций
- •6.4. Анализ потоков данных
- •6.4.1. Интервалы
- •6.4.2. Анализ потоков данных с помощью интервалов
- •6.4.3. Несводимые графы управления
- •7. Включение действий в синтаксис
- •7.1. Получение четверок
- •7.2. Работа с таблицей символов
- •Контрольные вопросы
- •8. Проектирование компиляторов
- •8.1. Число проходов
- •8.2. Таблицы символов
- •8.3. Таблица видов
- •Контрольные вопросы
- •9. Распределение памяти
- •9.1. Стек времени прогона
- •9.2. Методы вызова параметров
- •9.3. Обстановка выполнения процедур
- •9.4. «Куча»
- •9.5. Счетчик ссылок
- •9.6. Сборка мусора
- •Контрольные вопросы
- •10. Генерация кода
- •10.1. Генерация промежуточного кода.
- •10.2. Структура данных для генерации кода
- •10.3. Генерация кода для типичных конструкций
- •10.3.1. Присвоение
- •10.3.2. Условные зависимости
- •10.3.3. Описание идентификаторов
- •10.3.4. Циклы
- •10.3.5. Вход и выход из блока
- •10.3.6. Прикладные реализации
- •10.4. Проблемы, связанные с типами
- •10.5. Время компиляции и время прогона
- •Контрольные вопросы
- •11. Исправление и диагностика ошибок
- •11.1. Типы ошибок
- •11.2. Лексические ошибки
- •11.3. Ошибки в употреблении скобок
- •11.4. Синтаксические ошибки
- •11.5. Методы исправления синтаксических ошибок
- •11.6. Предупреждения
- •11.7. Сообщения о синтаксических ошибках
- •11.8. Контекстно-зависимые ошибки
- •11.9. Ошибки, связанные с употреблением типов
- •11.10. Ошибки, допускаемые во время прогона
- •Контрольные вопросы
- •Список литературы
146
Отметим, что если F строится из программы, то число дуг не более чем вдвое превосходит число участков. Потому шаг 1) алгоритма выполняется за время пропорциональное квадрату числа участков. Требуется емкость памяти пропорциональная числу участков.
Если 1, 2,.., n участок программы, то их доминаторы можно записать как последовательность e1, e2,.., en, где ei прямой доминатор
для i.
6.3.3.Примеры преобразования программ
Полного каталога оптимизирующих преобразований программ с циклами не существует, однако для широкого класса программ можно использовать следующие преобразования.
Удаления бесполезных операторов
Это - обобщение топологического преобразование Т1. Без оператора, не влияющего на значение программы можно обойтись. Линейные участки, недостижимые из начальной вершины, очевидно, бесполезны, и их можно удалить. Операторы, вычисляющие значения, не используемые в конечном итоге при вычислении выходной переменной, такие попадают в эту категорию.
Исключение избыточных вычислений
Это преобразование обобщает топологическое преобразованиеТ2.
Предположим, что у нас есть программа, в которой участок домини-
рует над ¢, и что и содержит операторы A¬B+C и A¢¬B+C. Если В и С не переопределены (выяснить это не трудно), то значения вычислен-
ные этими двумя выражениями совпадают. Тогда в после вычисления А¬В+С можно вставить операторX¬A, где X- новая переменная. Затем A¢¬B+C, можно заменить на А¢¬X. Кроме того, если А, нигде на
пути из в ¢ не переопределяется, то оператор X¬ A не нужен, а А¢¬B+C можно заменить А¢¬A.
Пример. Рассмотрим граф управления, изображенный на рис. 11.15.

147
B¬D+D
C¬D*D
A¬B+C
A¬B*C B 2
F¬A+G
G¬B+C
D¬D+1
B1
A¬B+C B3
E¬A*A
B 4
B 5
Рис. 11.15. Граф управления.
В этом графе 1 доминирует над 2, 3 и 4. Тогда В+С принимает одно и то же значение при вычислении в 1, 3 и 4. Поэтому в 3 и
4 не обязательно перевычислять выражения В+С.
В 1 после оператораА¬В+С, можно поместить оператор при-
своения X¬А. Тогда в 3 и 4 операторы А¬В+С и G¬B+C можно заменить A¬X и G¬X соответственно. Отметим, что А вычисляется в
2, вместо X нельзя использовать А.
Теперь в 3 присвоение A¬X становится избыточным, его можно исключить.
Для исключения из программ избыточных вычислений (общих подвыражений) надо выявить вычисления, общие для двух или более участков программы. Избыточные вычисления, общие для участка и какого-нибудь из доминантов мы рассмотрим. Однако, выражения А+В могут вычисляться в нескольких участках, ни один из которых ни до-
минирует над данным участком . Вообще выражение А+В считается
избыточным в участке если