**Dynamic VLIW** — сборка VLIW-бандла переносится из compile-time в run-time, статический ISA (например, x86 или ARM) транслируется в широкое VLIW-слово на лету:
- бинарный транслятор (программный или аппаратный) формирует и кеширует бандлы прямо по ходу исполнения;
- решения о параллелизации учитывают реальные кеш-промахи и поведение ветвлений, чего статическому компилятору не видно;
- сохраняется совместимость со стандартным ISA, под капотом — VLIW-ядро.
- Примеры: **Transmeta Crusoe/Efficeon** (x86 $\rightarrow$ VLIW через Code Morphing Software), **NVIDIA Denver/Carmel** (ARM $\rightarrow$ внутренний широкий формат с кешированием трансляций).
----
### Смешение уровней. Интеграция
Уровневую организацию и разделение по уровням разбирали раньше. Здесь — обратный процесс.

1. Зачем: для обеспечения системных характеристик: энергопотребление, реальное время, производительность.
1. Смешение уровней $\longrightarrow$ рост связанности и сложности системы.
1. Смешение уровней при разработке.
1. Сквозные инструментальные решения.
Пример: hard real-time на современном процессоре. Спекулятивное исполнение, OoO, кеш, виртуальная память делают время выполнения недетерминированным $\longrightarrow$ требуется отключение/обход этих механизмов на нижних уровнях.
---
## Языки высокого уровня
Инструкции и Go To $\rightarrow$ Структурные блоки и их последовательность
1. Естественные элементы для архитектуры фон Неймана:
- последовательный код$^*$,
- условный оператор$^*$,
- циклы, подпрограммы.
1. Распределение регистров. Математические выражения.
1. Функции, области видимости и автоматическая память.
1. Исключения, состояния и перезапуски.$^{**}$
1. Полиморфизм. Замыкания.$^{**}$
- $^*$ — переосмыслены.
- $^{**}$ — опустим.


Подробности: [Курс ФП. История](https://gitlab.se.ifmo.ru/functional-programming/main)
----
### Распределение регистров. Выражения


1. Проблемы:
- кол-во регистров конечно (ARM 15/31, x86 8/16, MIPS 32/32),
- не все регистры одинаковы (особенно в CISC).
1. Проблема компилятора или низкоуровневого программирования.
1. Код не ограничивается выражениями.
1. Согласование использования регистров между вызовами процедур.
----
#### Раскраска регистров

$R_1, R_2$ — регистры аргументов.
$R_{LK}$ — возврат, $R_1$ — результат.
Источник: [Register allocation](https://cs420.epfl.ch/archive/20/c/08_reg-alloc.html)
В статье пример с Lisp.
---
### Подпрограммы. Процедуры
1. Зачем:
- переиспользование машинного кода,
- оптимизация работы кеша инструкций.
1. Инструкции:
- Через `inline`.
- Через `goto`.
- Через `call`, `return`.
1. Данные: рабочая память выделена статически.
1. Нет реентерабельности (при статическом выделении).
1. Проблемы: кеширование, сброс регистров, переходы и конвейер.
```c
int *x, *y;
void *SWAP_RET;
int tmp;
swap:
tmp = *x;
*x = *y;
*y = tmp;
goto *SWAP_RET;
```
```c
int tmp;
void swap(int *x, int *y) {
tmp = *x;
*x = *y; // прерывание: isr()
*y = tmp;
}
int a, b;
void isr() {
a = 1;
b = 2;
swap(&a, &b);
}
```
----
#### Реентерабельность. Рекурсивный вызов
1. Реализация через `call`, `return`.
- Статическое выделение памяти для каждого входа.
- Автоматическая память, стек: `push`, `pop` (рекурсия).
1. Зачем:
- параллелизм уровня задач,
- рекурсивные алгоритмы.
1. Проблемы: автоматическая память, утечки данных, перезапись адреса возврата.
```c
int fact(int n) {
if (n == 0) return 1;
return n * fact(n - 1);
}
```
```c
struct swap {int* x; int* y; int tmp;};
void swap(struct swap* base) {
base->tmp = *(base->x);
*(base->x) = *(base->y);
*(base->y) = base->tmp;
}
struct swap enter1, enter2;
swap(&enter1);
swap(&enter2);
// или через автоматическую память (стек):
void swap(int* x, int* y) {
int tmp; // reserve mem
tmp = *x;
*x = *y;
*y = tmp;
}
```

---
### Переосмысление условного оператора
- (1) Традиционный подход: встроенная конструкция языка, реализуемая инструментарием (компилятор, интерпретатор).
- (2) Полиморфизм + замыкания (анонимные функции). Smalltalk.
```smalltalk
Object subclass: #Bool !
Bool subclass: #True
ifTrue: aBlock ifFalse: bBlock
^ aBlock value ! !
Bool subclass: #False
ifTrue: aBlock ifFalse: bBlock
^ bBlock value ! !
```
```smalltalk
(17 * 13 > 220).
>>>true
(17 * 13 > 220)
ifTrue: [ 'bigger' ]
ifFalse: [ 'smaller' ].
>>>'bigger'
n := 1.
[ n < 1000 ] whileTrue: [ n := n*2 ].
n
>>> 1024
```
----
- (3) Нормальный порядок вычислений. Ленивые вычисления.
Охватывающее выражение полностью редуцируется, применяя функции до вычисления аргументов (с кешированием).
```python
def my_if(cond, if_true, if_false):
if cond:
if_true
else:
if_false
my_if(True,
print("foo"),
print("bar"))
```
```python
if True:
print("foo")
else:
print("bar")
```
```python
print("foo")
```
Нормальный порядок (~макросы)
``` c
#define square(X) ((X) * (X))
x = square(1 + 2);
-> x = ((1 + 2) * (1 + 2));
```
Ленивые вычисления:
```haskell
let square x = x * x
in square (1 + 2)
--
let square x = x * x
tmp = 1 + 2
in square tmp
--
let square x = x * x
tmp = 1 + 2
in tmp * tmp
```
---
### Переосмысление последовательного кода
- (1) Optional Chaining (Swift).
Глубокий JSON с опциональными полями.
```swift
let string: String? = "hello" // or nil
let count = string?.count
if count != nil {
print(count!)
}
```
----
- (2) `async/await`
То, что выглядит последовательным кодом, им не является (кооперативная многозадачность).
```python
import asyncio
async def main():
print('hello')
await asyncio.sleep(1) # будет возвращено замыкание, с оставшимся
# кодом, которое будет выполнено после
# завершения sleep.
print('world')
asyncio.run(main()) # asyncio.run обеспечивает ожидание асинхронных
# функций и запуск соответствующих замыканий.
# (кооперативная многозадачность)
```
----
- (3) Монады. Явно определяем операцию связывания (`bind`, `>>=`):
- результата прошлого шага
- и действия следующего шага.
(без погружения в детали, очень синтетический пример, без синтаксического сахара и реального применения)
```haskell
class Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
instance Monad Maybe where
return :: a -> Maybe a
return x = Just x
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
Nothing >>= _ = Nothing
Just x >>= f = f x
string = Just "hello"
count = string >>= (\s -> return (length s))
```
Async/Await — см. библиотеку lwt для OCaml.
Детали: см. курс [Функционального программирования](https://gitlab.se.ifmo.ru/functional-programming/main).