Практикум «Оптимизирующие компиляторы» (на примере GCC) (1157417), страница 4
Текст из файла (страница 4)
Функция должна удовлетворять некоторым условиям иограничениям, таким как максимальный размер, число и типы параметров.Функция при этом может содержать циклы и рекурсивные вызовы самойсебя. Код для сохранения RTL-кода функции и последующего его встраиваниясодержится в файле integrate.c.3 Ключ для получения отладочной информации прохода: -dr, файл сотладочной информацией: .rtl.Оптимизация вызововПроисходит удаление рекурсивных вызовов в конце функции иоптимизация хвостовых (sibling) вызовов функций (замена командывызова на команду перехода).
Цель оптимизации – уменьшить накладныерасходы при вызове функций (там, где это возможно). Для этогоудаляются лишние команды организации кадра стека.Уменьшение накладных расходов при вызове функций. Реализация располагается в файле sibcall.c.3 Ключ для получения отладочной информации: -di, файл с отладочнойинформацией: .sibling.Оптимизация переходовУпрощает переходы к следующим инструкциям, цепочки переходов и т. д.Происходит удаление меток, на которые никто не ссылается и удалениенедостижимого кода, за исключением случая, когда недостижимый кодсодержит циклические конструкции.
Также происходит преобразованиекода, реализованного с переходами, в последовательность инструкций,устанавливающих значения по результатам сравнения, если такиеинструкции поддерживаются, например, инструкции setcc для Intel®Pentium® II и выше.Практикум «оптимизирующие компиляторы»Оптимизация переходов производится два или три раза. Первый разнепосредственно после генерации RTL, второй раз после поиска общихподвыражений (если это потребуется), третий раз непосредственно передгенерацией ассемблерного кода.Возможные улучшения: удаление неиспользуемого кода, упрощениепредсказания переходов. Файл с реализацией: jump.c.3 Ключ для получения отладочной информации: -dj, файл с отладочнойинформацией: .jump.Сканирование регистров (определение времени жизнипеременных)В результате прохода появляется информация о первом и последнемиспользованииинформация(временииспользуетсяжизни)вкаждогодальнейшем(псевдо)прирегистра.удаленииЭтаобщихподвыражений.
Файл с реализацией: regclass.c.Зацепление переходовПри этом проходе происходит поиск условных переходов, где послепроверки условия переход происходит к такому же условию либо к егоинверсии. Такие переходы могут быть «сцеплены» по второму условию(так как первую проверку можно опустить). Проход выполняется, еслиопция -fthread-jumps включена.Возможные улучшения: упрощение предсказания переходов. Файл с реализацией: jump.cПрактикум «оптимизирующие компиляторы»SSAПроходы, основанные на использовании представления SSA (static singleassignment form) включаются опцией –fssa.
В представлении SSA каждаяпеременная (псевдорегистр) присваивается только один раз. В настоящиймомент преобразование в форму SSA присутствует не во всех версиях.Окончательно оно реализовано в версии 4. Файл с реализацией ssa.c3 Ключ для получения отладочной информации: -de, файл с отладочнойинформацией: .ssa.Продвижение констант в условных операторахИспользуется для подстановки констант в условныхоператорах.Включается опцией -fssa-ccp. Время исполнения линейно зависит отразмера кода.3 Ключ для получения отладочной информации: -dW, файл с отладочнойинформацией: .ssaccp.Удаление «мертвого» кодаОсуществляет удаление неиспользуемого кода, который не оказываетвидимого эффекта на программу.
Включается опцией -fssa-dce. Времяисполнения линейно зависит от размера кода.3 Ключ для получения отладочной информации: -dX, файл с отладочнойинформацией: .ssadce.Удаление общих подвыражений (CSE)Проход производит распространение констант и удаление повторновычисляемыхвыражений.Еслираспространениеконстантстанетпричиной преобразования условного перехода в безусловный или еголиквидацию, то после CSE запускается оптимизация переходов.Основная идея CSE – проходя через код функции сохранять представлениявыражений, производящих одинаковые вычисления и заменять этивыражения самым «дешевым» эквивалентным выражением. Очень сложноПрактикум «оптимизирующие компиляторы»отслеживать разные возможности, когда происходит слияние несколькихветвей исполнения кода.
Поэтому в каждой такой точке слияния обычновсе, что было известно о выражениях до этой точки, забывается. Каждыйбазовый блок обрабатывается отдельно. Файлы с реализацией: cse.c, cselib.c.3 Ключ для получения отладочной информации: -ds, файл с отладочнойинформацией: .cseГлобальное удаление общих подвыражений GCSEВ зависимости от того оптимизируется ли программа по размеру или поскорости, этот проход выполняет одну из двух оптимизаций. Еслиоптимизация происходит по скорости выполнения, производится LCM(lazy code motion – ленивое перемещение кода). LCM основывается наработе Knoop, Ruthing и Steffen.
LCM также обеспечивает выносинвариантов за пределы цикла. Если происходит оптимизация по размеру,то используется удаление частичной избыточности методом MorelRenvoise. Этот метод не производит перемещение инвариантов за пределыцикла. Файлы с реализацией: gcse.c, lcm.c.3 Ключ для получения отладочной информации: -dG, файл с отладочнойинформацией: .gcse.Оптимизация цикловПри этом проходе неизменяемые в циклах выражения перемещаются запределы циклов. Так же возможно снижение мощности выражений ираскрутка циклов.При втором проходе основное внимание уделяется оптимизации на уровнебазовых блоков, кроме того, производится раскрутка, вынесение первых ипоследних итераций за пределы цикла (peeling) и вынесение условныхвыражений за пределы цикла.Практикум «оптимизирующие компиляторы»Возможные улучшения: упрощение циклов, возможно улучшение работысистемы предсказания переходов.
Файлы с реализацией: loop.c (есть документация), loop.h, unroll.c (естьдокументация), integrate.c, integrate.h, dependence.h, cfgloopanal.c,cfgloopmanip.c, loop-init.c, loop-unswitch.c, loop-unroll.c.3 Ключ для получения отладочной информации: -dL, файл с отладочнойинформацией: .loop, .loop2.Оптимизация цепочек переходовЭтот проход – более агрессивная форма глобального CSE. Происходитпреобразованиеуправляющегографафункцииспомощьюраспространения констант в условия условных операторов. Файл с реализацией: gcse.c.3 Ключ для получения отладочной информации: -dG, файл с отладочнойинформацией: .bypass.Вторичное удаление общих подвыраженийВключается опцией -frerun-cse-after-loop.
Повторный запуск CSE.3 Ключ для получения отладочной информации: -dt, файл с отладочнойинформацией: .cse2.Анализ потока данныхЭтот проход делит программу на базовые блоки. В процессе деленияудаляются недостижимые циклы. Затем вычисляется время жизни каждогопсевдорегистра. Также происходит обнаружение выражений, значениякоторых далее нигде не используются.
Объединяются ссылки на ячейкипамяти с инструкциями сложения или вычитания для дальнейшего ихпреобразования в автоинкрементную или автодекрементную адресацию.Возможные улучшения: сокращение размера базовых блоков. Файл с реализацией: flow.c.3 Ключ для получения отладочной информации: -df, файл с отладочнойинформацией: .flow.Практикум «оптимизирующие компиляторы»Комбинирование инструкцийДелается попытка объединить 2 – 3 инструкции, последовательнопреобразующие данные, в одну комбинированную инструкцию, еслитаковая имеется. Для этого объединяются подстановкой RTL выражениядляэтихвыражения.инструкций,Затемкомбинированияипроизводитсяделаетсяинструкцийалгебраическое упрощениепопыткасописаниемсопоставитькомандырезультатвописаниипроцессора.Возможные улучшения: использование более сложных инструкций,которые работают быстрее, чем последовательность простых.
Файл с реализацией: combine.c.3 Ключ для получения отладочной информации: -dc, файл с отладочнойинформацией: .combine.Преобразование условных операторов (if-конверсия)Преобразование зависимостей по управлению в зависимости по данным.Например, преобразование условного кода в поток управления без ветвей –обычно для предикатного исполнения команд, например для архитектурыIA-64. Файл с реализацией: ifcvt.c.3 Ключ для получения отладочной информации: -dE, файл с отладочнойинформацией: .ce.Перемещение регистровВ этом проходе обрабатываются инструкции, в которых требуетсяперезагрузить значение из памяти в регистр, но эта перезагрузка можетбыть произведена с помощью команды «перемещение регистр-регистр».Затем производится попытка оптимизировать код так, чтобы избавится отперемещения регистра – изменив просто номер регистра в инструкции.Практикум «оптимизирующие компиляторы»Возможные улучшения: уменьшения числа обращений к памяти иперемещения значений из регистра в регистр.
Файл с реализацией: regmove.c.3 Ключ для получения отладочной информации: -dN, файл с отладочнойинформацией: .regmove.Планирование инструкцийПроход определяет инструкции, выходные данные которых в выходныхрегистрахнебудутдоступнынекотороеколичествотактовдляпоследующих инструкций. Делается попытка переупорядочить инструкциив базовом блоке так, чтобы разделить определение и использованиевыходных данных, в противном случае в конвейере будут приостановки.Планирование инструкций производится дважды: после комбинированияинструкций и после перезагрузки значений в регистры.Возможные улучшения: предотвращение задержек в конвейере.