Багатоадресний код з неявно іменованим результатом (тріади)

 

Тріади являють собою записи операцій у формі із трьох складових: операція й два операнди. Наприклад, в символьному запису тріади можуть мати вигляд: <операції>(<операнд_1>,<операнд_2>). Особливістю тріад є те, що один або два операнди можуть бути посиланнями на іншу тріаду якщо операндом для даної тріади виступає результат виконання іншої тріади. Тому тріади при записі послідовно нумерують для зручності здійснення посилань одних тріад на інші (у реалізації компілятора як посилання можна використати не номери тріад, а безпосередньо посилання у вигляді вказівників - тоді при зміні нумерації й порядку проходження тріад міняти посилання не потрібно).

Наприклад, вираз А:=В*С+D-B*10, записаний у вигляді тріад, буде мати вигляд:

1: * (В, С)

2: + (^1, D)

3: * (B, 10)

4: - (^2, ^3)

5::= (А, ^4)

Тут операції позначені відповідними знаками (при цьому присвоювання також є операцією), а знак «^» означає посилання операнда однієї тріади на результат іншої.

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

Тріади являють собою лінійну послідовність, а тому для них нескладно написати тривіальний (простий) алгоритм, що буде перетворювати послідовність тріад у послідовність команд результуючої програми (або послідовність команд асемблера). У цьому їхня перевага перед синтаксичними деревами. Однак для тріад потрібен також і алгоритм, відповідальний за розподіл пам'яті, необхідної для зберігання проміжних результатів обчислення, оскільки тимчасові змінні для цієї цілі не використаються (у цьому відмінність тріад від тетрад).

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

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

Необхідність створення алгоритму, відповідального за розподіл пам'яті для зберігання проміжних результатів, є головним недоліком тріад. Але при грамотному розподілі пам'яті й регістрів процесора цей недолік може бути обернений на перевагу.

Приклад реалізації генератора коду з використанням тріад наведено в [2].

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: