Оптимизации, произведенные компилятором, могут значительно ускорить выполнение программы, особенно если она работает на процессоре, способном выполнять несколько команд параллельно. RISC-процессор — именно такого типа и ему необходим оптимизирующий компилятор для достижения высокой производительности. Применение нескольких проходов также облегчает процесс написания самого компилятора.

Рисунок 4.1 Структура оптимизирующего компилятора
Первый проход компилятора, показанного на рис. 4.1, часто называют препроцессором (front end) компилятора. Его задача — преобразование текста на ЯВУ в общую промежуточную форму (common intermediate form).
Постпроцессор (back end) компилятора состоит из фаз оптимизации и фазы генерации кода. Препроцессоры зависят от ЯВУ, тогда как постпроцессоры — от аппаратуры. Если общая промежуточная форма независима как от ЯВУ, так и от аппаратуры, то она может использоваться несколькими компиляторами. Для каждого нового ЯВУ нужен лишь новый препроцессор. Аналогично, если создан постпроцессор для новой аппаратуры, то с ним будут работать все старые препроцессоры. Такой модульный подход упрощает создание компиляторов ЯВУ для нового компьютера.
Набор команд MI аналогичен общей промежуточной форме, применяемой в компиляторах. Компилятор ЯВУ преобразует исходный текст в форму для MI. Транслятор, расположенный уровнем ниже MI, считывает программу в этой форме, выполняет оптимизацию и генерирует инструкции IMPI или PowerPC. Транслятор очень напоминает постпроцессор компилятора.
Общая промежуточная форма для некоторых языков может как транслироваться, так и интерпретироваться. В главе 11 мы рассмотрим язык Java, использующий как раз такую форму. Промежуточная форма Java, известная как байт-код, также включена в MI.
Набор инструкций MI заменяет общую промежуточную форму не во всех компиляторах AS/400 — некоторые языки имеют собственную промежуточную форму. Ниже приводится описание внутренней структуры компиляторов языков для AS/400, и место MI в этой структуре.
Компиляторы для AS/400
Ранние компиляторы (например, RPG/400 и языка управления CL) для System/38 и AS/400 генерировали команды: MI довольно прямолинейно. Хотя они и проходили уровень ассемблера, в самом компиляторе не было общей промежуточной формы. Ее роль выполняли команды MI.
Модель программы для этих языков, включая форму программы ниже уровня MI, называется исходной моделью программ или OPM (Original Program Model). Позднее, для языков типа C/400, была добавлена расширенная модель программ или EPM (Extended Program Model). На рисунке 4.2 показан процесс генерации кода IMPI для OPM и ЕРМ. Мы представили здесь эти две модели только для демонстрации эволюции компиляторов AS/400. На RISC-системах версии 4 не используются ни компиляторы ОРМ, ни ЕРМ.
Сначала рассмотрим компилятор ОРМ. Он принимает на входе операторы ЯВУ ОРМ (вместе с не показанными на рисунке описаниями файлов) и на выходе генерирует код промежуточного представления программы IRP (Intermediate Representation of a Program). IRP, по сути, — ассемблер для команд MI. Следующий шаг — код IRP преобразуется в команды MI с помощью компонента под названием PRM (Program Resolution Monitor), который создает шаблон программы, помеченный на рисунке как шаблон программы ОРМ и содержащий команды MI и другие данные. Шаблоны используются для создания объектов MI. Транслятор, расположенный ниже уровня MI, создает по шаблону программы программный объект, содержащий команды IMPI. Содержание шаблона программы будет рассмотрено далее.
ОРМ — пример классического компилятора, генерирующего ассемблерную форму программы (IRP), после чего ассемблер (PRM) генерирует двоичную машинную программу (шаблон программы). Компиляция на AS/400 требует дополнительного шага (этапа трансляции) и поэтому может занимать больше времени, чем на некоторых других системах. Обратите внимание, что все эти этапы для пользователя AS/400 невидимы и выглядят, как одна операция.
По мере реализации на AS/400 новых языков, таких как С/400 и Pascal, потребовалось добавить расширения. Этапы компиляции для ЕРМ (расширенной версии ОРМ) также показаны на рис. 4.2. В компиляторах таких языков препроцессор и постпроцессор разделены. Общая промежуточная форма в них называется U-код. Для AS/400 был создан новый постпроцессор компиляторов CUBE-1 (Common Use Back End 1).
Читать дальше