Опубликован: 23.07.2006 | Уровень: специалист | Доступ: платный
Лекция 11:

Оптимизация

Def-Use Chains


Следующей удобной формой представления программ для оптимизации является представление с использованием def-use chains .

Помимо алфавита операторов введем в рассмотрение алфавиты входов I и выходов O и определим для каждого оператора \omega множество его входов input(\omega) и выходов output(\omega). При этом будем требовать, чтобы множества входов и выходов для разных операторов не пересекались.

Рассмотрим теперь отображение DU , которое каждому выходу сопоставляет некоторое подмножество множества входов. Тогда для каждого оператора определяются множества def(\omega) и use(\omega), которые есть соответственно множества его выходов и множество тех выходов других операторов, образы которых при отображении DU содержат хотя бы один вход оператора \omega

Неформально говоря, данное представление позволяет отследить потоки данных в программе без учета того, как именно эти данные преобразуются. Множества входов и выходов соответствуют интуитивному представлению об аргументах и результатах операторов, а отображение DU просто описывает, как используются выработанные операторами результаты.

Пример


Рассмотрим представление программы, приведенной в разделе "Представление программы", с использованием def-use chains.

Здесь входы операторов обозначены с помощью кружков, расположенных слева он операторов, выходы - с помощью кружков, расположенных справа. Пунктирные стрелки ведут из выходов одних операторов к входам других и обозначают образы при отображении DU.

Построение данного представления опирается на решение одной из задач из области анализа потоков данных, а именно - задачи о достижимых определениях. Подробно данная задача рассмотрена в "Анализ потоков данных" .

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

Удаление пустого оператора

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

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

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

Удаление мертвого кода


Данное преобразование легко реализуется, если программа представлена с помощью def-use chains. Преобразование заключается в удалении такого оператора, у которого не используются его выходы.

Пример применения такого преобразования приведен на иллюстрации.

Данное преобразование повторно по отношению к самому себе, поскольку удаление одного оператора приводит к тому, что операторы, вырабатывающие для него данные, также могут оказаться неиспользуемыми.

Вероника Стрельская
Вероника Стрельская
Россия
Сергей Покаляев
Сергей Покаляев