Практикум «Оптимизирующие компиляторы» (на примере GCC), страница 15
Описание файла
PDF-файл из архива "Практикум «Оптимизирующие компиляторы» (на примере GCC)", который расположен в категории "". Всё это находится в предмете "конструирование компиляторов" из 7 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Просмотр PDF-файла онлайн
Текст 15 страницы из PDF
Исходные инструкции, указанные в однойстроке, могут выполняться одновременно. В затемнённых ячейках таблицыуказаны номера итераций исходного цикла.Номер инструкции в исходном теле циклаТакт654372112112122312334234453451Группаинструкций1Старт-кодПрактикум «оптимизирующие компиляторы»61234556723456678345677894567889105678991011678910101112789101111121389101112121314910111213131415101112131414151611121314151516171213141516161813141516191415162015162116Итерации цикла(11 итераций)Код зачисткиВынесение условных выражений за пределы циклаЦель оптимизации: Уменьшение накладных расходов на проверкуусловия с инвариантной относительно цикла переменной.Пути достижения: Перенос цикла в ветви условного оператора.Граф потока управления для циклаvoid foo (void) {0:int i;0:i = 0;1:while (i < n) {2:вход0/*тело цикла*/3:1}}23выходПрактикум «оптимизирующие компиляторы»Исходный кодИсходный код после вынесения условноговыраженияint n = 64;int n = 64;int a [64];int a [64];int b [64];int b [64];void foo (void) {void foo (void) {0:int i = 0;0:int i = 0;0:int c;0:int c;1:while (i < n){0:if (c < 10)2:a[i]=a[i]+4;2:2:if (c<10)3:a [i] = a[i]+4;3:b[i]=a[i]*b[i-1];3:i++;3:2:b[i]=a[i]*b[i-1];else4:6:while (i < n) {b[i]=a[i]+6;i++;}0:else8: }7:}8:a [i] = a[i]+4;8:b[i]=a[i]+6;8:i++;while (i < n) {9:}}Практикум «оптимизирующие компиляторы»Исходный граф потока управленияГраф потока управления после вынесенияусловного выраженияначалоначало012310236467889конецконецВынесение первых и последних итерацийЦель оптимизации: Удаление зависимостей, вызванных несколькимипервыми или последними итерациями.Пути достижения: Вынесение нескольких первых или последнихитераций за пределы цикла.Исходный текстКод после вынесения первой итерации второгоциклаint n = 64;int n = 64;int a [64];int a [64];int b [64];int b [64];void foo (void) {void foo (void) {0:int i = 3;0:int i = 2;1:while (i < n) {0:if (i <= 2)Практикум «оптимизирующие компиляторы»2:b [i] = b [i] + b [2];1:2:i++;2:i = 3;}3:while (i < n) {i = 2;4:a [i] = a [i] + 3;while (i < n) {4:b [i] = b [i] + b[2]i++;4:5:6:a [i] = a [i] + 3;4:6:i++;7:9:}a [i] = a [i] + 3;}}}Исходный граф потока данныхГраф потока данных после вынесения первойитерации первого цикланачалоначало0011224569347конецконецОптимизация хвостовых вызововЦель оптимизации: Уменьшить накладные расходы при вызове функций.Пути достижения: Замена вызова (call) на безусловный переход (jmp).Практикум «оптимизирующие компиляторы»Исходная программаint bar (int a) {int foo (int a) {printf ("bar!");printf ("foo!");if (a == 0)if (a == 0)return -1;return 0;return a;return bar (a);}}Оптимизация вызовов отключенаОптимизация вызовов включенаbar:bar:pushl%ebppushl%ebpmovl%esp, %ebpmovl%esp, %ebp……leaveleaveretretfoo:foo:pushl%ebppushl%ebpmovl%esp, %ebpmovl%esp, %ebp……subl$12, %espmovl8(%ebp), %eaxpushl8(%ebp)movl%eax, 8(%ebp)callbarleaveaddl$16, %espjmpbar……leaveleaveretretВстраивание функций (Inline)Цель оптимизации: Снижение накладных расходов на вызовы функций(за счет увеличения размера).Путидостижения:вызывающуюКопированиефункцию.телаКонкретнаявстраиваемойреализацияфункциивопределяетсякомпилятором.
Обычно есть ряд ограничений на разрастание кода и наприсутствие в коде различных управляющих структур, например вызовадругих функций.Практикум «оптимизирующие компиляторы»Оригинальный кодvoid bar (int* a, int i) {После встраиванияvoid foo (void) {a[i]=a[i]+3;int i;}for (i = 3; i < n; i++)a[i]=a[i]+3;void foo (void) {int i;for (i = 3; i < n; i++)bar (a, i);}}Практикум «оптимизирующие компиляторы»Приложение А.
Установка GCCКратко опишем процесс установки GCC с использованием исходныхкодов. Более подробную информацию об установке можно получить издокумента “GCC Installation Guide” (http://gcc.gnu.org/install/).Получение дистрибутива.Как получить последнюю версию дистрибутива компилятора можноузнать по адресу http://gcc.gnu.org/releases.html. На момент написанияданного пособия последняя версия компилятора была 3.3.3.
Существуетдва основных варианта дистрибуции: компилятор в полном объёме (совсеми языками, которые входят в стандартную поставку), или отдельноядро компилятора и ряд пакетов поддержки входных языков. Дляопределённости, далее предполагается использование первого варианта, вэтом случае файл с исходными кодами компилятора имеет имя gcc3.3.3.tar.bz2.
Для начала работ по установке нужно извлечь содержимоеархива:# tar –jxf gcc-3.3.3.tar.bz2В результате выполнения этой команды в текущем каталоге появитсякаталог gcc-3.3.3 c исходными кодами GCC.Конфигурирование GCCПеред началом установки необходимо создать каталог для храненияобъектныхмодулейиисполняемыхфайлов.Рекомендуетсянеиспользовать дерево каталогов gcc, которое получается в результатераспаковки архива (т.е. в нашем случае, gcc-3.3.3). Создать каталогможно следующим образом:Практикум «оптимизирующие компиляторы»# mkdir objdir# cd objdirДалее необходимо запустить сценарий конфигурации:# ../gcc-3.3.3/configure --prefix=somedir--enable-languages=somelangОпция --prefix указывает каталог, куда будет установлен GCC (поумолчанию это /usr/local). Опция --enable-languages содержитсписок необходимых языков, разделенных запятой. Стандартная поставкаподдерживает следующие языки: ada, c, c++, f77, java, objc.КомпиляцияДля запуска компиляции необходимо выполнить следующую команду:# make bootstrapТестированиеДля проверки работоспособности и корректности компилятора можновыполнитьтестированиятестирование,номожнонайтиэтотвшагнеобязателен.документе“GCCОписаниеTesting”(http://gcc.gnu.org/install/test.html).
Выполнение тестирования:# make –k checkУстановка# make installПроисходит копирование файлов в указанную директорию somedir исоздание справочной документации.Практикум «оптимизирующие компиляторы»Приложение Б. Использование GCCВовремяработыGCCобычновыполняетпрепроцессирование,компиляцию, ассемблирование и линковку. «Общие опции» позволяютостановить этот процесс на промежуточной стадии. Например, приуказании опция -c не запускается линкер. Тогда вывод состоит ихобъектных файлов, порожденных ассемблером.Другие опции передаются на одну из стадий обработки. Одни опцииуправляют препроцессором, другие самим компилятором; имеются опции,управляющие ассемблером и линкером; большинство из них не описаноздесь, поскольку редко требуется использовать какую-нибудь из них.Можно указывать опции и другие аргументы в любом порядке.
Побольшей части, используемый порядок не имеет значения. Но, порядокважен, когда используется несколько опций одного вида. Например, еслиуказана опция -L (см. ниже) больше чем один раз, директориипросматриваются в порядке указания.Многие опции имеют длинные имена, начинающиеся с -f или с -W.Большинство из них имеет положительную и отрицательную формы;отрицательной формой -ffoo будет -fno-foo.Общие опции-x языкУказывает, какой язык использовать для заданного входного файла.Возможные значения опции: c, c-header, cpp-output, c++, c++header,c++-cpp-output,objective-c,objective-c-header,objc-cpp-output, assembler, assembler-with-cpp, ada, f77,f77-cpp-input, ratfor, java, treelang.Практикум «оптимизирующие компиляторы»$ gcc –x java test.java-cОтключаетлинковщик.Исходныефайлыкомпилируютсяилиассемблируются, но не линкуются.
Конечный вывод происходит в формеобъектного файла для каждого исходного файла. По умолчанию, имяобъектного файла формируется из имени исходного файла заменойсуффикса («.c», «.cpp» и т. д.) на «.o».$ gcc –c somelib.c-SОстановиться после компиляции, не ассемблировать. Вывод производитсяв форме файла с ассемблерным кодом для каждого не ассемблерноговходного файла. По умолчанию, имя файла с ассемблерным кодомделается из имени исходного файла заменой суффикса («.c», «.cpp» и.т.
д.)на «.s».$ gcc –S sibcall.c-EОстановиться после стадии препроцессирования, не запускать собственнокомпилятор. Вывод делается в форме препроцессированного исходногокода, который посылается на стандартный вывод.$ gcc –E test.cpp-o имя_файлаПоместить вывод в файл имя_файла. Эта опция применяется внезависимости от вида порождаемого файла, есть ли это выполнимый файл,объектный файл, ассемблерный файл или препроцессированный C код.Поскольку указывается только один выходной файл, нет смыслаиспользовать -o при компиляции более чем одного входного файла, еслине порождается выполнимый файл.Практикум «оптимизирующие компиляторы»Если -o не указано, по умолчанию выполнимый файл помещается в a.out,объектный файл для source.suffix – в source.o, его ассемблерный кодв source.s и все препроцессированные C файлы – в стандартный вывод.$ gcc –o program source1.c source2.c object1.oobject2.o-pipeИспользовать неименованные программные каналы вместо временныхфайлов для коммуникации между различными стадиями компиляции.Опции оптимизации и генерации отладочной информации-gПорождает отладочную информацию в родном формате операционнойсистемы (stabs, COFF, XCOFF или DWARF).
GDB (отладчик) можетработать с этой отладочной информацией.-O1, -O2, -O3, -OsОптимизировать. Этими флагами устанавливается то, какие проходыоптимизации будут выполнены.Флаг -Os включает оптимизацию размера.-O0Не оптимизировать.Опции поиска каталогов и подключения библиотек-llibraryИщет при линковке библиотеку с именем library. Есть различие в том,где в командной строке указана эта опция: линкер ищет обрабатываемыебиблиотеки и объектные файлы в порядке, в котором они указаны. ТакимПрактикум «оптимизирующие компиляторы»образом, foo.o -lz bar.o ищет библиотеку z после файла foo.o, ноперед bar.o.
Если foo.o ссылается на функции в z, эти функции не могутбыть загружены.Линкерпросматриваетбиблиотеки,которая,стандартныйсписоккаталоговвпоискахфактически,являетсяфайломсименемliblibrary.a. Затем линкер использует этот файл так, как будто бы онбыл точно специфицирован по имени.Директории, в которых ищет линкер, включают несколько стандартныхсистемных каталогов, плюс любые каталоги, которые определены спомощью опции -L (см.