Low Level Virtual Machine
Transkrypt
Low Level Virtual Machine
Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie Low Level Virtual Machine J. Lamecki 14 czerwca 2011 J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie Outline 1 Wprowadzenie Co to jest LLVM? Dlaczego moduªowy kompilator? Cechy LLVM 2 LLVM IR - posta¢ po±rednia Format LLVM IR Bloki podstawowe SSA 3 LLVM jako biblioteka U»yte narz¦dzia Przykªad generowania funkcji Kompilacja JIT Kompilacja AOT 4 Podsumowanie Podsumowanie J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie Co to jest LLVM? Dlaczego moduªowy kompilator? Cechy LLVM Co to jest LLVM? Zestaw gotowych klocków umo»liwiaj¡cych konstrukcj¦ kompilatora Low Level Virtual Machine - niskopoziomowa maszyna wirtualna LLVM posiada swój byte-code - posta¢ po±redni¡ pozwalaj¡c¡ przedstawi¢ w niej programy napisane w j¦zykach niskopoziomowych, takich jak j¦zyk C. Doª¡czone s¡ tak»e moduªy pozwalaj¡ce na generowanie kodu maszynowego oraz optymalizacj¦ postaci po±redniej. J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie Co to jest LLVM? Dlaczego moduªowy kompilator? Cechy LLVM Dlaczego moduªowy kompilator? Kompilatory s¡ zªo»onymi i czasochªonnymi w tworzeniu programami Przykªad GCC - 5,7mln tys LOC LLVM - 670tys LOC Wiele elementów kompilatora jest niezale»ne od docelowej architektury, systemu operacyjnego i j¦zyka programowania Przykªad GCC - 35 architektur, > 15 j¦zyków LLVM - 13 architektur, > 10 j¦zyków J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie Co to jest LLVM? Dlaczego moduªowy kompilator? Cechy LLVM Dlaczego moduªowy kompilator? (cd.) Wiele zastosowa« wymaga generowania kodu maszynowego (cz¦sto JIT) Przykªad rodowiska wykonawcze j¦zyków skryptowych, graka 3D (shader'y) Ci¡gle powstaj¡ nowe architektury Przykªad x86_64 (1999), XCore (2007), Blackn (2000), AVR32 (2006), LatticeMicro32 (2006), S+core (2005), ESi-RISC (2009) J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie Co to jest LLVM? Dlaczego moduªowy kompilator? Cechy LLVM Cechy LLVM Wsparcie 13 architektur sprz¦towych Wiele gotowych moduªów optymalizacji (z mo»liwo±ci¡ ªatwego dodawania wªasnych oraz zale»no±ci mi¦dzy moduªami) Czytelna i prosta w zrozumieniu posta¢ po±rednia (LLVM Intermediate Representation) Doskonaªa dokumentacja i wiele przykªadów Mo»liwo±¢ wbudowania w swój program (biblioteka napisana w C++, licencja BSD) Elegancki mechanizm wykonywania zbudowanego kodu (JIT, jak niedost¦pne mo»e zawsze interpretowa¢) J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie Co to jest LLVM? Dlaczego moduªowy kompilator? Cechy LLVM Dodatkowe elementy Clang - kompilator C, C++ i Objective-C LLDB - debugger Klee - narz¦dzie symbolicznie ewaluuj¡ce kod (potra wykry¢ wszystkie mo»liwe wyniki dziaªania programu) vmkit - maszyna wirtualna Java libc++, compiler-rt - biblioteki standardowe C++ oraz pomocnicze funkcje kompilatora (jak libgcc) J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie Format LLVM IR Bloki podstawowe SSA Format LLVM IR LLVM IR jest formatem opisuj¡cym moduª kompilacji (podobnie jak plik '.o'). binarna (.bc - bitcode) tekstowa (.ll) Obie formy s¡ równowa»ne. LLVM zawiera narz¦dzia do konwersji mi¦dzy tymi formatami. Narz¦dzia LLVM oczekuj¡ zazwyczaj bitcode. LLVM IR zawiera funkcje, zmienne globalne, staªe oraz deklaracje. J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie Format LLVM IR Bloki podstawowe SSA Bloki podstawowe LLVM IR zawiera funkcje które skªadaj¡ si¦ z jednego lub wi¦cej bloków podstawowych. Bloki podstawowe to jednostki kodu zawieraj¡ce instrukcje, które zawsze s¡ zako«czone specjaln¡ instrukcj¡ (terminatorem) - przenosz¡c¡ sterowanie do innego bloku (powrót z funkcji, skok do innego bloku, wyrzucenie wyj¡tku). Instrukcje w LLVM IR s¡ statycznie silnie typowane J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie Format LLVM IR Bloki podstawowe SSA Przykªad bloku podstawowego C: #include <stdio.h> void wypisz_2_liczby(int n) { printf("%d %d\n",n,n+1); } LLVM IR: @.str = private constant [7 x i8] c"%d %d\0A\00" dene void @wypisz_2_liczby(i32 %n) nounwind { %1 = add nsw i32 %n, 1 %2 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([7 x i8]* @.str, i64 0, i64 0), i32 %n, i32 %1) nounwind ret void } J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie Format LLVM IR Bloki podstawowe SSA SSA SSA (Single Static Assignment) to wªasno±¢ postaci po±redniej polegaj¡ca na istnieniu dokªadnie jednego miejsca w kodzie gdzie dana zmienna jest ustawiana. Warto±ci zmiennych nie mog¡ wi¦c by¢ zmieniane. LLVM IR posiada wªasno±¢ SSA Aby wykona¢ tak¡ konstrukcj¦ jak p¦tla czy operator ?: (x?y:z) niezb¦dna jest dodatkowa instrukcja - phi Instrukcja phi zwraca warto±¢ zale»n¡ od miejsca z którego przyszªo sterowanie do bloku podstawowego w którym instrukcja ta si¦ znajduje. J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie Format LLVM IR Bloki podstawowe SSA Przykªad SSA void entry(int val) { if(val) tak(); else nie(); } %0: %1 = icmp eq i32 %val, 0 br i1 %1, label %3, label %2 T F %3: %2: tail call void (...)* @nie() nounwind br label %4 tail call void (...)* @tak() nounwind br label %4 %4: ret void CFG for ’entry’ function J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie Format LLVM IR Bloki podstawowe SSA Przykªad PHI %0: %1 = icmp eq i32 %n, 1 br i1 %1, label %14, label %2 int collatz(int n) { if(n==1) T F return 0; %2: return collatz( %14: (n%2) ? ret i32 0 (3*n+1) : %3 = and i32 %n, 1 %4 = icmp eq i32 %3, 0 br i1 %4, label %8, label %5 T F (n/2) ) + 1; %5: %8: %9 = sdiv i32 %n, 2 br label %10 } %6 = mul nsw i32 %n, 3 %7 = add nsw i32 %6, 1 br label %10 %10: %11 = phi i32 [ %7, %5 ], [ %9, %8 ] %12 = tail call i32 @_collatz(i32 %11) nounwind %13 = add nsw i32 %12, 1 ret i32 %13 CFG for ’collatz’ function J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie U»yte narz¦dzia Przykªad generowania funkcji Kompilacja JIT Kompilacja AOT U»yte narz¦dzia py-llvm - wi¡zania LLVM do j¦zyka Python opt (cz¦±¢ LLVM) - optymalizacja kodu LLVM, dodatkowe przebiegi informacyjne llvm-ld (cz¦±¢ LLVM) - linker llvm-dis (cz¦±¢ LLVM) - disassembler (przej±cie z LLVM IR w formie binarnej do tekstowej) J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie U»yte narz¦dzia Przykªad generowania funkcji Kompilacja JIT Kompilacja AOT Kod LLVM który chcemy uzyska¢ Jest to moduª zawieraj¡cy jedn¡ funkcj¦ (kwadratuj) przyjmuj¡c¡ jeden argument typu double i zwracaj¡c¡ kwadrat tego argumentu ; ModuleID = 'my_module' dene double @kwadratuj(double %x) { entry: %0 = fmul double %x, %x ret double %0 } J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie U»yte narz¦dzia Przykªad generowania funkcji Kompilacja JIT Kompilacja AOT Kod tworz¡cy funkcj¦ # ªaduj biblioteki LLVM from llvm import * from llvm.core import * # utwórz moduª module = Module.new('my_module') # funkcja zwracaj¡ca kwadrat swojego argumentu # zwraca double, przyjmuje jeden double ty_double = Type.double() # typ double ty_func = Type.function(ty_double, [ty_double]) # typ funkcji func = module.add_function(ty_func, 'kwadratuj') func.args[0].name = 'x' # nazwa argumentu J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie U»yte narz¦dzia Przykªad generowania funkcji Kompilacja JIT Kompilacja AOT Kod tworz¡cy funkcj¦ (cd.) # zbuduj blok podstawowy entry = func.append_basic_block('entry') builder = Builder.new(entry) # buduje instrukcje mno»enia pierwszego argumentu przez siebie v_kwadrat = builder.fmul(func.args[0], func.args[0]) # zwraca wynik w zmiennej zawieraj¡cej wynik mno»enia builder.ret(v_kwadrat) # wypisz tekstow¡ reprezentacj¦ moduªu print module Wynikiem wykonania programu jest kod LLVM IR przedstawiony na wcze±niejszym slajdzie J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie U»yte narz¦dzia Przykªad generowania funkcji Kompilacja JIT Kompilacja AOT Kompilacja just-in-time from llvm.ee import * # utwórz obiekt kompiluj¡cy JIT moduª ee = ExecutionEngine.new(func.module) for i in xrange(0,10): # dla i=0,1,..,9 # opakuj argument arg = GenericValue.real(ty_double, oat(i)) # uruchom funkcj¦, odpakuj wynik rv = ee.run_function(func, [arg]).as_real(ty_double) # wypisz wynik print 'i=', i, ' i*i=', rv Program ten pokazuje jak ªatwo mo»na wygenerowa¢ kod maszynowy i uruchomi¢ go wewn¡trz swojego programu J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie U»yte narz¦dzia Przykªad generowania funkcji Kompilacja JIT Kompilacja AOT Kompilacja ahead-of-time Poprzedni przykªad mo»na rozszerzy¢ o zapis moduªu do pliku: # zapisz bitcode do pliku with le('przyklad-kwadrator.o','wb') as fbc: module.to_bitcode(fbc) Kod wygenerowany w LLVM mo»na tak»e skompilowa¢ do wolno stoj¡cej formy (natywnego pliku wykonywalnego). Aby skompilowa¢ pliki LLVM IR modul1.o i modul2.o do kodu wynikowego program.exe wystarczy polecenie: llvm-ld -native -o program.exe modul1.o modul2.o J. Lamecki Low Level Virtual Machine Wprowadzenie LLVM IR - posta¢ po±rednia LLVM jako biblioteka Podsumowanie Podsumowanie Podsumowanie Kompilatory s¡ coraz cz¦±ciej fragmentem wi¦kszych zastosowa« Tworzenie kompilowanych j¦zyków programowania jest do±¢ proste przy u»yciu odpowiednich narz¦dzi A przede wszystkim: Fakt Nie ma czego si¦ ba¢! J. Lamecki Low Level Virtual Machine Appendix Dalsze informacje Dalsze informacje Strona gªówna projektu http://llvm.org/ LLVM and Clang: Advancing Compiler Technology http://llvm.org/pubs/2011-02-FOSDEMLLVMAndClang.html Kaleidoscope: Implementing a Language with LLVM http://llvm.org/docs/tutorial/ J. Lamecki Low Level Virtual Machine