Oversigt over GCC ‘ s udvidede kompilation pipeline, herunder specialiserede programmer som præprocessor, assembler og linker.
GCC følger den 3-trins arkitektur, der er typisk for Multi-language og multi-CPU compilere. Alle programtræer konverteres til en fælles abstrakt repræsentation i “middle end”, hvilket gør det muligt at dele kodeoptimering og binær kodegenereringsfaciliteter af alle sprog.,
GCCS eksterne grænseflade følger Uni. – konventioner. Brugere påberåber sig et sprogspecifikt driverprogram (gcc
for C, g++
for C++ osv.), som fortolker kommando argumenter, kalder den faktiske compiler, kører assembler på output, og derefter eventuelt kører linker til at producere en komplet eksekverbar binær.
hvert af sprogkompilatorerne er et separat program, der læser kildekode og udsender maskinkode. Alle har en fælles intern struktur., En pr-sprog frontend analyserer kildekoden på dette sprog og producerer en abstrakt syntaks træ (“træ” for korte).
disse konverteres om nødvendigt til den midterste ende input repræsentation, kaldet generisk form; den midterste ende omdanner derefter gradvist programmet til dets endelige form. Compileroptimeringer og statiske kodeanalyseteknikker (såsom FORTIFY_SOURCE, et compilerdirektiv, der forsøger at opdage nogle bufferoverløb) anvendes til koden., Disse arbejder på flere repræsentationer, for det meste den arkitekturuafhængige GIMPLE-repræsentation og den arkitekturafhængige RTL-repræsentation. Endelig er maskinkode produceret ved hjælp af arkitektur-specifikke mønster matching oprindeligt baseret på en algoritme af Jack Davidson og Chris Fraser.
GCC blev skrevet primært i C bortset fra dele af Ada frontend. Distributionen inkluderer standardbibliotekerne for Ada, C++ og Java, hvis kode for det meste er skrevet på disse sprog., På nogle platforme, distributionen inkluderer også en lav-niveau runtime library, libgcc, skrevet i en kombination af maskine-uafhængig C og processor-specifik maskine kode, der primært er designet til at håndtere aritmetiske operationer, at målet processor kan ikke udføre direkte.gcc bruger mange standardværktøjer i sin opbygning, herunder Perl, fle., Bison og andre almindelige værktøjer. Derudover kræver det i øjeblikket tre yderligere biblioteker at være til stede for at bygge: GMP, MPC og mpfr.
i maj 2010 besluttede GCC-styringskomit .en at tillade brug af en C++ – compiler til at kompilere gcc., Kompilatoren var beregnet til at blive skrevet for det meste i C plus en delmængde af funktioner fra C++. Dette blev især besluttet, så GCC ‘ s udviklere kunne bruge destructors og generics-funktionerne i C++.
i August 2012 meddelte GCC steering committee, at GCC nu bruger C++ som implementeringssprog. Dette betyder, at for at opbygge GCC fra kilder kræves en C++ – compiler, der forstår ISO/IEC C++03-standard.,
Foran endsEdit
Front ender består af forbehandling, leksikalsk analyse syntaktisk analyse (parsing) og semantisk analyse. Målene for compiler frontends er at enten acceptere eller afvise kandidatprogrammer i henhold til sprog grammatik og semantik, identificere fejl og håndtere gyldige program repræsentationer til senere compiler faser. Dette eksempel viser le Ander og parser trin udført for et simpelt program skrevet i C.,
hver frontend bruger en parser til at producere det abstrakte syntakstræ i en given kildefil. På grund af syntaks træ abstraktion, kan kildefiler af nogen af de forskellige understøttede sprog behandles af den samme bagenden. GCC startede med at bruge LALR parsere genereret med Bison, men skiftede gradvist til håndskrevne rekursive afstamningsparsere til C++ i 2004 og til C og Objective-C i 2006. Fra 2021 bruger alle frontends håndskrevne rekursive afstamningsparsere.
indtil GCC 4.,0 træets repræsentation af programmet var ikke helt uafhængig af, at processoren blev målrettet. Betydningen af et træ var noget anderledes for forskellige sprogforender, og forenden kunne give deres egne trækoder. Dette blev forenklet med indførelsen af GENERIC og GIMPLE, to nye former for sproguafhængige træer, der blev introduceret med fremkomsten af GCC 4.0. Generisk er mere kompleks, baseret på GCC 3.jav Java frontend mellemliggende repræsentation. GIMPLE er en forenklet generisk, hvor forskellige konstruktioner sænkes til flere GIMPLE instruktioner., De C, C++, og Java forreste ender producere generiske direkte i den forreste ende. Andre frontends har i stedet forskellige mellemliggende repræsentationer efter parsing og konverterer disse til generiske.
i begge tilfælde konverterer den såkaldte “gimplifier” derefter denne mere komplekse form til den enklere SSA-baserede GIMPLE-form, der er det fælles sprog for et stort antal magtfulde sprog – og arkitekturuafhængige globale (funktionsomfang) optimeringer.,
generisk og GIMPLEEdit
generisk er en mellemliggende repræsentation sprog, der anvendes som en “midterste ende”, mens kompilering kildekode i eksekverbare binære filer. En delmængde, kaldet GIMPLE, er målrettet af alle de forreste ender af gcc.
Den midterste fase af GCC, som gør alt det kode, analyse og optimering, der arbejder uafhængigt af både kompileret sprog, og det mål, arkitektur, startende fra GENERISK repræsentation og udvide det til at registrere overførsel sprog (RTL)., Den generiske repræsentation indeholder kun den delmængde af de bydende nødvendigt programmering konstruktioner optimeret af den midterste ende.
ved omdannelse af kildekoden til GIMPLE opdeles komplekse udtryk i en tre-adressekode ved hjælp af midlertidige variabler. Denne repræsentation blev inspireret af den enkle repræsentation, der blev foreslået i McCAT-kompilatoren af Laurie J. Hendren for at forenkle analysen og optimeringen af imperative programmer.,
Optimeringredit
optimering kan forekomme under enhver fase af kompilering; imidlertid udføres hovedparten af optimeringer efter syntaksen og semantisk analyse af frontenden og før kodegenerering af bagenden; således er et almindeligt, selvom noget modstridende, navn på denne del af kompilatoren “midterenden.”
Den nøjagtige sæt af GCC optimeringer varierer fra udgivelse til udgivelse, som det udvikler sig, men omfatter standard algoritmer, såsom loop optimering, hoppe threading, fælles underudtryk afskaffelse, instruktion planlægning, og så videre., RTL-optimeringerne er af mindre betydning med tilføjelsen af globale SSA-baserede optimeringer på GIMPLE-træer, da RTL-optimeringer har et meget mere begrænset omfang og har mindre information på højt niveau.nogle af disse optimeringer, der udføres på dette niveau, inkluderer eliminering af død kode, eliminering af delvis redundans, global værdi nummerering, sparsom betinget konstant udbredelse og skalar udskiftning af aggregater. Array-afhængighedsbaserede optimeringer såsom automatisk vektorisering og automatisk parallelisering udføres også. Profilstyret optimering er også mulig.,
Back endEdit
GCC ‘ s bagende er delvist specificeret af præprocessormakroer og funktioner, der er specifikke for en målarkitektur, for eksempel for at definere dens endethed, ordstørrelse og kaldende konventioner., Den forreste del af bagenden bruger disse til at hjælpe med at bestemme RTL-generation, så selvom GCCS RTL er nominelt processoruafhængig, er den oprindelige sekvens af abstrakte instruktioner allerede tilpasset målet. På ethvert tidspunkt skal de faktiske RTL-instruktioner, der danner programrepræsentationen, overholde maskinbeskrivelsen af målarkitekturen.
maskinbeskrivelsesfilen indeholder RTL-mønstre sammen med operand-begrænsninger og kodestykker for at udsende den endelige samling., Begrænsningerne indikerer, at et bestemt RTL-mønster muligvis kun gælder (for eksempel) for visse hard .areregistre, eller (for eksempel) tillader øjeblikkelige operand-forskydninger af kun en begrænset størrelse (f .eks. 12, 16, 24,… bit forskydninger, etc.). Under RTL-generationen kontrolleres begrænsningerne for den givne målarkitektur. For at udstede et givet uddrag af RTL skal det matche et (eller flere) af RTL-mønstrene i maskinbeskrivelsesfilen og opfylde begrænsningerne for dette mønster; ellers ville det være umuligt at konvertere den endelige RTL til maskinkode.,
mod slutningen af kompileringen reduceres gyldig RTL til en streng form, hvor hver instruktion refererer til reelle maskinregistre og et mønster fra målets maskinbeskrivelsesfil. At danne streng RTL er en kompliceret opgave; et vigtigt skridt er registerallokering, hvor rigtige hard .areregistre vælges til at erstatte de oprindeligt tildelte pseudo-registre. Dette efterfølges af en” ladning ” fase; eventuelle pseudo-registre, der ikke blev tildelt en reel hard .are register er ‘spildt’ til stakken, og RTL til at udføre denne Spilde genereres., Ligeledes skal forskydninger, der er for store til at passe ind i en faktisk instruktion, brydes op og erstattes af RTL-sekvenser, der vil overholde offset-begrænsningerne.
i den sidste fase bygges maskinkoden ved at kalde et lille kodestykke, der er knyttet til hvert mønster, for at generere de rigtige instruktioner fra målets instruktionssæt ved hjælp af de endelige registre, forskydninger og adresser, der er valgt under genindlæsningsfasen. Samlingen generation uddrag kan være blot en streng, i hvilket tilfælde en simpel streng substitution af registre, forskydninger, og/eller adresser i strengen udføres., Samlingsgenerationsuddraget kan også være en kort blok C-kode, der udfører noget ekstra arbejde, men i sidste ende returnerer en streng, der indeholder den gyldige samlingskode.
andre featuresEdit
Nogle funktioner i GCC omfatter:
- Link-tid optimering optimerer tværs objekt fil grænser til direkte at forbedre den linkede binære. Link – time optimering er afhængig af en mellemliggende fil, der indeholder serialisering af nogle Gimple repræsentation indgår i objektet fil. Filen genereres ved siden af objektet fil under kilde kompilering., Hver kilde kompilering genererer en separat objekt fil og link-tid hjælper fil. Når objektfilerne er forbundet, udføres kompilatoren igen og bruger hjælpefilerne til at optimere kode på tværs af de separat kompilerede objektfiler.
- Plugins kan udvide GCC compiler direkte. Plugins tillader en bestand compiler, der skal skræddersys til specifikke behov ved ekstern kode indlæst som plugins. For eksempel kan plugins tilføje, erstatte eller endda fjerne midterste passerer opererer på Gimple repræsentationer., Flere GCC-udvidelsesmoduler og er allerede blevet offentliggjort, især GCC Python plugin, som linker mod libpython, og gør det muligt at påberåbe sig vilkårlige Python-scripts inde fra compileren. Målet er at tillade GCC plugins, der skal skrives i Python. Den MELT plugin giver et højt niveau Lisp-lignende sprog til at udvide GCC.
- C++ transaktionshukommelse ved kompilering med-fgnu-TM.
- fra GCC 10 tillader identifikatorer UTF-8 (Unicode) kodning, dvs.C kildekode bruger UTF-8-kodning som standard.