Алексей Рагозин (Deutsche Bank)

Preview:

Citation preview

LLVM – не виртуальная машина

Алексей Рагозин

В докладеГенерация машинного кода

AST Vs. Byte code Vs. Machine code

Архитектура компилятора

LLVM как экосистема

Генерация кодаИсходный код

double distance(double x1, double y1, double x2, double y2) {

return Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); }

Генерация кодаAST (Abstract Syntax Tree)

x2 x1 x2 x1 y2 y1 y2 y1

Генерация кодаИнтерпретация AST Простота реализации Гибкость Не слишком эффективно

Генерация кодаБайт код (byte code) Псевдокод, предназначенный

для интерпретации Простая система инструкций Как правило, стековая машина

Генерация кодаБайт код (JVM)

DLOAD 4: x2DLOAD 0: x1DSUBDLOAD 4: x2DLOAD 0: x1DSUBDMULDLOAD 6: y2DLOAD 2: y1

DSUBDLOAD 6: y2DLOAD 2: y1DSUBDMULDADDINVOKESTATIC Math.sqrt (D)D DRETURN

Генерация кодаПочему стековая машина? Компактный набор инструкций Простота интерпретации Простота генерации кода

Обход AST в глубину

Генерация кодаРеальный CPU Vs. Стековая ВМ Ограниченное количество регистров Неравноценные регистры CISC – сложные инструкции “Векторные” инструкции

SIMD – single instruction multiple data

Генерация кодаМашинный код (x86)# {method} 'distance' '(DDDD)D'# parm0: xmm0:xmm0 = double# parm1: xmm1:xmm1 = double# parm2: [sp+0x30] = double# parm3: [sp+0x38] = doublemov %eax,0xffffd000(%esp)push %ebpsub $0x28,%esp ;*dload

movsd 0x38(%esp),%xmm3movsd 0x30(%esp),%xmm2subsd %xmm0,%xmm2movapd %xmm2,%xmm0

mulsd %xmm2,%xmm0subsd %xmm1,%xmm3movapd %xmm3,%xmm1mulsd %xmm3,%xmm1addsd %xmm1,%xmm0sqrtsd %xmm0,%xmm0

add $0x28,%esppop %ebptest %eax,0x320100 ; {poll_return}ret

Генерация кодаБайт код Простой набор инструкций Может интерпретироваться напрямую

Бит код Бинарное представление графа выполнения Не предназначен для интерпретации

Архитектура компилятораПарсер

ПромежуточноеПредставление

Runtimeбиблиотека

Трансформация высокоуровневых

конструкций в граф исполнения

Оптимизация на уровне графа

ПромежуточноеПредставление

Генерация машинного кода

Иск

лю

чени

я

Сб

орка

мус

ора

Под

дер

жка

отл

адчи

ка

Генерация кодаLLVM IRdefine double @distance(

double %x1, double %y1, double %x2, double %y2) {

%dx = fsub double %x2, %x1 %dy = fsub double %y2, %y1 %sx = fmul double %dx, %dx %sy = fmul double %dy, %dy %ss = fadd double %sx, %sy %dst = call double @llvm.sqrt.f64(%ss) ret double %dst}

Генерация кодаLLVM IR

for.body: ... %val0 = load i32* %arrayidx ... store i32 %val0, i32* %arrayidx1 ... br i1 %exitcond, label %for.end, label %for.body for.end:

Генерация кодаLLVM IR Блок – набор инструкций без переходов SSA – single statement assignment Базовый набор инструкций “интринсики” для дополнительных

инструкций Аннотация кода мета данными

Проблема регистров Ограниченное число Неравноценность

регистров Ограничение

конвенции вызовов Дорогое сохранение /

восстановление регистров

Генерация кодаData Flow Graph

x2 x1 y2 y1

Генерация кодаLLVM – генерация кода CFG – Control Flow Graph DFG – Data Flow Graph Распределение регистров Упорядочивание инструкций+ Эвристические оптимизации

Генерация кодаLLVM – фазы кодогенератора Instruction selection Scheduling and formation SSA based optimization Register allocation Prolog/Epilog code Late machine code optimization Code emission

Генерация кодаLLVM IR – общий языкдля алгоритмов оптимизации loop unrolling autovectorization global variable numbering constant folding …

Архитектура компилятораПарсер

ПромежуточноеПредставление

Runtimeбиблиотека

Трансформация высокоуровневых

конструкций в граф исполнения

Оптимизация на уровне графа

ПромежуточноеПредставление

Генерация машинного кода

Иск

лю

чени

я

Сб

орка

мус

ора

Под

дер

жка

отл

адчи

ка

Экосистема LLVMЛицензия в стиле BSDCLang – C/C++ компиляторLLVM JIT IR интерпретатор / Интеграция с окружением (переменные и п.р.)

VMKitРазличные коммерческие проекты XCode / MacOS OpenGL / Компиляторы Intel

LLVM не …LLVM не реализует Управление памятью / сборку мусора “Динамическую” оптимизацию кода

но LLVM поддерживает Работу с картами стека (stack maps) Маркировку GC корней Вставку GC барьеров в IR

LLVM и JIT Интерпретатор IR Линковка JIT кода с родительским

процессом Качественная статическая оптимизация

Для трассирующих компиляторов Трассы можно записывать в IR

LLVMCompile once, generate code anywhere Компилятор производит IR на выходе Код распространяется в виде IR Генерация машинного кода в процессе

инсталляции / загрузки

Apple XCode, NativeCL, Android ART

Спасибо!

Алексей Рагозинalexey.ragozin@gmail.com

http://blog.ragozin.info