160 likes | 531 Views
LLVM. Воронин Дмитрий. Agenda. Что такое LLVM LLVM проекты Промежуточное представление LLVM Пример создания новой фазы компиляции в LLVM Пример внедрения новой фазы в компилятор clang Пример использования JIT компиляции в LLVM. LLVM.
E N D
LLVM Воронин Дмитрий
Agenda • Что такое LLVM • LLVM проекты • Промежуточное представление LLVM • Пример создания новой фазы компиляции в LLVM • Пример внедрения новой фазы в компилятор clang • Пример использования JIT компиляциив LLVM
LLVM • LLVM – набор средств разработки (компиляторы, ассемблеры, дебаггеры, библиотеки и пр.), тесно связанных между собой. • Идея разработки: • создать блоки (библиотеки), из которых можно «собирать» готовые решения (или внедрять блоки в свои проекты) • максимально переиспользовать разработанный код • Примеры: • использование парсера фронтенда для нужд IDE (индексирование, подсветка ситаксиса, рефакторинг) • использование единого промежуточного представление (IR) для всех входных языков, как для статической так и для динамической компиляции.
LLVM проекты • Clang – C/C++/Objective-C фронтент • DragonEgg – плагин к GCC, заменяющий GCC оптимизатор LLVM’овским • LLDB – дебаггер (для Mac OS X) • Libc++ - реализация C++ библиотеки для нового стандарта C++’0X • VMKit – реализация Java Virtual Machine
СПО проекты (на базе LLVM) • Crack – скриптовый язык программирования, объединяющий парадигмы C++, Java, Python • TCE – TTA-based Co-design Environment (TTA – Transport Triggered Architecture), тулчейн для преобразования C/C++ программы в VHDL • PinaVM – SystemCфронтенд, SystemC– язык для системного моделирования, дизайна и верификации • IcedTea – замена «несвободных» компонент в OpenJDK • GHC – Glasgow HaskelCompiler • Rubinius – реализация Ruby • FAUST – Functional AUdio Stream (real time audio signal processing language)
Проприетарныепроекты (на базе LLVM) • Компилятор фирмы Apple • Копилятор GPGPU фирмы Nvidia • Компилятор GPGPU фирмы AMD • Компилятор фирмы RapidMind (куплена фирмой Intel) • Portable Native Client фирмы Google
LLVM IRs LLVM IR CodeGen IR AST C X86 Backend Fortran Optimizer Power PC Backend Ada ARM Backend
Основные объекты LLVMIR LLVMContext • constants maps and predefined constants • types maps and predefined types • map of value handles Module • list of global variables and aliases • values and types sym-tabs • list of functions Function • list of arguments • list of basic blocks • values sym-tab BasicBlock • list of instructions Instruction • list of uses • result type Use - pointer to argument (Value) Constant Type
Типы Type* DerivedType IntegerType CompositeType FunctionType OpaqueType StructType SequentialType ArrayType VectorType PointerType *Type has a list of it’s uses
Значения Value Argument User* BasicBlock Constant Instruction * User has a list of it’s uses
Константы Constant ConstantInt ConstantFP ConstantArray ConstantStruct ConstantVector BlockAddress ConstantExpr GlobalValue BlockAddress UnaryConstantExpr BinaryConstantExpr GetElementPtrConstantExpr SelectConstantExpr ExtractElementConstantExpr InsertElementConstantExpr ShuffleVectorConstantExpr ExtractValueConstantExpr InsertValueConstantExpr CompareConstantExpr GlobalVariable GlobalAlias Function
Инструкции Instruction CallInst StoreInst GetElementPtrInst SelectInst BinaryOperator UnaryInstruction TerminatorInst CmpInst _other_ CastInst ICmpInst FCmpInst TruncInst ZExtInst SExtInst FPTruncInst FPExtInst UIToFPInst SIToFPInst FPToUIInst FPToSIInst IntToPtrInst PtrToIntInst BitCastInst AllocaInst LoadInst VAArgInst ExtractValueInst ReturnInst BranchInst SwitchInst IndirectInst InvokeInst UnwindInst UnreachableInst
Специальные инструкции (intrinsic) CallInst IntrinsicInst EHExceptionIntrinsic EHSelectIntrinsic MemIntrinsic DbgInfoIntrinsic DbgDeclareInst DbgValueInst MemSetInst MemTransferInst MemCpyInst MemMoveInst
Пример IR int foo( int *a, int size) { int i, sum = 0; for( i=0; i<size; i++) sum += a[i]; return sum; } definei32 @foo(i32* %a, i32 %size) { ;<label>:0 %1 = icmpsgti32 %size, 0 bri1 %1, label %1, label %3 ;<label>:1 ; preds = %1, %0 %i.1 = phii32 [ 0, %0 ], [ %i.2, %1 ] %sum.1 = phii32 [ 0, %1 ], [ %4, %1 ] %gep = getelementptri32* %a, i32 %i.1 %3 = loadi32* %gep %4 = addi32 %3, %sum.1 %i.2 = addi32 %i.1, 1 %p = icmpeqi32 %i.2, %size bri1 %p, label %2, label %1 ;<label>:2 ; preds = %1, %0 %sum.2 = phii32 [ 0, %0 ], [ %4, %1 ] reti32 %sum.2 }
Приведения объектов IR (isa, cast, dyn_cast) Каждый класс реализует метод static inline boolclassof( Value* val); template < class X, class Y > inline boolisa( Y *val); template < class X, class Y > inline X cast( Y *val); template < class X, class Y> inline X dyn_cast( Y *val); for ( BasicBlock::iterator it = bb->begin(), …) { Instruction *inst = it; if ( isa< BranchInst >( inst) ) { // inst можно привести к BranchInst BranchInst *br = cast< BranchInst >( inst); } if ( InvokeInst *invoke = dyn_cast< InvokeInst >( inst) ) { // invoke приведен к InvokeInst } }