Генерация высококачественного кода для программ на СИ
Страница 15. Lattice Inc.


 

Lattice Inc.

 Имеющий большую историю компилятор Lattice MS-DOS C последовательно
 совершенствовался с каждой новой версией. Он известен как генератор
 стабильного, предсказуемого кода и выполняет умеренную оптимизацию.
 Lattice С выполняет снижение мощности, сжатие цепочки переходов и удаление
 общих подвыражений. Он не удаляет дублирующиеся присваивания после теста
 встроенных функций и лишние присваивания в функции dead_code. Хотя он не
 генерирует никакого кода для недостижимого printf в функции dead_code,
 компилятор Lattice C генерирует ненужный безусловный переход к LEAVE,
 которая является следующей инструкцией.
 Единственными сгенерированными машинно-зависимыми инструкциями были ENTER
 и LEAVE, инструкции микропроцессоров 80x86 для прологов и эпилогов
 функций. Это сомнительное благо, поскольку выполнение ENTER требует больше
 циклов микропроцессора, чем установка адресации стекового фрейма
 отдельными инструкциями. Lattice C не выполняет оптимизацию циклов.
 Manx Software Systems Inc.
 Компилятор Aztec C86 сгенерировал хороший код с довольно хорошим уровнем
 оптимизации. Кроме свертки констант и алгебраических упрощений, Aztec C86
 выполнил снижение мощности и удаление общих подвыражений. Однако, он не
 выполнил удаление лишних присваиваний и не удалял недостижимый код. Aztec
 C86 сгенерировал код для недостижимого оператора printf вместе с
 безусловным переходом через него.
 Поскольку любая программа на Си имеет значительное количество вызовов
 функций, заголовок каждого вызова необходимо минимизировать. 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 к оптимизации вознаграждается при работе теста
 выполнения. Он выполняется за время, которое является лучшим или близко к
 лучшему по каждой категории.

 
« Предыдущая статья   Следующая статья »