Проміжне представлення (IR) — структура даних або код, що використовується внутрішньо компілятором або віртуальною машиною для подання вихідного коду. IR проєктується так, щоб бути зручним для подальшої обробки, зокрема для оптимізації та трансляції. «Хороше» IR повинно бути точним — здатним представляти вихідний код без втрати інформації — та незалежним від будь-якої конкретної мови-джерела або цільової мови. IR може набувати однієї з кількох форм: внутрішньої структури даних, або спеціального кортежного чи стекового коду, читаного програмою. В останньому випадку його також називають проміжною мовою.

Канонічний приклад можна знайти в більшості сучасних компіляторів. Наприклад, інтерпретатор CPython перетворює лінійний, людиночитаний текст програми на проміжну графову структуру, яка дозволяє виконувати аналіз потоку керування та перестановки перед виконанням. Використання такого проміжного представлення дозволяє компіляторним системам, як-от GNU Compiler Collection і LLVM, застосовуватися для багатьох різних мов-джерел з метою генерації коду для багатьох різних цільових архітектур інструкцій.

Проміжна мова Проміжна мова — мова абстрактної машини, призначена для полегшення аналізу комп'ютерних програм. Термін походить з їх використання в компіляторах, де вихідний код програми транслюється у форму, більш придатну для перетворень з покращення коду, перш ніж бути використаним для генерації об'єктного або машинного коду для цільової машини. Проєктування проміжної мови зазвичай відрізняється від практичної машинної мови трьома фундаментальними способами:

Кожна інструкція представляє рівно одну фундаментальну операцію; наприклад, інструкції з режимами адресації типу «зсув-додавання», поширені в мікропроцесорах, відсутні.

Інформація про потік керування може не включатися до набору інструкцій.

Кількість доступних регістрів процесора може бути великою або навіть необмеженою.

Популярним форматом проміжних мов є трьохадресний код.

Цей термін також використовується для позначення мов, які застосовуються як проміжні деякими мовами програмування високого рівня, що самі не генерують об'єктний або машинний код, а виводять лише проміжну мову. Ця проміжна мова передається компілятору для такої мови, який потім генерує завершений об'єктний або машинний код. Зазвичай це робиться для спрощення процесу оптимізації або для підвищення переносимості шляхом використання проміжної мови, для якої існують компілятори для багатьох процесорів і операційних систем, таких як C. Мови, що використовуються для цього, за складністю знаходяться між мовами високого рівня та низькорівневими мовами, такими як мова асемблера.

Мови

Хоча C не була явно спроєктована як проміжна мова, її природа як абстракції асемблера та її повсюдна поширеність як де-факто системної мови в Unix-подібних та інших операційних системах зробили її популярною проміжною мовою: Eiffel, Sather, Esterel, деякі діалекти Lisp (Lush, Gambit), підмножина Smalltalk Slang у Squeak, Nim, Cython, SystemTap, Vala, V та інші використовують C як проміжну мову. Варіанти C були розроблені для надання її можливостей як переносної мови асемблера, зокрема C-- та C Intermediate Language.

Будь-яку мову, що орієнтована на віртуальну машину або p-code машину, можна вважати проміжною мовою:

байткод Java Загальна проміжна мова Microsoft — проміжна мова, призначена для спільного використання всіма компіляторами для .NET Framework перед статичною або динамічною компіляцією в машинний код. Хоча більшість проміжних мов створені для підтримки статично типізованих мов, проміжне представлення Parrot призначене для підтримки динамічно типізованих мов — спочатку Perl і Python.

TIMI використовується компіляторами на платформі IBM i.

O-code для BCPL Попередньо скомпільований код MATLAB Microsoft P-Code Pascal p-code

GNU Compiler Collection (GCC) використовує кілька проміжних мов внутрішньо для спрощення переносимості та крос-компіляції. Серед цих мов:

історична Register Transfer Language (RTL) деревоподібна мова GENERIC заснована на SSA мова GIMPLE. (Нижчий рівень, ніж GENERIC; вхід для більшості оптимізаторів; має компактну «байткодну» нотацію.) GCC підтримує генерацію цих IR як кінцевої цілі: HSA Intermediate Layer

LLVM Intermediate Representation (перетворюється з GIMPLE у вже неактуальному llvm-gcc, який використовує оптимізатори та генерацію коду LLVM).

Компіляторна платформа LLVM базується на проміжній мові LLVM IR, компактне бінарне серіалізоване представлення якої також називається «bitcode» і було продукталізоване Apple. Подібно до байткоду GIMPLE, LLVM Bitcode корисний для оптимізації на етапі компонування. Як і GCC, LLVM також орієнтується на деякі IR, призначені для прямого розповсюдження, зокрема IR Google PNaCl і SPIR. Подальшим розвитком у межах LLVM є використання багаторівневого проміжного представлення (MLIR) з потенціалом генерації коду для різних гетерогенних цілей і поєднання виходів різних компіляторів.

Проміжна мова ILOC"An ILOC Simulator" W. A. Barrett, 2007, перефразування роботи Keith Cooper та Linda Torczon «Engineering a Compiler», Morgan Kaufmann, 2004. . використовується в курсах з проєктування компіляторів як проста цільова мова."CISC 471 Compiler Design" Uli Kremer

Інше Інструменти статичного аналізу часто використовують проміжне представлення. Наприклад, Radare2 — це набір інструментів для аналізу бінарних файлів і зворотної інженерії. Він використовує проміжні мови ESIL та REIL для аналізу бінарних файлів.

Примітки