Практикум «Оптимизирующие компиляторы» (на примере GCC) (1157417), страница 5
Текст из файла (страница 5)
Файлы с реализацией: sched-deps.c, sched-ebb.c,sched-int.h, sched-rgn.c, schedvis.c.3 Ключ для получения отладочной информации: -dS, файл с отладочнойинформацией: .sched.Распределение регистровВо время этого прохода удаляются все ссылки на псевдорегистры. Этодостигается либо назначением им аппаратного регистра, либо заменой ихэквивалентнымивыражениями(например,константами),либопомещением их в стек.
Проход состоит из нескольких подпроходов.Предпочтение класса регистраRTL-код сканируется с целью получения информации о том, какой классрегистров (какой регистровый файл) предпочтительнее для каждогопсевдорегистра. Файл с реализацией: regclass.c.Практикум «оптимизирующие компиляторы»Локальное распределение регистровНазначает аппаратные регистры псевдорегистрам, используемым внутриодного базового блока.
Файл с реализацией: local-alloc.c.3 Ключ для получения отладочной информации: -dl, файл с отладочнойинформацией: .lreg.Глобальное распределение регистровНазначает регистры псевдорегистрам, которые используются более чем водном базовом блоке (внутри одной функции). Файл с реализацией: global.c.Распределение регистров с помощью раскраски графаДругой метод распределения регистров. Включается опцией -fnew-ra. Файлы с реализацией: ra.h, ra.с, ra-build.c, ra-colorize.c, ra-debug.c, rarewrite.c.3 Ключ для получения отладочной информации: -dl.Перезагрузка регистровПроисходит перенумерованиепсевдорегистроввсоответствиисаппаратными регистрами, которые им назначены.
Псевдорегистры, длякоторых не нашлось аппаратного регистра, помещаются в стек. Далееведется поиск некорректных инструкций, в которых по разным причинамзначение не может быть помещено в регистр или этот регистр имеетнесовместимый с типом данных тип. Такие инструкции корректируютсязагрузкой «проблемных» значений во временные регистры.
Для того,чтобы сделать в памяти копию некоторого значения из регистра,генерируются дополнительные инструкции для сброса значений регистровв память. Файлы с реализацией: reload.с, reload.h, reload1.c.3 Ключ для получения отладочной информации: -dg, файл с отладочнойинформацией: .greg.Практикум «оптимизирующие компиляторы»Планирование инструкций-2Планирование инструкций повторяется для того, чтобы попытатьсяисключить приостановки конвейера, вызванные операциями загрузки изпамяти, которые появились из-за сброса псевдорегистров в память впредыдущем проходе.Возможные улучшения: предотвращение задержек в конвейере.
Файлы с реализацией: sched-deps.c, sched-ebb.c,sched-int.h, sched-rgn.c, schedvis.c.3 Ключ для получения отладочной информации: -dR, файл с отладочнойинформацией: .sched2.Переупорядочивание базовых блоковРеализуется управляемое профилировщиком переразмещение кода. Еслиинформация профилировщика не доступна, применяются различныеметоды статического анализа (например, частота запуска базовых блоковили вероятность выбора ветви программы при переходах). Файлы с реализацией: bb-reorder.c, predict.c.3 Ключ для получения отладочной информации: -dB, файл с отладочнойинформацией: .bbpro.Управление отложенными переходамиОпциональный проход для некоторых процессоров. Пытается найтиинструкции, которые могут исполняться в свободных слотах командпереходов, которые допускают отложенную форму (например, сигнальныепроцессоры, некоторые типы RISC-процессоров).Возможные улучшения: эффективное использование слотов задержки.
Файл с реализацией: reorg.c.3 Ключ для получения отладочной информации: -dd, файл с отладочнойинформацией: .dbr.Практикум «оптимизирующие компиляторы»Укорачивание ветвейВнекоторыхпроцессорахкомандыусловногопереходаимеютограниченный диапазон перехода (например, от -128 до +127 слов). Вслучае, если ветвь имеет большую длину, организовывается более длиннаяпоследовательность команд для перехода.Преобразование регистров в регистровый стекПреобразование кода базовых блоков – вместо использования обычныхрегистров с произвольным доступом к использованию регистрового стека.В настоящее время, это поддерживается только для регистров дляхранения чисел с плавающей точкой в сопроцессоре Intel 80387.
Файл с реализацией: reg-stack.c.3 Ключ для получения отладочной информации: -dk, файл с отладочнойинформацией: .stack.Вывод ассемблерного кодаВыводит ассемблерный код для функции. Также несёт ответственность заопределение ненужных инструкций тестирования и сравнения. Проводитсямашинно-зависимая оптимизация. Пролог и эпилог функции генерируютсяв виде ассемблерного кода (они никогда не существуют в RTL-коде).Возможные улучшения: использование специализированных инструкций. Файл с реализацией: final.c.Вывод информации для отладки Файлы с реализацией: dbxout.c, sdbout.c, dwarfout.c, dwarf2out.c, dwarf2asm.c,vmsdbgout.c.Практикум «оптимизирующие компиляторы»Резюме по проходамТаблица 1.
Проходы GCC.Название проходаКлючи дляполучения rtlдампаИмя файладампаГенерация RTL-dr.rtlОптимизация вызовов-di.siblingОптимизация переходов-dj.jumpSSA оптимизация-de.ssaПродвижение условных констант-dW.ssaccpУдаление “мертвого” кода-dX.ssadceУдаление общих подвыражений-ds.cseГлобальное удаление общих подвыражений-dG.gcseОптимизация циклов-dL.loop, .loop2Оптимизация цепочек переходов-dG.bypassВторичное удаление общих подвыражений-dt.cse2Анализ потока данных-df.flowКомбинирование инструкций-dc.combine-dE/-dC.ce3/.ce1Перемещение регистров-dN.regmoveПланирование инструкций-dS.schedРаспределение регистров-dlПарсерОптимизация дереваСканирование регистровЗацепление переходовПреобразование условных операторовПредпочтение класса регистраЛокальное распределение регистров.lregГлобальное распределение регистров.gregРаспределение регистров с помощью раскраскиграфаПерезагрузка регистровПланирование инструкций-2-dR.sched2Переупорядочивание базовых блоков-dB.bbproУправление отложенными переходами-dd.dbrПрактикум «оптимизирующие компиляторы»Укорачивание ветвейПреобразование регистров в регистровый стек-dk.stackВывод ассемблерного кодаВывод информации для отладкиДополнительные ключи:Таблица 2.
Дополнительные ключи.Название проходаКлючи дляполучения rtlдампаИмя файладампаАссемблерный файл аннотируется отладочнойинформацией-dAДамп после подсчёта вероятности исполненияветвей переходов-dbВывод всех макроопределений-dDВывод после организации кода обработкиисключений-dh.ehВывод после машинно-зависимых оптимизаций-dM.machВывод после перенумерования регистров после ихраспределения регистров-dn.rnregВывод после трассировщика (потока данных)-dT.tracerВывод после второго прохода анализа потокаданных-dw.flow2Вывод после прохода pipeline-оптимизации-dz.peephole2Вывод вообще всей отладочной информации обовсех проходах-daВывод статистики использования памяти-dmАннотация ассемблерных инструкции с показомвозможных вариантов генерации кода-dpВывод RTL в выходном тексте программы наассемблере-dPВывод после каждого прохода информации обуправляющем графе в виде, пригодном дляпросмотра с помощью программы просмотраграфов VCG-dvВывод информации при синтаксическом исемантическом анализе на дескриптор устройстваошибки-dy.bpПрактикум «оптимизирующие компиляторы»Представление программ вкомпилятореПри преобразовании программы, написанной на языке программированиявысокого уровня, в ассемблерный код, выполняемом при компиляции,исходная текстовая форма представления преобразуется в форму, удобнуюдляобработкикомпилятором.Промежуточнаяформаувеличиваетэффективность работы компилятора, позволяет более точно проводитьанализпотокаданныхипотокауправленияиреализовыватьразнообразные преобразования.
Выбор соответствующего промежуточногопредставления оказывает определяющее влияние на реализацию исложность исполнения оптимизирующих преобразований, и, в итоге, навремя компиляции. В целом, адекватное внутреннее представлениепрограммы позволяет улучшить многие характеристики инфраструктурыкомпилятора, например:1.
продлитьжизненныйвыполняющегоциклразличныекомпилятора,восновномпреобразованияядра,внутреннегопредставления программы;2. возможность задействовать оптимизатор, максимально (машинно)независимыйотформыпредставленияпрограммыиотхарактеристик компьютера;3. возможносмть использования компилятора как перенацеливаемого –генерирующего машинный код для разных архитектур.Обычно к внутреннему представлению программы предъявляется рядтребований, среди ключевых можно выделить:Практикум «оптимизирующие компиляторы»1. выразимость оптимизации – явное указание в промежуточномпредставлении программы действий и конструкций исходнойпрограммы;2.
сохранение качества – переход к внутреннему представлению недолжен нарушать исходные свойства программы, допускающиеэффективную реализацию;3. сохранение свойств (присутствующих во входной программе иполезных при выполнении оптимизаций);4. унификация конструкций промежуточной программы по отношениюк набору применяемых оптимизаций;5. удобство оптимизации с точки зрения упрощения алгоритмовоптимизатора.К наиболее распространённым формам промежуточного представленияпрограмм относятся синтаксическое дерево; управляющий граф (уграф),который может иметь разные формы – например, плоскую илииерархическую; постфиксная нотация (для шитых кодов); трёхадресныйкод.С практической точки зрения хорошее промежуточное представлениедолжно удовлетворять ещё ряду требований:1.