Kodegenerering (kompilator) - Code generation (compiler)

I computing , kodegenerering er den proces, hvorved en compiler 's kode generator konverterer nogle mellemliggende repræsentation af kildekoden til en form (fx maskinkode ), som let kan udføres af en maskine.

Sofistikerede kompilatorer udfører typisk flere afleveringer over forskellige mellemformer. Denne flertrinsproces bruges, fordi mange algoritmer til kodeoptimering er lettere at anvende en ad gangen, eller fordi input til en optimering er afhængig af den gennemførte behandling udført af en anden optimering. Denne organisation letter også oprettelsen af ​​en enkelt compiler, der kan målrette mod flere arkitekturer, da kun de sidste af kodegenereringstrinnene ( backend ) skal ændres fra mål til mål. (For mere information om kompilerdesign, se Compiler .)

Input til kodegeneratoren består typisk af et parsetræ eller et abstrakt syntakstræ . Træet konverteres til en lineær sekvens af instruktioner, sædvanligvis i et mellemsprog som f.eks. Tre-adresse kode . Yderligere stadier af kompilering omtales måske eller ikke som "kodegenerering", afhængigt af om de involverer en væsentlig ændring i programmets repræsentation. (For eksempel vil et kighul -optimeringspas sandsynligvis ikke blive kaldt "kodegenerering", selvom en kodegenerator muligvis kan indeholde et kighul -optimeringspas.)

Store opgaver

Ud over den grundlæggende konvertering fra en mellemrepræsentation til en lineær sekvens af maskininstruktioner, forsøger en typisk kodegenerator at optimere den genererede kode på en eller anden måde.

Opgaver, der typisk er en del af en sofistikeret kompilers fase "kodegenerering", omfatter:

Instruktionsvalg udføres typisk ved at foretage en rekursiv postorder -transversal på det abstrakte syntakstræ, der matcher bestemte trækonfigurationer mod skabeloner; for eksempel træet W := ADD(X,MUL(Y,Z))kan blive omdannet til en lineær sekvens af instruktioner ved rekursivt at generere sekvenserne for t1 := Xog t2 := MUL(Y,Z), og derefter udsender instruktionen ADD W, t1, t2.

I en kompilator, der bruger et mellemsprog, kan der være to instruktionsvalgstrin - et til at konvertere parsetræet til mellemkode og en anden fase meget senere til at konvertere mellemkoden til instruktioner fra instruktionssættet på målmaskinen. Denne anden fase kræver ikke en træovergang; det kan gøres lineært og involverer typisk en simpel udskiftning af mellemsprogede operationer med deres tilsvarende opcodes . Men hvis kompilatoren faktisk er en sprogoversætter (f.eks. En, der konverterer Java til C ++ ), kan den anden kodegenereringsfase indebære at bygge et træ ud fra den lineære mellemkode.

Runtime -kodegenerering

Når kodegenerering sker ved runtime , som i just-in-time compilation (JIT), er det vigtigt, at hele processen er effektiv med hensyn til plads og tid. For eksempel, når regulære udtryk tolkes og bruges til at generere kode under runtime, genereres en ikke-deterministisk endelig tilstandsmaskine ofte i stedet for en deterministisk, fordi den førstnævnte normalt kan oprettes hurtigere og optager mindre hukommelsesplads end sidstnævnte. På trods af at den generelt genererer mindre effektiv kode, kan JIT -kodegenerering drage fordel af profilering af oplysninger, der kun er tilgængelige under runtime.

Relaterede koncepter

Den grundlæggende opgave med at tage input på ét sprog og producere output på et ikke-trivielt andet sprog kan forstås i form af transformationsoperationer i formel sprogteori . Følgelig er nogle teknikker, der oprindeligt blev udviklet til brug i kompilatorer, også blevet anvendt på andre måder. F.eks Yacc (Endnu en Compiler-compiler ) tager input i Backus-Naur formular og konverterer det til en parser i C . Selvom det oprindeligt blev oprettet til automatisk generering af en parser til en compiler, bruges yacc også ofte til at automatisere skrivekode, der skal ændres, hver gang specifikationerne ændres.

Mange integrerede udviklingsmiljøer (IDE'er) understøtter en eller anden form for automatisk kildekodegenerering , ofte ved hjælp af algoritmer til fælles med kompilatorkodgeneratorer, selvom de normalt er mindre komplicerede. (Se også: Programtransformation , datatransformation .)

Afspejling

Generelt forsøger en syntaks og semantisk analysator at hente programmets struktur fra kildekoden, mens en kodegenerator bruger denne strukturelle information (f.eks. Datatyper ) til at producere kode. Med andre ord tilføjer førstnævnte oplysninger, mens sidstnævnte mister nogle af oplysningerne. En konsekvens af dette tab af information er, at refleksion bliver vanskelig eller endda umulig. For at imødegå dette problem integrerer kodegeneratorer ofte syntaktiske og semantiske oplysninger ud over den kode, der er nødvendig for udførelse.

Se også

Referencer