Download
konstrukce p eklada n.
Skip this Video
Loading SlideShow in 5 Seconds..
Konstrukce p řekladačů PowerPoint Presentation
Download Presentation
Konstrukce p řekladačů

Konstrukce p řekladačů

105 Vues Download Presentation
Télécharger la présentation

Konstrukce p řekladačů

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

  1. Konstrukce překladačů David Bednárek www.ksi.mff.cuni.cz

  2. Pravidla studia SWI109 2/1 Z,Zk

  3. Pravidla studia • Cvičení • Každých 14 dní • Zápis v SIS • Zápočtové testy • Hromadný termín na cvičení koncem semestru • Opravné termíny individuálně ve zkušebních termínech • Alternativa: Implementace části překladače • Podle zadání ze šk.r. 2010/11 • Přednáška • Zkouška - písemná

  4. Literatura

  5. Literatura • A.V. Aho, R. Sethi, J.D. UllmanCompiler: Principles, Techniques and Tools (1986) • Grune, Bal, Jacobs, LangendoenModern Compiler Design (2000) • Přehled včetně front-endů a překladu neprocedurálních jazyků • Steven S. MuchnickAdvanced Compiler Design and Implementation (1997) • Přehled optimalizací v back-endech • Randy Allen, Ken KennedyOptimizing Compilers for Modern Architectures (2001) • Hardwarově závislé optimalizace • R. MorganBuilding an Optimized Compiler (1998) • Srikant, Shankar (eds.)The Compiler Design Handbook (2003)– Optimizations and Machine Code Generation • Sbírka 22 článků • J. R. LevineLinkers and Loaders (1999)

  6. Architektura překladače

  7. Architektura překladače • Amatérský pohled Lexikální analyzátor Posloupnost tokenů Parser Derivační strom Sémantický analyzátor Derivační strom Derivační strom Generátor kódu Cílový kód

  8. Architektura překladače • Z velké dálky front-end závislý na vstupním jazyku back-end závislý na cílovém stroji Lexikální analyzátor Posloupnost tokenů Parser Generátor kódu Derivační strom Mezikód Cílový kód Sémantický analyzátor Derivační strom Derivační strom Generátor mezikódu

  9. Architektura překladače • S optimalizacemi front-end závislý na vstupním jazyku back-end závislý na cílovém stroji Lexikální analyzátor Optimalizace Posloupnost tokenů Mezikód (střední úrovně) Parser Strojově závislé optimalizace Mezikód (střední úrovně) Derivační strom Mezikód (střední úrovně) Sémantický analyzátor Generátor kódu Derivační strom Derivační strom Mezikód nízké úrovně Optimalizace Strojově závislé optimalizace Derivační strom Cílový kód Generátor mezikódu

  10. Architektura překladače • Detailní pohled akademika (pouze optimalizace) • Muchnick: Advanced Compiler Design and Implementation Scalar replacement of array references Data-cache optimizations Constant folding Algebraic simplification and reassociation Procedure integration Tail-call optimization Scalar replacement of aggregates Sparse conditional constant propagation Interprocedural constant propagation Procedure specialization and cloning Sparse conditional constant propagation In-line expansion Leaf-routine optimization Shrink wrapping Machine idioms Tail merging Branch optimizations and conditional moves Dead-code elimination Software pipelining, loop unrolling Basic-block and branch scheduling Register allocation Basic-block and branch scheduling Intraprocedural I-cache optimization Instruction prefetching Data prefetching Branch prediction Global value numbering Local and global copy propagation Sparse conditional constant propagation Dead-code elimination Local and global common-subexpression elimination Loop-invariant code motion Dead-code elimination Code hoisting Induction-variable strength reduction Linear-function test replacement Induction-variable removal Unnecessary bounds-checking elimination Control-flow optimizations Interprocedural register allocation Aggregation of global references Interprocedural I-cache optimization

  11. Architektura překladače • Realita • GNUCompilerCollectionInternals Enter static single assignment form Warn for uninitialized variables Dead code elimination Dominator optimizations Redundant phi elimination Forward propagation of single-use variables Copy renaming PHI node optimizations May-alias optimization Profiling Lower complex arithmetic Scalar replacement of aggregates Dead store elimination Tail recursionelimination Forward store motion Partial redundancy elimination Loop invariant motion Canonical induction variable creation Induction variable optimizations Loop unswitching Vectorization Tree level if-conversion for vectorizer Conditional constant propagation Folding builtin functions Split critical edges Partial redundancy elimination Control dependence dead code elimination Tail call elimination Warn for function return without value Mudflap statement annotation Leave static single assignment form RTL generation Generate exception handling landing pads Cleanup control flow graph Common subexpression elimination Global common subexpression elimination. Loop optimization Jump bypassing If conversion Web construction Life analysis Instruction combination Register movement Optimize mode switching Modulo scheduling Instruction scheduling Register class preferencing Local register allocation Global register allocation Reloading Basic block reordering Variable tracking Delayed branch scheduling Branch shortening Register-to-stack conversion Final Debugging information output Remove useless statements Mudflap declaration registration Lower control flow Lower exception handling control flow Build the control flow graph Find all referenced variables

  12. Názvosloví

  13. Základní bloky • Procedura • Procedura nebo funkce • Call graph • Graf (možného) volání mezi procedurami • Základní blok (BB – basic block) • Část procedury bez větvení a smyček, se vstupem pouze na začátku a výstupem pouze na konci • Volání procedury může a nemusí být považováno za předěl BB • Tok řízení - control-flow (graph) • Možnosti předávání řízení mezi základními bloky v proceduře • Reprezentováno orientovaným (cyklickým) grafem • Tok dat - data-flow • Předávání dat, obvykle uvnitř jednoho základního bloku • Pro jeden BB může být reprezentováno dagem

  14. Dag • Závislost (dependence) • Povinnost provést jednu operaci/instrukci po jiné • Částečné uspořádání operací/instrukcí v jednom BB • Datová závislost (dependence) • Závislost producent-konzument v toku dat • Antidependence • Read-Write: Čtení se musí stihnout před zápisem • Write-Write: Pořadí zápisů se nesmí změnit • Jiné důvody, obvykle nízkoúrovňového původu • Dag (directed acyclic graph) • Orientovaný acyklický graf použitý pro zaznamenání • data-flow • závislostí

  15. Typy • Skalární/jednoduchý/atomický typ (scalar) • Typ, s nímž dokáže přímo pracovat cílový stroj • Složený typ (aggregate) • Pole, struktura, třída, řetězec apod. • Zarovnání (alignment) • Požadavek na umístění proměnné/paměťového místa na adrese dělitelné 2, 4, 8, nebo 16 • Striktní: Při nedodržení procesor vyvolá výjimku • Optimalizační: Při nedodržení bude kód pomalejší

  16. Proměnné • Proměnná (variable) • Proměnná deklarovaná ve vstupním jazyce, včetně parametrů • Pomocná proměnná (temporary) vytvořená překladačem • Statická/globální proměnná • Proměnná s jedinou instancí přístupná všem procedurám • (Lokální) proměnná • Parametr, deklarovaná či pomocná proměnná přístupná pouze jedné proceduře • Jazyky s vnořenými procedurami vyžadují další kategorii proměnných přístupných z vnořených procedur • Paměťové místo • Část proměnné nebo dynamicky alokované paměti

  17. Alias • Alias • Situace (nebo možnost výskytu situace), kdy k jedné proměnné, její části, či paměťovému místu, vedou dvě různé přistupové cesty • int x; int a[ 20]; • int * p = & x; a[ i] = ...; • a[ j] = ...; • Rozhodnutí, zda může jít o alias, je obecně algoritmicky neřešitelná úloha • Pokud si překladač není jist, že o alias nejde, musí se chovat, jako by to alias byl • Nejistý alias je ještě horší, než jistý • Proměnná bez aliasu • Lokální proměnná, která prokazatelně nemá alias • Všechny přístupy k ní lze jednoznačně určit

  18. Live range • Doba života/rozsah platnosti proměnné (live range) • Množina míst v proceduře, kdy je proměnná zapotřebí • Tedy existuje možnost, že by ještě byla čtena (před zápisem) • Zkoumá se obvykle pouze pro skalární lokální proměnné bez aliasu • Variable splitting/renaming • Proměnnou s nesouvislým rozsahem platnosti lze nahradit několika jinými • Odpadne omezení na shodnou alokaci v jednotlivých souvislých oblastích rozsahu platnosti

  19. Alokace – přidělování místa • Statická alokace (static allocation) • Pro statické proměnné • Vyhrazení místa na „pevné“ adrese • Podléhá relokaci při spojování linkerem a zavádění loaderem • Registrová alokace (register allocation) • Pro skalární lokální proměnné bez aliasu • Umístění do fyzického registru cílového stroje • Pouze po dobu života proměnné • Omezeno počtem fyzických registrů • Zásobníková alokace (stack allocation) • Umístění na zásobníku • Zásobník může být definován procesorem nebo emulován • Složené nebo aliasované lokální proměnné • Proměnné, které se nevešly do registrů • Spill-code • Kód „navíc“, který musel být přidán pro manipulaci s proměnnými, které se nevešly do registrů

  20. Volací konvence • Volací konvence • Úmluva o způsobu spolupráce volající a volané procedury • Definována cílovým prostředím nebo autorem překladače • Umístění parametrů • Zásobník nebo registry • Pořadí • Přesné umístění je komplikováno zarovnáním • Umístění návratové hodnoty • Obvykle registr • Složené typy se obvykle řeší jako parametry předávané odkazem • Odpovědnost za úklid zásobníku • Volající/volaný • Povinnost zachovat obsah registrů • Všechny, některé, nebo žádné • Další technické definice • Úprava jména procedury jako symbolu pro linker • Pokročilá interprocedurální optimalizace: Automatická úprava volací konvence podle místních podmínek volaného a všech volajících

  21. Činnost překladače, optimalizace • Intraprocedurální • Uvnitř jedné procedury • Lokální • Uvnitř jednoho základního bloku • Příklad: Jednodušší verze schedulingu nebo CSE • Globální • Pro celou proceduru najednou • Příklad: Přidělování registrů, složitější CSE • Interprocedurální • Pro celý program najednou • Při separátním překladu modulů je součástí linkeru • Obvykle exponenciální nebo algoritmicky neřešitelné úlohy • Příklad: Interprocedurální analýza aliasů • Srovnání: In-line expanze procedury patří formálně mezi intraprocedurální optimalizace

  22. Typy • Logický typ • Datový typ definovaný vstupním jazykem • Základní typy + typové konstrukce • Neomezená množina typů • Fyzický typ • Typ rozeznávaný cílovým strojem • Konečná množina vestavěných typů • Celá čísla několika velikostí (znaménková a bezznaménková) • Ukazatel (pokud nesplývá s celým číslem) • Reálná čísla několika velikostí/přesností • Na ostatní typy se pohlíží jako na posloupnost bajtů • Rozhoduje délka, případně požadavek na zarovnání

  23. Mezikódy • Vysokoúrovňový mezikód • Reprezentace vstupního programu • Během fází, řešících konstrukce a pravidla vstupního jazyka • Užívá logické typy a operace vstupního jazyka • Nejčastěji ve formě anotovaného AST (abstract syntax tree) • Derivační strom podle abstraktní gramatiky • Mezikód střední úrovně • Nejčastější hranice mezi front- a back-endem • Na vstupním jazyce nezávislá reprezentace • Užívá fyzické typy a operace na nich • Nejčastěji ve formě čtveřic • Tříadresové pseudoinstrukce, pomocné proměnné • Někdy ve speciálních formách (SSA – static single assignment) • Control-flow může být ve formě grafu BB (základních bloků) • Nízkoúrovňový mezikód • Ekvivalent strojových instrukcí • Nekompaktní forma, symbolické a relokované operandy • Před alokací registrů forma s neomezeným počtem virtuálních registrů • Někdy v univerzální strojově nezávislé formě (GCC RTL)

  24. Mezikódy

  25. Mezikódy • Informace uložené v mezikódu střední úrovně • Seznam globálních proměnných • Další globální informace pro generovaný kód • Seznam procedur • Další informace pro debugger

  26. Mezikódy • Informace uložené v mezikódu střední úrovně • Seznam globálních proměnných • Velikost • Inicializace • Příznak konstantnosti • Jméno (pro linker) • Logický typ (pro debugger) • Další globální informace pro generovaný kód • Konstanty (reálné, řetězcové, strukturované) • Tabulky virtuálních funkcí, RTTI • Často splývají s globálními proměnnými • Seznam procedur • Další informace pro debugger • Jména a konstrukce typů

  27. Mezikódy • Popis procedury • Jméno (pro linker a chybová hlášení) • Seznam parametrů • Fyzický typ (+ velikost) • Umístění podle volací konvence • Jméno (pro debugger a chybová hlášení) • Logický typ (pro debugger a určení aliasů) • Seznam lokálních proměnných • Fyzický typ (+ velikost) • Jméno (pro debugger a chybová hlášení) • Logický typ (pro debugger a určení aliasů) • Proměnné ve vnořených blocích se obvykle povyšují na úroveň procedury • Kód procedury • Další informace (popisy výjimek apod.)

  28. Mezikódy • Kód procedury • Plně sekvenční forma • Posloupnost (pseudo-)instrukcí virtuálního stroje • Tok řízení popsán skokovými instrukcemi • Částečně sekvenční forma • Tok řízení popsán grafem, jehož uzly jsou základní bloky • Každý základní blok obsahuje posloupnost (pseudo-)instrukcí • Skokové instrukce pouze na konci BB nebo zaznamenány jinak • Nesekvenční forma • Tok řízení popsán grafem, jehož uzly jsou základní bloky • Tok dat uvnitř základního bloku popsán dagem • Různé formy podle stupně analýzy aliasů a rozsahů platnosti • Pokročilejší formy nahrazují lokální proměnné rozhraními bloků

  29. int gcd( int x, int y) { int z; if ( x > y ) { z = y; y = x; x = z; } while ( x > 0 ) { z = y % x; y = x; x = z; } return y; } CONST:(C1,I32,0) PROC ”gcd” PARAM:(Px,I32,”x”),(Py,I32,”y”) VAR:(Vz,I32,”z”) TMP:(T1,B),(T2,B),(T3,I32) ENTER GT_I32 T1,Px,Py JF T1,L1 MOV_I32 Vz,Py MOV_I32 Py,Px MOV_I32 Px,Vz L1: GT_I32 T2,Px,C1 JF T2,L2 MOD_I32 T3,Py,Px MOV_I32 Vz,T3 MOV_I32 Py,Px MOV_I32 Px,Vz JMP L1 L2: RET_I32 Py Plně sekvenční čtveřicový mezikód

  30. int gcd( int x, int y) { int z; if ( x > y ) { z = y; y = x; x = z; } while ( x > 0 ) { z = y % x; y = x; x = z; } return y; } CONST:(C1,I32,0) PROC ”gcd” PARAM:(Px,I32,”x”),(Py,I32,”y”) VAR:(Vz,I32,”z”) TMP:(T1,B),(T2,B),(T3,I32) Částečně sekvenční čtveřicový mezikód ENTER GT_I32 T1,Px,Py JC T1 MOV_I32 Vz,Py MOV_I32 Py,Px MOV_I32 Px,Vz MOD_I32 T3,Py,Px MOV_I32 Vz,T3 MOV_I32 Py,Px MOV_I32 Px,Vz GT_I32 T2,Px,C1 JC T2 RET_I32 Py

  31. int gcd( int x, int y) { int z; if ( x > y ) { z = y; y = x; x = z; } while ( x > 0 ) { z = y % x; y = x; x = z; } return y; } CONST:(C1,I32,0) PROC ”gcd” PARAM:(Px,I32,”x”),(Py,I32,”y”) VAR:(Vz,I32,”z”) Nesekvenční mezikód (před analýzou aliasů) Control-Flow vždy if true if false ENTER LD_I32(Px) LD_I32(Py) LD_I32(Py) GT_I32 ST_I32(Vz) JC Dag Data-flow Závislosti LD_I32(Px) ST_I32(Py) LD_I32(Vz) ST_I32(Px) LD_I32(Py) LD_I32(Px) MOD_I32 LD_I32(Px) ST_I32(Vz) GTC_I32(C1) LD_I32(Px) JC ST_I32(Py) LD_I32(Vz) ST_I32(Px) LD_I32(Py) RET_I32

  32. Mezikódy střední úrovně • Plně sekvenční forma • Částečně sekvenční forma • Nesekvenční forma • Všechny tyto formy lze generovat přímoz abstraktního syntaktického stromu • Jedním průchodem zdola nahoru • goto je nutné ošetřit dodatečnými zásahy (backpatching) • Strom nemusí fyzicky existovat,postačí průchod myšleným stromem • LR analýza: pravá derivace pozpátku • LL analýza rekurzivním sestupem • Většina front-endů přesto strom konstruuje • Složité konstrukce jazyka (šablony, předkompilované části) • Rozhraní mezi syntaktickým a sémantickým analyzátorem • Optimalizace

  33. Mezikódy střední úrovně • Plně sekvenční forma • Částečně sekvenční forma • Nesekvenční forma • Táž forma se obvykle v průběhu překladu upravuje • Připojují se odvozené informace a optimalizační rozhodnutí • Provádějí se ekvivalentní úpravy (optimalizace) • Jedna forma může mít různé variace • A to i uvnitř jednoho překladače • Odráží různé způsoby a/nebo různé stupně analýzy • Řada překladačů užívá dvě z těchto forem • Z historických důvodů (stabilita rozhraní front-end/back-end) • Pro vytvoření druhé formy je nutná analýza první formy

  34. CONST:(C1,I32,0) PROC ”gcd” PARAM:(Px,I32,”x”),(Py,I32,”y”) VAR:(Vz,I32,”z”) TMP:(T1,B),(T2,B),(T3,I32) ENTER GT_I32 T1,Px,Py JF T1,L1 MOV_I32 Vz,Py MOV_I32 Py,Px MOV_I32 Px,Vz L1: GT_I32 T2,Px,C1 JF T2,L2 MOD_I32 T3,Py,Px MOV_I32 Vz,T3 MOV_I32 Py,Px MOV_I32 Px,Vz JMP L1 L2: RET_I32 Py V sekvenčním mezikódu Základní blok Začíná Na začátku procedury V cíli skoku Za podmíněným skokem Končí Podmíněným skokem Nepodmíněným skokem Návratem z procedury Před cílem skoku Detekce základních bloků

  35. CONST:(C1,I32,0) PROC ”gcd” PARAM:(Px,I32,”x”),(Py,I32,”y”) VAR:(Vz,I32,”z”) TMP:(T1,B),(T2,B),(T3,I32) ENTER GT_I32 T1,Px,Py JF T1,L1 MOV_I32 Vz,Py MOV_I32 Py,Px MOV_I32 Px,Vz L1: GT_I32 T2,Px,C1 JF T2,L2 MOD_I32 T3,Py,Px MOV_I32 Vz,T3 MOV_I32 Py,Px MOV_I32 Px,Vz JMP L1 L2: RET_I32 Py CONST:(C1,I32,0) PROC ”gcd” PARAM:(Px,I32,”x”),(Py,I32,”y”) VAR:(Vz,I32,”z”) TMP:(T1,B),(T2,B),(T3,I32) Detekce základních bloků ENTER GT_I32 T1,Px,Py JC T1 MOV_I32 Vz,Py MOV_I32 Py,Px MOV_I32 Px,Vz MOD_I32 T3,Py,Px MOV_I32 Vz,T3 MOV_I32 Py,Px MOV_I32 Px,Vz GT_I32 T2,Px,C1 JC T2 RET_I32 Py

  36. int gcd( int x, int y) { int z; if ( x > y ) { z = y; y = x; x = z; } while ( x > 0 ) { z = y % x; y = x; x = z; } return y; } Ve zdrojovém kódu Základní blok Začíná Na začátku procedury Na začátku then a else bloku Na začátku těla cyklu Za if příkazem Za while cyklem Končí Na konci procedury Na konci then a else bloku Na konci těla cyklu Na konci podmínky v if Na konci podmínky ve while Příkazem return/break apod. Komplikace Zkrácené vyhodnocování booleovských výrazů Podmíněný výraz Příkaz goto Detekce základních bloků

  37. int gcd( int x, int y) { int z; if ( x > y ) { z = y; y = x; x = z; } while ( x > 0 ) { z = y % x; y = x; x = z; } return y; } CONST:(C1,I32,0) PROC ”gcd” PARAM:(Px,I32,”x”),(Py,I32,”y”) VAR:(Vz,I32,”z”) TMP:(T1,B),(T2,B),(T3,I32) Detekce základních bloků ENTER GT_I32 T1,Px,Py JC T1 MOV_I32 Vz,Py MOV_I32 Py,Px MOV_I32 Px,Vz MOD_I32 T3,Py,Px MOV_I32 Vz,T3 MOV_I32 Py,Px MOV_I32 Px,Vz GT_I32 T2,Px,C1 JC T2 RET_I32 Py

  38. int gcd( int x, int y) { int z; if ( x > y ) { z = y; y = x; x = z; } while ( x > 0 ) { z = y % x; y = x; x = z; } return y; } CONST:(C1,I32,0) PROC ”gcd” PARAM:(Px,I32,”x”),(Py,I32,”y”) VAR:(Vz,I32,”z”) Nesekvenční mezikód s hranicemi příkazů Control-Flow vždy if true if false ENTER LD_I32(Px) LD_I32(Py) LD_I32(Py) GT_I32 ST_I32(Vz) JC Dag operand LD_I32(Px) ST_I32(Py) LD_I32(Vz) ST_I32(Px) LD_I32(Py) LD_I32(Px) MOD_I32 LD_I32(Px) ST_I32(Vz) GTC_I32(C1) LD_I32(Px) JC ST_I32(Py) LD_I32(Vz) ST_I32(Px) LD_I32(Py) RET_I32

  39. int gcd( int x, int y) { int z; if ( x > y ) { z = y; y = x; x = z; } while ( x > 0 ) { z = y % x; y = x; x = z; } return y; } CONST:(C1,I32,0) PROC ”gcd” PARAM:(Px,I32,”x”),(Py,I32,”y”) VAR:(Vz,I32,”z”) Nesekvenční mezikód před analýzou aliasů Control-Flow vždy if true if false ENTER LD_I32(Px) LD_I32(Py) LD_I32(Py) GT_I32 ST_I32(Vz) JC LD_I32(Px) ST_I32(Py) LD_I32(Vz) ST_I32(Px) LD_I32(Py) LD_I32(Px) MOD_I32 LD_I32(Px) ST_I32(Vz) GTC_I32(C1) LD_I32(Px) JC ST_I32(Py) LD_I32(Vz) ST_I32(Px) LD_I32(Py) RET_I32 Dag operand pořadí

  40. Odstranění závislostí po analýze aliasů LD_I32(Py) LD_I32(Px) LD_I32(Py) LD_I32(Px) MOD_I32 MOD_I32 ST_I32(Vz) ST_I32(Vz) LD_I32(Px) ST_I32(Py) ST_I32(Py) LD_I32(Vz) LD_I32(Vz) ST_I32(Px) ST_I32(Px)

  41. Odstranění závislostí po analýze aliasů ENTER LD_I32(Px) LD_I32(Py) ENTER GT_I32 LD_I32(Px) LD_I32(Py) LD_I32(Py) JC GT_I32 ST_I32(Vz) JC LD_I32(Py) LD_I32(Px) LD_I32(Px) ST_I32(Py) ST_I32(Vz) ST_I32(Py) LD_I32(Vz) LD_I32(Vz) ST_I32(Px) ST_I32(Px) LD_I32(Py) LD_I32(Py) LD_I32(Px) LD_I32(Px) ST_I32(Py) MOD_I32 MOD_I32 LD_I32(Px) LD_I32(Px) ST_I32(Vz) ST_I32(Vz) GTC_I32(C1) GTC_I32(C1) LD_I32(Px) LD_I32(Vz) JC JC ST_I32(Px) ST_I32(Py) LD_I32(Vz) ST_I32(Px) LD_I32(Py) LD_I32(Py) RET_I32 RET_I32

  42. int gcd( int x, int y) { int z; if ( x > y ) { z = y; y = x; x = z; } while ( x > 0 ) { z = y % x; y = x; x = z; } return y; } CONST:(C1,I32,0) PROC ”gcd” PARAM:(Px,I32,”x”),(Py,I32,”y”) VAR:(Vz,I32,”z”) Nesekvenční mezikód po analýze aliasů Control-Flow vždy if true if false ENTER LD_I32(Px) LD_I32(Py) GT_I32 JC Dag dependence: operand w-r w-? antidependence: r-w ?-w LD_I32(Py) LD_I32(Px) ST_I32(Py) ST_I32(Vz) LD_I32(Vz) ST_I32(Px) LD_I32(Py) LD_I32(Px) ST_I32(Py) MOD_I32 LD_I32(Px) ST_I32(Vz) GTC_I32(C1) LD_I32(Vz) JC ST_I32(Px) LD_I32(Py) RET_I32

  43. int gcd( int x, int y) { int z; if ( x > y ) { z = y; y = x; x = z; } while ( x > 0 ) { z = y % x; y = x; x = z; } return y; } CONST:(C1,I32,0) PROC ”gcd” PARAM:(Px,I32,”x”),(Py,I32,”y”) VAR:(Vz,I32,”z”) Nesekvenční mezikód s rozsahy platnosti ENTER LD_I32(Px) LD_I32(Py) GT_I32 JC Dag operand antidependence: r-w LD_I32(Py) LD_I32(Px) ST_I32(Py) ST_I32(Vz) LD_I32(Vz) ST_I32(Px) LD_I32(Py) LD_I32(Px) ST_I32(Py) MOD_I32 LD_I32(Px) ST_I32(Vz) GTC_I32(C1) LD_I32(Vz) JC ST_I32(Px) LD_I32(Py) RET_I32 Oblasti platnosti Px Py Vz/1 Vz/2

  44. Algoritmus: Určení rozsahů platnosti • VAR – množina proměnných • Orientovaný graf control-flow v proceduře: (BB,CF) • BB – množina základních bloků • CF  BB  BB – přechody mezi základními bloky • Lokální analýza • Vnitřní chování každého základního bloku • W : BB  VAR → Bool – blok zapisuje do proměnné • R : BB  VAR → Bool – blok čte proměnnou před prvním zápisem • Triviální algoritmus • Globální analýza • Platnost proměnných na začátku každého základního bloku • L : BB  VAR → Bool – proměnná je živá na začátku bloku • Polynomiální algoritmus • Dopočet • Platnost proměnných na koncích bloků a uvnitř bloků • Detekce čtení nezapsaných proměnných • Triviální algoritmus • Vylepšení • Určení komponent souvislosti a přeznačení proměnných

  45. Algoritmus: Určení rozsahů platnosti • Vstup • (BB,CF) – graf control flow • W(b,v) – blok b zapisuje do proměnné v • R(b,v) – blok b čte proměnnou v před prvním zápisem do ní • Výstup • L(b,v) – proměnná v je živá na začátku bloku b • for each b in BB • L(b,v) = R(b,v); • do { • for each <b1,b2> in CF • L(b1,v) |= ~ W(b1,v) & L(b2,v); • } while changed; • Algoritmus se provádí vektorově • Pro všechny proměnné (v) najednou • Překladač využije SIMD instrukce • O(|BB|*|CF|*|VAR|)

  46. Určení rozhraní BB ENTER ENTER LD_I32(Px) LD_I32(Py) LD_I32(Px) LD_I32(Py) GT_I32 GT_I32 JC JC LD_I32(Py) LD_I32(Px) LD_I32(Py) LD_I32(Px) ST_I32(Py) ST_I32(Vz) ST_I32(Py) ST_I32(Vz) LD_I32(Vz) LD_I32(Vz) ST_I32(Px) ST_I32(Px) LD_I32(Py) LD_I32(Px) LD_I32(Py) LD_I32(Px) ST_I32(Py) MOD_I32 ST_I32(Py) MOD_I32 LD_I32(Px) LD_I32(Px) ST_I32(Vz) ST_I32(Vz) GTC_I32(C1) GTC_I32(C1) LD_I32(Vz) LD_I32(Vz) JC JC ST_I32(Px) ST_I32(Px) LD_I32(Py) LD_I32(Py) RET_I32 RET_I32

  47. int gcd( int x, int y) { int z; if ( x > y ) { z = y; y = x; x = z; } while ( x > 0 ) { z = y % x; y = x; x = z; } return y; } CONST:(C1,I32,0) PROC ”gcd” PARAM:(Px,I32,”x”),(Py,I32,”y”) VAR:(Vz,I32,”z”) Nesekvenční mezikód s rozhraními BB ENTER LD_I32(Px) LD_I32(Py) GT_I32 JC Dag operand antidependence: r-w LD_I32(Py) LD_I32(Px) ST_I32(Py) ST_I32(Vz) LD_I32(Vz) ST_I32(Px) LD_I32(Py) LD_I32(Px) ST_I32(Py) MOD_I32 LD_I32(Px) ST_I32(Vz) GTC_I32(C1) LD_I32(Vz) JC ST_I32(Px) LD_I32(Py) RET_I32 Rozhraní 1 Px Py Rozhraní 2 Px Py

  48. Náhrada proměnných rozhraním BB ENTER ENTER LD_I32(Px) LD_I32(Py) GT_I32 GT_I32 JC JC LD_I32(Py) LD_I32(Px) ST_I32(Py) ST_I32(Vz) LD_I32(Vz) ST_I32(Px) LD_I32(Py) LD_I32(Px) ST_I32(Py) MOD_I32 MOD_I32 LD_I32(Px) ST_I32(Vz) GTC_I32(C1) GTC_I32(C1) LD_I32(Vz) JC JC ST_I32(Px) LD_I32(Py) RET_I32 RET_I32

  49. int gcd( int x, int y) { int z; if ( x > y ) { z = y; y = x; x = z; } while ( x > 0 ) { z = y % x; y = x; x = z; } return y; } CONST:(C1,I32,0) PROC ”gcd” PARAM:(Px,I32,”x”),(Py,I32,”y”) Nesekvenční mezikód bez proměnných ENTER GT_I32 JC MOD_I32 GTC_I32(C1) JC RET_I32 Dag data Rozhraní 1 Px Py Rozhraní 2 Px Py

  50. int gcd( int x, int y) { int z; if ( x > y ) { z = y; y = x; x = z; } while ( x > 0 ) { z = y % x; y = x; x = z; } return y; } CONST:(C1,I32,0) PROC ”gcd” PARAM:(Px,I32,”x”),(Py,I32,”y”) Nesekvenční mezikód po duplikaci BB ENTER GT_I32 JC RET_I32 RET_I32 MOD_I32 MOD_I32 GTC_I32(C1) GTC_I32(C1) JC JC Dag data Rozhraní 1 Px Py Rozhraní 2 Px Py