Loading AI tools
Из Википедии, свободной энциклопедии
Кодогенерация — часть процесса компиляции, когда специальная часть компилятора, кодогенератор, конвертирует синтаксически корректную программу в последовательность инструкций, которые могут выполняться на машине. При этом могут применяться различные, в первую очередь машинно-зависимые оптимизации. Часто кодогенератор является общей частью для множества компиляторов. Каждый из них генерирует промежуточный код, который подаётся на вход кодогенератору.
Обычно на вход генератора кода подаётся дерево разбора[англ.] или абстрактное синтаксическое дерево. Дерево преобразуется в линейную последовательность инструкций промежуточного языка (например, в трехадресный код).
Сложные компиляторы, как правило, делают несколько проходов через различные промежуточные формы кода. Этот многоступенчатый процесс используется потому, что многие алгоритмы оптимизации кода проще реализовать каждый отдельно, или же потому, что какой-то шаг оптимизации зависит от результата отработки другого шага. Кроме того, при такой организации, легко создать один компилятор, который будет создавать код для нескольких платформ, так как достаточно заменить последний шаг генерации кода (бэкэнд, англ. backend).
Дальнейшие этапы компиляции могут и не относиться к «генерации кода», в зависимости от того, насколько значительными будут изменения, вносимые ими. Так, локальная оптимизация вряд ли может называться «генерацией кода», однако сам генератор кода может включать в себя этап локальной оптимизации.
В дополнение к основной задаче — преобразованию кода из промежуточного представления в машинные инструкции — генератор кода обычно пытается оптимизировать создаваемый код теми или иными способами. Например, он может использовать более быстрые инструкции, использовать меньше инструкций, использовать имеющиеся регистры и предотвращать избыточные вычисления.
Некоторые задачи, которые обычно решают сложные генераторы кода:
Выбор инструкций обычно выполняется рекурсивным обходом абстрактного синтаксического дерева, в этом случае сравниваются части конфигураций дерева с шаблонами; например, дерево W:=ADD(X,MUL(Y,Z))
может быть преобразовано в линейную последовательность инструкций рекурсивной генерации последовательностей t1:=X
и t2:=MUL(Y,Z)
, а затем инструкцией ADD W,t1,t2
.
В компиляторах, использующих промежуточный язык, может быть две стадии выбора инструкций — одна для конвертирования дерева разбора в промежуточный код, а вторая (следует намного позже) — для преобразования промежуточного кода в инструкции целевой системы команд. Вторая стадия не требует обхода дерева: она может выполняться последовательно и обычно состоит из простой замены операций промежуточного языка соответствующими им кодами операций. На самом деле, если компилятор фактически является транслятором (например, один переводит Eiffel в C), то вторая стадия генерации кода может включать построение дерева из линейного промежуточного кода.
Когда генерация кода происходит во время выполнения программы, как в JIT, важно, чтобы весь процесс генерации кода был эффективен как по времени, так и по используемой памяти. Например, при интерпретации регулярных выражений, чаще создаются недетерминированные конечные автоматы, чем детерминированные, потому что они создаются быстрее и занимают меньше памяти. Несмотря на то, что создаётся, в общем, менее эффективный код, генерация кода в JIT может предоставить возможность профилирования информации, доступной только во время выполнения программы.
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.