Differences

This shows you the differences between two versions of the page.

Link to this comparison view

cpl:labs:04 [2015/10/25 20:24]
laura.vasilescu [Tool-uri pentru lucrul cu IR-ul]
cpl:labs:04 [2016/10/22 18:24] (current)
bogdan.nitulescu [04. Introduction to LLVM]
Line 5: 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 23: Line 24:
 </​code>​ </​code>​
  
-Observați utilizarea flag-urilor ''​-S'',​ ca atunci când dorim obținerea unui fișier ​similar cu cel al unui limbaj de asamblare, și ''​-c'',​ ca atunci când dorim obținerea unui fișier binar, similar ​cu un fișier ​obiect. Pentru conversia între cele 2 reprezentări se pot folosi tool-urile ''​llvm-as''​ și ''​llvm-dis''​. ​Coincidența nu este întâmplătoare,​ întrucât IR-ul este foarte asemănător unui limbaj de asamblare.+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. 
 + 
 +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>​ 
  
 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.
Line 31: Line 46:
 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''​).
  
-**Control flow graph**-ul poate fi vizualizat sub forma unui fișier ''​DOT''​. Pentru obținerea fișierelor,​ se poate utiliza utilitarul ''​opt'':​+**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'':​
 <code bash> <code bash>
 opt -dot-cfg yourfile.ll opt -dot-cfg yourfile.ll
 </​code>​ </​code>​
-Rezultatul rulării va consta în cate un fișier ''​DOT''​ pentru fiecare funcție din modul (''​cfg.f.dot'',​ ''​cfg.g.dot''​ etc). Pentru a vizualiza fișierele ​pe mașina virtuală puteți instala pachetul ''​xdot'':​+Rezultatul rulării va consta în câte un fișier ''​DOT''​ pentru fiecare funcție din modul (''​cfg.f.dot'',​ ''​cfg.g.dot''​ etc). Pentru a vizualiza fișierele ​în mașina virtuală puteți instala pachetul ''​xdot'':​
 <code bash> <code bash>
 sudo apt-get install xdot sudo apt-get install xdot
Line 41: Line 58:
 </​code>​ </​code>​
  
-Fiecare nod din graful plotat de ''​xdot''​ reprezintă un basic block, în timp ce arcele reprezintă posibile căi de execuție. Fiecare nod va conține secvența de instrucțiuni corepunzătoare basic block-ului pe care îl reprezintă. O descriere completă a tuturor instrucțiunilor din IR-ul de LLVM se găsește [[http://​llvm.org/​docs/​LangRef.html|aici]]. Majoritatea instrucțiunilor sunt destul de intuitive: **add**, **sub**, **mul**, **fadd**, **fsub**, **fmul** etc pentru operații aritmetice, **load** și **store** pentru citiri și scrieri din memorie, **icmp** și **fcmp** pentru realizarea comparațiilor,​ și așa mai departe. Spre deosebire de limbajele de asamblare tradiționale,​ IR-ul de LLVM este tipat - fiecare valoare are un anumit tip și tipurile pe care se poate aplica o anumită operație sunt bine definite.+Fiecare nod din graful plotat de ''​xdot''​ reprezintă un basic block, în timp ce arcele reprezintă posibile căi de execuție. Fiecare nod va conține secvența de instrucțiuni corepunzătoare basic block-ului pe care îl reprezintă. O descriere completă a tuturor instrucțiunilor din IR-ul de LLVM se găsește [[http://​llvm.org/​docs/​LangRef.html|aici]]. Majoritatea instrucțiunilor sunt destul de intuitive: **add**, **sub**, **mul**, **fadd**, **fsub**, **fmul** etc pentru operații aritmetice, **load** și **store** pentru citiri și scrieri din memorie, **icmp** și **fcmp** pentru realizarea comparațiilor,​ și așa mai departe. Spre deosebire de limbajele de asamblare tradiționale,​ IR-ul de LLVM are noțiunea de tipuri de date - fiecare valoare are un anumit tip și tipurile pe care se poate aplica o anumită operație sunt bine definite.
  
 ==== Sistemul de tipuri ==== ==== Sistemul de tipuri ====
Line 112: Line 129:
  
 <code C> <code C>
-a = x + y; 
 x = m * n; x = m * n;
 +a = x + y;
 +x = m + n;
 b = x + y; b = x + y;
 </​code>​ </​code>​
  
-La transformarea în formă SSA, vor exista două versiuni diferite ale variabilei ''​x''​ - una reprezentând valoarea de dinainte de atribuire, una reprezentând valoarea de după:+La transformarea în formă SSA, vor exista două versiuni diferite ale variabilei ''​x''​ - una reprezentând valoarea de după prima atribuire, una reprezentând valoarea de după cea de-a doua atribuire:
  
 <code C> <code C>
 +x_1 = m * n;
   a = x_1 + y;   a = x_1 + y;
-x_2 =   ​n;+x_2 = m n;
   b = x_2 + y;   b = x_2 + y;
 </​code>​ </​code>​
Line 158: Line 177:
 if.else: if.else:
   %x.2 = add i32 %m, %n   %x.2 = add i32 %m, %n
-  br label %if.else+  br label %if.end
  
 if.end: if.end:
Line 174: Line 193:
 ======= Exerciții de laborator (10p) ======= ======= Exerciții de laborator (10p) =======
  
-În rezolvarea laboratorului folosiți arhiva de sarcini ​[[TODO | lab04-tasks.zip]]+În rezolvarea laboratorului folosiți arhiva de sarcini ​{{ :cpl:labs:lab04-tasks.zip ​}}
  
 ===== Exercițiul 1 - Control flow (1p) ===== ===== Exercițiul 1 - Control flow (1p) =====
Line 209: Line 228:
  
 ===== BONUS ===== ===== BONUS =====
-=== 1 cpl karma - Clase ===+=== Clase ===
 Intrați în directorul ''​7-classes''​ și inspectați fișierul ''​classes.cpp''​. Cum credeți că va arăta definiția lui ''​A''?​ Dar a lui ''​B''?​ Cum va diferenția compilatorul între cele 2 metode ''​g''​ ale lui ''​B''?​ Intrați în directorul ''​7-classes''​ și inspectați fișierul ''​classes.cpp''​. Cum credeți că va arăta definiția lui ''​A''?​ Dar a lui ''​B''?​ Cum va diferenția compilatorul între cele 2 metode ''​g''​ ale lui ''​B''?​
  
 Rulați ''​make classes.ll''​ și inspectați fișierul produs. ​ Rulați ''​make classes.ll''​ și inspectați fișierul produs. ​
  
-=== 1 cpl karma - Metode virtuale ===+=== Metode virtuale ===
 Intrați în directorul ''​8-virtual''​ și inspectați fișierul ''​classes.cpp''​. Cum credeți că vor arăta definițiile claselor ''​A''​ și ''​B''​ în acest caz? Ce metode se vor apela și cum pe obiectele de tip ''​A''​ și ''​B''​ în cadrul funcției ''​val''?​ Dar în cadrul funcției ''​ref''?​ De ce? Intrați în directorul ''​8-virtual''​ și inspectați fișierul ''​classes.cpp''​. Cum credeți că vor arăta definițiile claselor ''​A''​ și ''​B''​ în acest caz? Ce metode se vor apela și cum pe obiectele de tip ''​A''​ și ''​B''​ în cadrul funcției ''​val''?​ Dar în cadrul funcției ''​ref''?​ De ce?
  
cpl/labs/04.1445797490.txt.gz · Last modified: 2015/10/25 20:24 by laura.vasilescu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0