This shows you the differences between two versions of the page.
cpl:labs:04 [2016/10/22 17:27] bogdan.nitulescu [Tool-uri pentru lucrul cu IR-ul] |
cpl:labs:04 [2016/10/22 18:24] (current) bogdan.nitulescu [04. Introduction to LLVM] |
||
---|---|---|---|
Line 1: | Line 1: | ||
===== 04. Introduction to LLVM ===== | ===== 04. Introduction to LLVM ===== | ||
- | |||
- | **TO BE UPDATED SOON** | ||
LLVM conține o serie de biblioteci și utilitare care pot fi folosite pentru a construi compilatoare, interpretoare și alte tool-uri similare. Găsiți [[http://adriansampson.net/blog/llvm.html|aici]] o introducere și câteva exemple interesante de utilizare a LLVM-ului. Pentru și mai multe exemple, există o [[http://llvm.org/ProjectsWithLLVM/|pagină cu proiecte]] care folosesc LLVM. | LLVM conține o serie de biblioteci și utilitare care pot fi folosite pentru a construi compilatoare, interpretoare și alte tool-uri similare. Găsiți [[http://adriansampson.net/blog/llvm.html|aici]] o introducere și câteva exemple interesante de utilizare a LLVM-ului. Pentru și mai multe exemple, există o [[http://llvm.org/ProjectsWithLLVM/|pagină cu proiecte]] care folosesc LLVM. | ||
Line 7: | Line 5: | ||
Printre cele mai importante componente ale LLVM se află engine-ul de optimizări independente de platformă și de limbaj. Acesta lucrează cu o reprezentare intermediară a programelor, pe care o vom prezenta în cadrul acestui laborator. Această reprezentare este de asemenea liantul între front-end-uri (precum Clang pentru C/C++/Objective-C) și back-end-uri (în prezent, LLVM are back-end-uri pentru x86, ARM, PowerPC, MIPS, Sparc etc). | Printre cele mai importante componente ale LLVM se află engine-ul de optimizări independente de platformă și de limbaj. Acesta lucrează cu o reprezentare intermediară a programelor, pe care o vom prezenta în cadrul acestui laborator. Această reprezentare este de asemenea liantul între front-end-uri (precum Clang pentru C/C++/Objective-C) și back-end-uri (în prezent, LLVM are back-end-uri pentru x86, ARM, PowerPC, MIPS, Sparc etc). | ||
+ | Pentru a instala LLVM pe un sistem Linux aveți nevoie de pachetele ''llvm'' pentru a folosi tool-urile, ''llvm-dev'' pentru a putea folosi bibliotecile, ''clang'' pentru front-end-ul C/C++ . | ||
===== Reprezentarea intermediară a LLVM (LLVM IR) ===== | ===== Reprezentarea intermediară a LLVM (LLVM IR) ===== | ||
Reprezentarea intermediară a LLVM-ului are 3 forme: | Reprezentarea intermediară a LLVM-ului are 3 forme: | ||
Line 25: | Line 24: | ||
</code> | </code> | ||
- | Observați utilizarea flag-urilor ''-S'', ca atunci când dorim obținerea unui fișier în limbaj de asamblare, și ''-c'', ca atunci când dorim obținerea unui fișier obiect, urmate de ''-emit-llvm'' pentru a obține IR (fie în forma textuală, asemănătoare unui limbaj de asamblare, fie în forma binară, similară unui format obiect). Pentru conversia între cele 2 reprezentări se pot folosi tool-urile ''llvm-as'' și ''llvm-dis'': | + | Observați utilizarea flag-urilor ''-S'', ca atunci când dorim obținerea unui fișier în limbaj de asamblare, și ''-c'', ca atunci când dorim obținerea unui fișier obiect, urmate de ''-emit-llvm'' pentru a obține IR (fie în forma textuală, asemănătoare unui limbaj de asamblare, fie în forma binară, similară unui format obiect). Fără flagul ''-emit-llvm'', clang va general cod asamblare sau cod obiect nativ, la fel ca orice alt compilator, de exemplu gcc. |
- | <code bash> | + | |
+ | Pentru conversia între cele 2 reprezentări se pot folosi tool-urile ''llvm-as'' și ''llvm-dis'': | ||
+ | |||
+ | <code bash> | ||
+ | llvm-as yourfile.ll -o yourfile.bc | ||
+ | llvm-dis yourfile.bc -o yourfile.ll | ||
</code> | </code> | ||
+ | |||
Alte utilitare care merită menționate sunt ''opt'', care reprezintă o interfață către engine-ul de optimizări (primește ca input fișiere IR și scoate tot fișiere IR), ''llc'', care poate compila un fișier IR pentru o anumită arhitectură (primește un fișier IR și produce un fișier în limbaj de asamblare sau un fișier obiect), și ''lli'', care poate interpreta un fișier IR (primește un fișier IR și produce rezultatele rulării programului respectiv pe platforma curentă). Mai multe informații despre utilitarele din suita LLVM găsiți [[http://llvm.org/docs/CommandGuide/|aici]]. | Alte utilitare care merită menționate sunt ''opt'', care reprezintă o interfață către engine-ul de optimizări (primește ca input fișiere IR și scoate tot fișiere IR), ''llc'', care poate compila un fișier IR pentru o anumită arhitectură (primește un fișier IR și produce un fișier în limbaj de asamblare sau un fișier obiect), și ''lli'', care poate interpreta un fișier IR (primește un fișier IR și produce rezultatele rulării programului respectiv pe platforma curentă). Mai multe informații despre utilitarele din suita LLVM găsiți [[http://llvm.org/docs/CommandGuide/|aici]]. | ||
+ | |||
+ | <code bash> | ||
+ | lli yourfile.ll # Interpretează IR-ul | ||
+ | llc yourfile.ll -o yourfile.s # Genereaza un fișier în limbajul de asamblare nativ | ||
+ | </code> | ||
+ | |||
===== Organizarea IR-ului ===== | ===== Organizarea IR-ului ===== | ||
În general, fiecare fișier ''.ll'' sau ''.bc'' va conține un **modul** alcătuit din mai multe declarații de funcții, variabile globale, tipuri etc. | În general, fiecare fișier ''.ll'' sau ''.bc'' va conține un **modul** alcătuit din mai multe declarații de funcții, variabile globale, tipuri etc. | ||
IR-ul de LLVM pentru fiecare funcție este organizat sub forma unui **control flow graph**, alcătuit din basic block-uri. Un **basic block** este o secvență de instrucțiuni neîntreruptă de transferuri de control. Transferurile de control se realizează prin intermediul unor instrucțiuni de tip ''branch'', ''return'', ''switch'' etc (cunoscute sub numele de ''terminators''). | IR-ul de LLVM pentru fiecare funcție este organizat sub forma unui **control flow graph**, alcătuit din basic block-uri. Un **basic block** este o secvență de instrucțiuni neîntreruptă de transferuri de control. Transferurile de control se realizează prin intermediul unor instrucțiuni de tip ''branch'', ''return'', ''switch'' etc (cunoscute sub numele de ''terminators''). | ||
+ | |||
+ | **Atenție!** In LLVM, ultima instrucțiune din fiecare basic block trebuie neapărat să fie un terminator. | ||
**Control flow graph**-ul poate fi vizualizat grafic sub forma unui fișier ''DOT''. Pentru obținerea fișierelor, se poate utiliza utilitarul ''opt'': | **Control flow graph**-ul poate fi vizualizat grafic sub forma unui fișier ''DOT''. Pentru obținerea fișierelor, se poate utiliza utilitarul ''opt'': |