Kolekce kompilátorů GNU - GNU Compiler Collection

Kolekce kompilátoru GNU
Kolekce kompilátorů GNU logo.svg
GCC 10.2 GNU Compiler Collection self-compilation.png
Screenshot GCC 10.2 sestavující vlastní zdrojový kód
Původní autoři Richard Stallman
Vývojáři Projekt GNU
První vydání 23. května 1987 ; Před 34 lety ( 1987-05-23 )
Stabilní uvolnění
11.2 / 27. července 2021 ; před 2 měsíci ( 2021-07-27 )
Náhled vydání
11.2.0-RC / 21. července 2021 ; před 2 měsíci ( 2021-07-21 )
Úložiště
Napsáno C , C ++
Operační systém Cross-platform
Plošina GNU a mnoho dalších
Velikost ~ 15 milionů LOC
Typ Překladač
Licence GPLv3+ s výjimkou GCC Runtime Library
webová stránka gcc .gnu .org

GNU Compiler Collection ( GCC ) je optimalizace kompilátoru produkovaný GNU projekt podporuje různé programovací jazyky , hardwarové architektury a operační systémy . Free Software Foundation (FSF) distribuuje GCC jako svobodný software pod GNU General Public License (GNU GPL). GCC je klíčovou součástí řetězce nástrojů GNU a standardním překladačem pro většinu projektů souvisejících s jádrem GNU a Linuxem . Se zhruba 15 miliony řádků kódu v roce 2019 je GCC jedním z největších existujících bezplatných programů. Hrálo důležitou roli v růstu svobodného softwaru , jako nástroj i příklad.

Když to bylo poprvé vydána v roce 1987 Richard Stallman , GCC 1.0 byl jmenován GNU C kompilátor , protože to jen manipulovat s C programovací jazyk . V prosinci téhož roku byla rozšířena o kompilaci C ++ . Front endy byly později vyvinuty mimo jiné pro Objective-C , Objective-C ++ , Fortran , Ada , D a Go . Specifikace OpenMP a OpenACC jsou podporovány také v kompilátorech C a C ++.

GCC byl přenesen na více platforem a architektur instrukčních sad než kterýkoli jiný kompilátor a je široce nasazen jako nástroj při vývoji bezplatného i proprietárního softwaru . GCC je také k dispozici pro mnoho vestavěných systémů , včetně čipů založených na ARM a Power ISA .

Kromě toho, že je GCC oficiálním překladačem operačního systému GNU , byl přijat jako standardní překladač mnoha dalšími moderními počítačovými operačními systémy podobnými Unixu , včetně většiny distribucí Linuxu . Většina operačních systémů z rodiny BSD také krátce po vydání přešla na GCC, ačkoli od té doby se FreeBSD , OpenBSD a Apple macOS přesunuly do kompilátoru Clang , a to především z licenčních důvodů. GCC může také kompilovat kód pro Windows , Android , iOS , Solaris , HP-UX , AIX a DOS.

Dějiny

Na konci roku 1983, ve snaze bootstrap na GNU operační systém, Richard Stallman požádala Andrew S. Tanenbaum , autor v Amsterdam kompilátoru Kit (také známý jako Free University kompilátoru Kit ) o povolení používat tento software pro GNU. Když mu Tanenbaum poradil, že kompilátor není zadarmo a pouze univerzita je zdarma, Stallman se rozhodl pracovat na jiném kompilátoru. Jeho původním plánem bylo přepsat stávající překladač z Národní laboratoře Lawrence Livermora z Pastelu na C s trochou pomoci Len Tower a dalších. Stallman napsal nový C frontend pro kompilátor Livermore, ale pak si uvědomil, že to vyžaduje megabajty místa v zásobníku, což je nemožnost na 68 000 unixovém systému s pouhými 64 KB, a dospěl k závěru, že bude muset napsat nový kompilátor úplně od začátku. Žádný z kódů kompilátoru Pastel neskončil v GCC, ačkoli Stallman použil frontend C, který napsal.

GCC byl poprvé vydán 22. března 1987, dostupný na FTP od MIT . Stallman byl uveden jako autor, ale citoval ostatní za jejich příspěvky, včetně Jacka Davidsona a Christophera Frasera pro myšlenku použití RTL jako prostředního jazyka, Paul Rubin pro psaní většiny preprocesoru a Leonard Tower pro „části analyzátoru, RTL generátor, definice RTL a popis stroje Vax. " Kompilátor GNU, který Peter H. Salus popsal jako „první hit svobodného softwaru“ , dorazil právě v době, kdy Sun Microsystems odděloval své vývojové nástroje od svého operačního systému a prodával je samostatně za vyšší kombinovanou cenu než předchozí balíček, který vedl mnoho uživatelů Sunu ke koupi nebo stažení GCC místo nástrojů prodejce. Zatímco Stallman považoval za svůj hlavní projekt GNU Emacs , v roce 1990 GCC podporovalo třináct počítačových architektur, překonávalo několik kompilátorů prodejců a komerčně je používalo několik společností.

Vidlice EGCS

Vzhledem k tomu, že GCC byla licencována pod GPL, programátoři, kteří chtěli pracovat v jiných směrech - zejména těch, která píšou rozhraní pro jiné jazyky než C -, si mohli vyvinout vlastní vidličku překladače za předpokladu, že splňují podmínky GPL, včetně požadavků na distribuci zdroje. kód . Vícenásobné vidlice se však ukázaly jako neúčinné a nepraktické a obtížnost získání práce přijatá oficiálním projektem GCC byla pro mnohé značně frustrující, protože projekt upřednostňoval stabilitu před novými funkcemi. FSF držel tak těsnou kontrolu nad tím, co bylo přidáno k oficiální verzi GCC 2.x (vyvíjené od roku 1992), že GCC bylo použito jako jeden příklad vývojového modelu „katedrály“ v eseji Erica S.Raymonda The Cathedral and the Bazar .

V roce 1997 vytvořila skupina vývojářů Experimental/Enhanced GNU Compiler System (EGCS), aby sloučila několik experimentálních vidlic do jednoho projektu. Základem fúze byl vývojový snímek GCC (pořízený kolem 2.7.2 a později následoval až do verze 2.8.1). Fúze zahrnovala g77 (Fortran), PGCC ( P5 Pentium -optimized GCC), mnoho vylepšení C ++ a mnoho nových architektur a variant operačního systému .

Zatímco oba projekty na sebe navzájem pečlivě navazovaly, vývoj EGCS se ukázal být výrazně dynamičtější, a to natolik, že FSF oficiálně zastavil vývoj kompilátoru GCC 2.x, požehnal EGCS jako oficiální verzi GCC a jmenoval projekt EGCS jako GCC. správci v dubnu 1999. S vydáním GCC 2.95 v červenci 1999 byly oba projekty opět sjednoceny. GCC od té doby udržuje pestrá skupina programátorů z celého světa pod vedením řídícího výboru.

GCC 3 (2002) odstranil front-end pro CHILL z důvodu nedostatečné údržby.

Před verzí 4.0 byl frontend Fortran g77, který podporoval pouze FORTRAN 77 , ale později byl upuštěn ve prospěch nového frontendu GNU Fortran, který podporuje Fortran 95 a velké části Fortranu 2003 a Fortranu 2008 také.

Od verze 4.8 je GCC implementován v C ++.

Podpora pro Cilk Plus existovala od GCC 5 do GCC 7.

GCC byl přenesen do široké škály architektur instrukčních sad a je široce nasazen jako nástroj při vývoji bezplatného i proprietárního softwaru . GCC je také k dispozici pro mnoho vestavěných systémů , včetně čipů Symbian (nazývaných gcce ), ARM a Power ISA . Kompilátor může cílit na širokou škálu platforem, včetně herních konzolí , jako je PlayStation 2 , Cell SPE PlayStation 3 a Dreamcast . Byl přenesen na více druhů procesorů a operačních systémů než kterýkoli jiný kompilátor.

Podporované jazyky

V květnu 2021 obsahuje nedávné vydání GCC 11.1 front - end pro programovací jazyky C ( gcc), C ++ ( g++), Objective-C , Fortran ( gfortran), Ada ( GNAT ), Go ( gccgo) a D ( gdcod 9.1) s se OpenMP a OpenACC paralelní jazyková rozšíření je podporováno, protože GCC 5.1. Verze před GCC 7 také podporovaly Javu ( gcj), což umožňuje kompilaci Javy do nativního strojového kódu.

Pokud jde o podporu jazykových verzí pro C ++ a C, od GCC 11.1 je výchozím cílem gnu ++ 17 , nadmnožina C ++ 17 a gnu11 , nadmnožina C11 , k dispozici je také přísná standardní podpora. GCC také poskytuje experimentální podporu pro C ++ 20 a nadcházející C ++ 23 .

Front-endy třetích stran existují pro mnoho jazyků, například Pascal ( gpc), Modula-2 , Modula-3 , PL/I a VHDL ( GHDL). Existuje několik experimentálních větví na podporu dalších jazyků, například kompilátor GCC UPC pro Unified Parallel C nebo Rust .

Design

Přehled rozšířeného kompilačního kanálu GCC včetně specializovaných programů, jako je preprocesor , assembler a linker .
GCC navazuje na 3stupňovou architekturu typickou pro vícejazyčné a víceprocesorové překladače . Všechny stromové struktury programu jsou převedeny na společnou abstraktní reprezentaci na „středním konci“, což umožňuje sdílení kódu pro optimalizaci kódu a generování binárních kódů všemi jazyky.

Externí rozhraní GCC dodržuje unixové konvence. Uživatelé vyvolají program ovladače specifický pro jazyk ( gccpro C, g++pro C ++ atd.), Který interpretuje argumenty příkazů , zavolá skutečný kompilátor, spustí na výstupu assembler a poté volitelně spustí linker, aby vytvořil úplný spustitelný binární soubor .

Každý z jazykových překladačů je samostatný program, který čte zdrojový kód a vydává strojový kód . Všechny mají společnou vnitřní strukturu. Front-end podle jazyka analyzuje zdrojový kód v tomto jazyce a vytvoří abstraktní strom syntaxe (zkráceně „strom“).

Ty jsou v případě potřeby převedeny na vstupní reprezentaci středního konce, která se nazývá GENERICKÁ forma; střední konec pak postupně transformuje program do jeho konečné podoby. Na kód se použijí optimalizace kompilátoru a techniky analýzy statického kódu (například FORTIFY_SOURCE, směrnice kompilátoru, která se pokouší zjistit nějaké přetečení vyrovnávací paměti ). Ty fungují na více reprezentacích, většinou na architektuře nezávislých GIMPLE reprezentací a na architektuře závislých RTL reprezentacích. Nakonec je strojový kód vytvořen pomocí přizpůsobení vzoru specifického pro architekturu původně založeného na algoritmu Jack Davidson a Chris Fraser.

GCC byl napsán především v jazyce C s výjimkou částí frontendu Ada . Distribuce zahrnuje standardní knihovny pro Ada a C ++, jejichž kód je většinou napsán v těchto jazycích. Na některých platformách distribuce obsahuje také runtime knihovna nízkoúrovňové, libgcc , které v kombinaci C a procesor pro konkrétní stroj nezávislé strojový kód , který je určen především pro zpracování aritmetických operací, že cílový procesor nemůže provádět přímo.

GCC ve své sestavě používá mnoho standardních nástrojů, včetně Perl , Flex , Bison a dalších běžných nástrojů. Kromě toho aktuálně vyžaduje, aby byly k vybudování přítomny tři další knihovny: GMP , MPC a MPFR .

V květnu 2010 se řídící výbor GCC rozhodl povolit použití kompilátoru C ++ ke kompilaci GCC. Kompilátor měl být napsán převážně v jazyce C plus podmnožina funkcí z jazyka C ++. Zejména bylo rozhodnuto, aby vývojáři GCC mohli používat destruktory a generické funkce C ++.

V srpnu 2012 řídicí výbor GCC oznámil, že GCC nyní používá jako implementační jazyk C ++. To znamená, že k vytváření GCC ze zdrojů je vyžadován kompilátor C ++, který rozumí standardu ISO/IEC C ++ 03 .

18. května 2020 se GCC přesunul od standardu ISO/IEC C ++ 03 ke standardu ISO/IEC C ++ 11 (tj. Potřebný ke kompilaci, bootstrapu, samotnému kompilátoru; ve výchozím nastavení však kompiluje novější verze C ++).

Přední konce

Rozhraní front -end se skládá z předzpracování , lexikální analýzy , syntaktické analýzy (analýzy) a sémantické analýzy. Cílem front -endů kompilátoru je buď přijmout nebo odmítnout kandidátské programy podle jazykové gramatiky a sémantiky, identifikovat chyby a zpracovat platné reprezentace programu do pozdějších fází kompilátoru. Tento příklad ukazuje kroky lexer a parser poskytovány za jednoduchý program napsaný v C .

Každý frontend používá analyzátor k vytvoření abstraktního stromu syntaxe daného zdrojového souboru . Kvůli abstrakci stromu syntaxe mohou být zdrojové soubory libovolného z různých podporovaných jazyků zpracovávány stejným back -endem . GCC začalo používat analyzátory LALR generované pomocí Bison , ale postupně přešly na ručně psané analyzátory rekurzivního sestupu pro C ++ v roce 2004 a pro C a Objective-C v roce 2006. Od roku 2021 všechny frontendy používají ručně psané rekurzivní sestupové analyzátory .

Až do GCC 4.0 nebyla stromová reprezentace programu plně nezávislá na cíleném procesoru. Význam stromu byl v různých jazykových frontendech poněkud odlišný a frontend mohl poskytovat vlastní kódy stromů. To bylo zjednodušeno zavedením GENERIC a GIMPLE, dvou nových forem jazykově nezávislých stromů, které byly zavedeny s příchodem GCC 4.0. GENERIC je složitější, vychází z mezilehlé reprezentace frontendu GCC 3.x Java. GIMPLE je zjednodušený obecný, ve kterých jsou různé konstrukty snížena na více instrukcí GIMPLE. Frontendy C , C ++ a Java produkují GENERIC přímo v frontendu. Ostatní frontendy místo toho mají po analýze různé přechodné reprezentace a převedou je na GENERIC.

V obou případech takzvaný „gimplifier“ poté převede tuto složitější formu na jednodušší GIMPLE formu založenou na SSA , která je společným jazykem pro velké množství výkonných globálních (funkčních rozsahů) optimalizací nezávislých na jazyce a architektuře.

GENERICKÉ a GIMPLE

GENERIC je středně pokročilý reprezentační jazyk používaný jako „střední konec“ při kompilaci zdrojového kódu do spustitelných binárních souborů . Na podmnožinu zvanou GIMPLE cílí všechny přední konce GCC.

Střední fáze GCC provádí veškerou analýzu a optimalizaci kódu , pracuje nezávisle na kompilovaném jazyce i na cílové architektuře, počínaje GENERICKOU reprezentací a jejím rozšířením na registrační přenosový jazyk (RTL). GENERICKÁ reprezentace obsahuje pouze podmnožinu imperativních programovacích konstrukcí optimalizovaných středním koncem.

Při transformaci zdrojového kódu na GIMPLE jsou složité výrazy rozděleny do kódu se třemi adresami pomocí dočasných proměnných . Tato reprezentace byla inspirována jednoduchou reprezentaci navržená v McCAT kompilátoru Laurie J. Hendren pro zjednodušení analýzu a optimalizaci z naléhavých programů .

Optimalizace

Optimalizace může nastat během jakékoli fáze kompilace; většina optimalizací se však provádí po syntaxi a sémantické analýze frontendu a před generováním kódu back -endu; běžný, i když poněkud rozporuplný název této části kompilátoru je „střední konec“.

Přesná sada optimalizací GCC se liší od vydání k vydání, jak se vyvíjí, ale zahrnuje standardní algoritmy, jako je optimalizace smyčky , skokové vlákno , eliminace běžných podvýrazů , plánování instrukcí atd. Tyto RTL optimalizace jsou méně důležitosti s přídavkem globální SSA-zakládal optimalizace na GIMPLE stromy jak RTL optimalizace mají mnohem omezenější rozsah, a mít informace na vysoké úrovni méně.

Některé z těchto optimalizací prováděných na této úrovni zahrnují mrtvou kódovou eliminaci , částečnou eliminaci redundance , globální hodnotové číslování , rozptýlenou podmíněnou konstantní propagaci a skalární nahrazení agregátů . Provádějí se také optimalizace založené na poli, jako je automatická vektorizace a automatická paralelizace . Je také možná optimalizace podle profilu .

Zadní konec

Zadní konec GCC je částečně specifikován makry preprocesoru a funkcemi specifickými pro cílovou architekturu, například pro definování její endianity , velikosti slova a konvencí volání . Přední část zadního konce je používá k rozhodnutí o generování RTL, takže ačkoli RTL GCC je nominálně nezávislý na procesoru, počáteční sekvence abstraktních instrukcí je již přizpůsobena cíli. V každém okamžiku musí skutečné instrukce RTL tvořící reprezentaci programu odpovídat popisu stroje cílové architektury.

Soubor popisu stroje obsahuje vzory RTL spolu s omezeními operandů a úryvky kódu pro výstup finální sestavy. Omezení naznačují, že konkrétní RTL vzor se může vztahovat pouze (například) na určité hardwarové registry, nebo (například) umožňovat okamžité offsety operandů pouze omezené velikosti (např. 12, 16, 24, ... bitové offsety atd. ). Během generování RTL se kontrolují omezení pro danou cílovou architekturu. Aby bylo možné vydat daný úryvek RTL, musí odpovídat jednomu (nebo více) RTL vzorům v souboru popisu stroje a splňovat omezení pro tento vzor; jinak by nebylo možné převést konečný RTL na strojový kód.

Ke konci kompilace je platný RTL redukován na striktní formu, ve které každá instrukce odkazuje na skutečné registry strojů a vzor ze souboru popisu stroje cíle. Vytvoření přísné RTL je komplikovaný úkol; důležitým krokem je alokace registrů , kde jsou vybrány skutečné hardwarové registry, které nahradí původně přiřazené pseudoregistry. Následuje fáze „přebíjení“; všechny pseudoregistry, kterým nebyl přiřazen skutečný hardwarový registr, jsou „vysypány“ do zásobníku a vygeneruje se RTL k provedení tohoto rozlití. Podobně musí být offsety, které jsou příliš velké, aby se vešly do skutečné instrukce, rozděleny a nahrazeny sekvencemi RTL, které budou dodržovat ofsetová omezení.

V konečné fázi je strojový kód vytvořen voláním malého úryvku kódu, přiřazeného ke každému vzoru, ke generování skutečných pokynů ze sady instrukcí cíle pomocí konečných registrů, offsetů a adres zvolených během fáze načítání. Fragment generování sestavení může být pouze řetězec, v takovém případě se provede jednoduchá náhrada řetězců registrů, offsetů a/nebo adres do řetězce. Fragment generování sestavení může být také krátkým blokem kódu C, který provádí nějakou další práci, ale nakonec vrací řetězec obsahující platný kód sestavení.

Standardní knihovna C ++ (libstdc ++)

Projekt GCC zahrnuje implementaci standardní knihovny C ++ s názvem libstdc ++ licencovanou pod licencí GPLv3 s výjimkou propojení uzavřené zdrojové aplikace, pokud jsou zdroje vytvořeny pomocí GCC. Aktuální verze je 11.

Další funkce

Některé funkce GCC zahrnují:

Optimalizace doby propojení
Optimalizace v době propojení optimalizuje přes hranice souborů objektu, aby přímo zlepšila propojený binární soubor. Optimalizace doby propojení závisí na přechodném souboru, který obsahuje serializaci nějaké Gimple reprezentace zahrnuté v souboru objektu. Soubor je generován spolu se souborem objektu během kompilace zdroje. Každá zdrojová kompilace generuje samostatný objektový soubor a pomocný soubor při propojení. Když jsou soubory objektů propojeny, kompilátor se spustí znovu a pomocí pomocných souborů optimalizuje kód v odděleně kompilovaných souborech objektů.
Pluginy
Pluginy přímo rozšiřují kompilátor GCC. Pluginy umožňují kompilátor skladu přizpůsobit konkrétním potřebám pomocí externího kódu načteného jako pluginy. Pluginy mohou například přidávat, nahrazovat nebo dokonce odebírat průchody středního konce fungující na reprezentacích Gimple . Bylo již publikováno několik doplňků GCC, zejména:
  • Zásuvný modul Python, který je propojen s libpythonem a umožňuje vyvolávat libovolné skripty Pythonu zevnitř kompilátoru. Cílem je umožnit psaní doplňků GCC v Pythonu.
  • Plugin MELT poskytuje jazyk Lisp na vysoké úrovni pro rozšíření GCC.
Podpora doplňků byla v roce 2007 kdysi sporným problémem.
C ++ transakční paměť
Jazyk C ++ má aktivní návrh na transakční paměť. Lze jej povolit v GCC 6 a novějších při kompilaci s -fgnu-tm.
Identifikátory Unicode
Ačkoli jazyk C ++ vyžaduje v identifikátorech podporu pro znaky jiné než ASCII Unicode , tato funkce je podporována pouze od GCC 10. Stejně jako u stávajícího zpracování řetězcových literálů se předpokládá, že zdrojový soubor je kódován v UTF-8 . Tato funkce je v jazyce C volitelná, ale od této změny byla také k dispozici.

Architektury

GCC kompilace Hello World ve Windows

Mezi rodiny cílových procesorů GCC od verze 11.1 patří:

Méně známé cílové procesory podporované ve standardní verzi zahrnovaly:

Verze GCC udržované odděleně od verze FSF podporovaly další procesory:

GCJ Java kompilátor může zaměřit buď nativního strojového jazyka architektury nebo Java Virtual Machine je Java bytecode . Při přesměrování GCC na novou platformu se často používá bootstrapping . Motorola 68000, Zilog Z80 a další procesory jsou také zaměřeny ve verzích GCC vyvinutých pro různé programovatelné kalkulačky grafických grafů Texas Instruments, Hewlett Packard, Sharp a Casio.

Licence

GCC je licencován pod licencí GNU General Public License verze 3. Výjimka runtime GCC umožňuje kompilaci proprietárních programů (kromě svobodného softwaru) s GCC. To nemá vliv na licenční podmínky zdrojového kódu GCC.

Viz také

Reference

Další čtení

externí odkazy

Oficiální

jiný