Поскольку любая программа на Си имеет значительное количество вызовов функций, заголовок каждого вызова необходимо минимизировать. Aztec C86 использует необычный, но эффективный подход к решению этой проблемы. На выходе компилятора получается текст в языке ассемблера, который обрабатывается отдельным ассемблером. Компилятор вставляет в текст директивы условного ассемблирования вокруг кода, который устанавливает стековый фрейм и сохраняет регистры. После генерации кода функции компилятор определяет символы для управления установкой стекового фрейма и сохранения только тех регистров, которые используются в функции.
Aztec C86 не смог решить задачу преобразования цепочки переходов в один переход к конечной цели. Он также не выполнял оптимизацию циклов.
Metaware Inc.
High C вырабатывает хороший код со средним уровнем оптимизации. Компилятор выполняет все базовые виды оптимизации, включая свертку констант и алгебраические упрощения, удаление лишних операций загрузки регистров, снижение мощности и удаление общих подвыражений. Компилятор Metaware удаляет недостижимый код из функции dead_code, но не удаляет лишние присваивания.
High C разумно использует машинно-зависимые инструкции. Компилятор усовершенствует загрузку констант с плавающей точкой, используя команду копирования строк MOVS процессоров 80x86 для записи значений с плавающей точкой, вычисленных во время компиляции. Он также генерирует инструкцию LEAVE процессоров 80x86 для эпилога функций, но устанавливает адресацию стекового фрейма в прологе функции с помощью отдельных инструкций, а не используя более длительную инструкцию ENTER.
Компилятор High C не выполняет вынесение инвариантного кода, важный метод оптимизации циклов. Он также не смог применить успешно удаление переменных индукции циклов. Встроенные функции поддерживаются для нескольких целочисленных и строковых операций, таких как strlen.
Microsoft C.
В версии 5.0 своего компилятора Си корпорация Microsoft вывела высокий уровень оптимизации кода на рынок PC. Microsoft уделяет много внимания анализу циклов. C 5.0 – единственный из рассматриваемых компиляторов, который выполняет вынесение инвариантного кода и настоящее удаление переменных индукции циклов. Компилятор Microsoft C 5.0 превосходно использует регистры, стараясь минимизировать обращения к памяти в теле цикла (см. рис. 4 и 5).
Простой пример цикла в коде теста демонстрирует степень оптимизации циклов, выполняемой Microsoft C 5.0 (см. рис. 3). Компилятор применяет снижение мощности и полностью удаляет константное умножение, выявляет конечное состояние переменных j5 и k5, и помещает в регистры все переменные внутри цикла.
Другой хороший пример оптимизации циклов этим компилятором отражен в функции unnecessary_loop. C 5.0 удаляет цикл for и генерирует код только с целью установки конечного состояния переменной - индекса цикла и оператора, включенного в цикл. Компилятор также хорошо использует регистры.
Внимание фирмы Microsoft к оптимизации вознаграждается при работе теста выполнения. Он выполняется за время, которое является лучшим или близко к лучшему по каждой категории.
Microsoft QuickC.
Когда речь идет об оптимизации, QuickC становится настолько беспомощным, насколько C 5.0 изощренным. Код, сгенерированный QuickC, был в основном дословным переводом, насыщенным излишними загрузками и сохранениями регистров, переходами на переходы. Этот компилятор применяет лишь наиболее первичные методы оптимизации, свертку констант и некоторые алгебраические упрощения. Он сгенерировал недостижимый код, поместил переход через него и не смог выполнить сжатие цепочки переходов.
В пользу компилятора свидетельствует то, что что он разумно управляет прологами и эпилогами функций, используя отдельные инструкции для установки адресации стекового фрейма при входе и инструкцию LEAVE при завершении функции. При входе сохраняются и при выходе восстанавливаются только те регистры, которые используются в теле функции.
QuickC был влючен в этот обзор, потому что он имеет ключ оптимизации в командной строке (-Ox). Генерируя код, который по своей природе - дословный перевод исходного текста, QuickC был разработан исключительно как быстрый прототип компилятора, но не как оптимизирующий компилятор.
WATCOM.
Новейший соперник, завоевывающий позиции на рынке компиляторов C - WATCOM C 6.0 (см. Product Watch, Philip N. Hisley, за этот месяц). C 6.0 вырабатывает компактный код, который прекрасно использует несколько ограниченный комплект регистров семейства 80x86. Кроме выполнения базовых приемов оптимизации, он поддерживает снижение мощности и удаление недостижимого кода и общих подвыражений. В то время, как Microsoft достигает улучшения кода благодаря оптимизации циклов, WATCOM увеличивает скорость путем уменьшения управляющих заголовков вызовов функций к их абсолютно минимальному размеру. Он достигает этого путем преимущественной передачи параметров через регистры, а не через стек.