Kompiler ^^^^^^^^ Nejdůležitelší program pod GNU je nesporně kompiler. Ten umožnil aby vzniklo všechno ostatní. A není to jen tak ledajaký kompiler. Chtěl bych vysvětlit, čím se odlišuje od klasických (třeba Borlandích) kompilerů. Klasický kompiler napřed načte vstup, rozloží ho na tokeny a poruzumí mu. Když už ví, co programátor napsal, přidělí pamětová místa proměným (modernější používají i registry) a potom pomocí jakýchsi prefabrikátů na každý příkaz jazyka složí výsledný kód. Případně se ješte pokusí předvyhodnotit výrazy, kde je očividně všechno konstantní, nebo se rozhlédne po vzniklém assembleru a vymění pár instrukcí, které se často špatně generují. Vzniklou skládačku potom pošle dál. GNU kompiler má jiné řešení. Nejprve porozumí programu. Toto je jediná část závislá na jazyce a nazývá se parsing. Potom se vygeneruje mezijazyk zvaný Register transfer language (RTL). Od tohoto okamžiku už je kompileru jedno, jestli kompiluje C, nebo pascal. Mezijazyk je podobný lispu. Tedy ideální pro strojové zpracování, protože všechny příkazy mají stejnou syntax (liší se pouze akcí) a obsahují dodatečně šikonvé informace, jako třeba co potřebuje za vstup/výstup a co modifikuje. Všechny proměné/pamět jsou unifikovány do registrů (tedy třeba pole je také registr). Jazyk není reprezentován textově ale ve specialní struktuře tak, aby se s ním dobře pracovalo. Jde ale uložit do textové podoby. Třeba následující hloupý přiklad: main() { return(0); } Má mezikód No je vidět, že to není zrovna nic moc optimálního :). Ale je to něco. Teď se dostanou ke slovu optimizéry. Valná většina je nezávislá na architektuře (procesoru) protože ani RTL se zatím moc asembleru nepodobá (snad až na jména registrů). Optimizerů je hodně. Takže jenom krátký popis: Optimizace skoků - zrušení skoků na skoky Scanování registrů - tady se najde kdy který registr (krycí název pro proměnou) byl použit poprvé/naposled Optimizace skoků, které skačou na stejný/opačný test - ty můžou být vyhozeny Propagace konstant, eliminace expresion - propagace konstant se snaží dosadit konstanty za registry. Pokud jsou nějaké expresion bez vstupů/výstupů a vedlejších efektů, nebo můžou byt vyhodnoceny tak se vyhodí/vypočtou. To zkracuje výrazy, vyhodí nepotřebné části programu atd. Optimizace smyček - Snaží se všechno, co jenom jde vyhodit ven znova eliminace expresion Analýza toku dat - Rozdělí program do bloků, vyhazuje nedosažitelné smyčky, a zjištůje, kde který registr je "živý" to znamená že je třeba uchovávat jeho hodnotu, najde výpočty, kde výsledek není použit. Kombinace instrukcí - (ne assemblerových ale těch RTL) Spojuje instrukce, keré jdou do jedné, používa algebru na optimizaci mat. výrazů a přidělí RTL kódu opravdové instrukce, které odpovídají popisu procesoru. (ano tahle část je částečně závislá na architektuře) Scheduling instrukcí - poskládá instrukce tak, aby dobře lezly do superskalárních riscových procesorů. Verze 2.8.0 (která ještě není to bude dělat i pro pentia/sextia) Třídy registrů - hardwarové registry mají několik tříd. Tak třeba pamět (zásobník), registry procesoru, registry koprocesoru. Tato část rozhodne, které třídy registru použít pro ten daný pseudoregistr. Alokace registrů - tady se konečně rozhodne, které proměné budou ve výsledném programu uloženy a kdy Globální alokace registrů - to samé ale pro globání proměné Reloading - tady se dosadí hardwarové registry registrům a zbytek se uloží do zásobníku Další scheduling - aby se instrukce nehádaly o pamět Znova optimizace skoků, další scheduling optimizace zasobníkových registrů - to je special pro 386kový kopr Převod do assembleru - a dílo je hotovo. Tohle zbylo z našeho příkladu Z toho vyrobit assembler je uz hračka: (Je v AT&T syntaxi. Ale snad to je jasné) main: xorl %eax,%eax ret Abych ukázal kvalitu kódu ještě jeden hloupý příklad: main() {int i,a=1,b=0; for(i=0;i<9999;i++) a=a+b,b=2*a; printf("%i\n",a); } Z gnu vylezo (teda mimo toho kometáře) A tohle vyrobil borland No myslím že srovnání je dost výmluvné ale v časopisech bývají nějaké ty tabulky s časem. Tak dobře. Rozhodl jsem se pro výpočet mandelbrotky. Je to celkem netriviální, koprocedor využívající smyčka z realného života. Tak se na tom má kompiler co činit. Testy si ale musíte přečíst až na druhé stránce výheň