Differences

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

Link to this comparison view

cpl:labs:04 [2015/10/26 11:17]
diana.vasile [Instrucțiuni] Clarify example
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.
  
 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'':​
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 160: 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 176: 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 211: 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.1445851065.txt.gz · Last modified: 2015/10/26 11:17 by diana.vasile
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