Опубликован: 28.06.2006 | Уровень: специалист | Доступ: платный | ВУЗ: Московский государственный технический университет им. Н.Э. Баумана
Лекция 10:

Динамическая генерация кода

Генерация развилок

Генерация кода, содержащего инструкции переходов, представляет некоторую сложность по сравнению с генерацией линейного кода. Дело в том, что появляются переходы вперед по коду, то есть переходы на инструкции, которые еще не были сгенерированы. Общий метод решения этой проблемы заключается в том, что такие инструкции переходов генерируются частично, то есть сначала вместо них в код вставляются заглушки, в которых не прописаны адреса переходов, а затем, когда адрес становится известен, заглушки заменяются на настоящие инструкции переходов.

Интересен факт, что генерация развилок существенно упрощается, если в процессе генерации придерживаться определенных требований структурированной парадигмы в программировании. Эти требования заключаются в том, что в генерируемой программе используются только пять структурных конструкций, а именно: последовательность (рис. 5.2a), выбор (рис. 5.2b), множественный выбор (рис. 5.2c), цикл с предусловием (рис. 5.2d) и цикл с постусловием (рис. 5.2e). При этом конструкции могут быть вложены друг в друга.

Peephole-оптимизация

Рис. 5.2. Peephole-оптимизация

Структурные конструкции удобны тем, что имеют ровно один вход и ровно один выход. Этот факт в сочетании с тем, что они вкладываются друг в друга, позволяет использовать для их порождения рекурсивные алгоритмы. В данном разделе мы предложим как раз рекурсивный вариант генерации структурных конструкций.

Генерация кода для логических выражений

Логические выражения отличаются от рассмотренных ранее в этой главе арифметических выражений тем, что могут вычисляться не полностью. Например, в выражении

(a = 10) and (sin(x) = 0.5)

второе равенство имеет смысл вычислять, только если первое равенство истинно (то есть если значение переменной a равно 10).

Это означает, что в коде, вычисляющем логические выражения, должны активно использоваться условные переходы.

Абстрактный синтаксис логических выражений

Будем рассматривать логические выражения, которые содержат арифметические выражения, рассмотренные ранее, в качестве подвыражений. Пусть также логические выражения содержат операции сравнения (равно, меньше, больше) и логические операции (логическое И, логическое ИЛИ, логическое НЕ).

Дополним абстрактный синтаксис выражений, приведенный ранее в данной главе, новым нетерминалом LogExpr. Правила для этого нетерминала приведены в таблице 5.4.

Таблица 5.4. Абстрактный синтаксис логических выражений
Правило Описание
LogExpr ::= Expr
Вырожденный случай, когда логическое выражение не содержит ни одной логической операции или операции сравнения
LogExpr ::= LogExpr
 ComparisonOp LogExpr
Сравнение двух выражений
LogExpr ::= LogExpr
 and LogExpr
Применение логического И
LogExpr ::= LogExpr
 or LogExpr
Применение логического ИЛИ
LogExpr ::= not LogExpr
Применение логического НЕ
ComparisonOp ::= equal
Равенство
ComparisonOp ::= less
Меньше
ComparisonOp ::=  greather
Больше
Отображение абстрактного синтаксиса логических выражений в CIL

Аналогично функциям GenExpr из раздела приведенного ранее, определим набор функций GenLogExpr, которые отображают деревья абстрактного синтаксиса, соответствующие логическим выражениям, в CIL.

Напомним, что каждая функция принимает в качестве параметра дерево абстрактного синтаксиса и возвращает последовательность инструкций:

GenLogExpr[Expr] = GenExpr[Expr];
GenLogExpr[LogExpr1 ComparisonOp LogExpr2] =
  GenLogExpr[LogExpr1],
  GenLogExpr[LogExpr2],
  GenComparisonOp[ComparisonOp];
GenLogExpr[LogExpr1 and LogExpr2] =
  GenLogExpr[LogExpr1],
  dup,
  brfalse LABEL,
  GenLogExpr[LogExpr2],
  and,
  LABEL: ;
GenLogExpr[LogExpr1 or LogExpr2] =
  GenLogExpr[LogExpr1],
  dup,
  brtrue LABEL,
  GenLogExpr[LogExpr2],
  or,
  LABEL: ;
GenLogExpr[not LogExpr] =
  GenLogExpr[LogExpr],
  not;
ComparisonOp[equal] = ceq;
ComparisonOp[less] = нужный вариант инструкции clt;
ComparisonOp[greater] = нужный вариант инструкции cgt;
Анастасия Булинкова
Анастасия Булинкова
Рабочим названием платформы .NET было
Bogdan Drumov
Bogdan Drumov
Молдова, Республика
Azamat Nurmanbetov
Azamat Nurmanbetov
Киргизия, Bishkek