finish overblik.md
Some checks failed
Check / Explore-Gitea-Actions (push) Failing after 8s

This commit is contained in:
sfja 2026-04-29 02:14:38 +02:00
parent 47913f928d
commit 007cc16873
5 changed files with 85 additions and 1 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

BIN
docs/images/mir_example.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
docs/images/mir_isel.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View File

@ -158,6 +158,10 @@ MIR er typestærkt ved at hver register har en associeret type. De fleste af dis
Det ses på illustrationen, hvordan let-statements bliver til `Alloca`-instruktioner, assignment (og initialisering) til `Store`-instruktioner, variabler til `Load`-instruktioner, integer literals til `Int`, return til `Return`, osv. Hver register skrives til én gang, som udgør SSA-formen. Hele koden er i Basic Block'en `bb0`. Det ses på illustrationen, hvordan let-statements bliver til `Alloca`-instruktioner, assignment (og initialisering) til `Store`-instruktioner, variabler til `Load`-instruktioner, integer literals til `Int`, return til `Return`, osv. Hver register skrives til én gang, som udgør SSA-formen. Hele koden er i Basic Block'en `bb0`.
![](./images/mir_example.png)<br>**Figur:** Eksempelprogram og dets genererede MIR. Her med compilerens syntaks-highlighting.
AST-sænkning er implementeret i `MiddleLowerer`-klassen defineret i [`src/middle.ts`](/src/middle.ts).
## MIR Control Flow-analyse ## MIR Control Flow-analyse
I dette trin analyseres control flow'et i MIR. Dette er primært et valideringstrin. Her fanges control flow-relaterede fejl såsom manglende return-statements. I dette trin analyseres control flow'et i MIR. Dette er primært et valideringstrin. Her fanges control flow-relaterede fejl såsom manglende return-statements.
@ -252,9 +256,89 @@ bb0:
Ikke implementeret. Ikke implementeret.
## MIR-fortolkning
Dette er ikke et inkluderet trin i kompileren. Dette komponent er en VM som fortolker programmer i MIR-repræsentation.
Fortolkeren er implementeret i en `FnInterpreter`-klasse defineret i [`src/mir_interpreter.ts`](/src/mir_interpreter.ts).
## MIR-sænkning / Low-level Intermediary Representation ## MIR-sænkning / Low-level Intermediary Representation
I dette trin sænkes programmet i MIR-form til en yderligere IR, LIR. MIR og LIR er ens på mange punkter, men med visse forskelle. Den største forskel er, at hvor MIR har high level-typer (`Ty`-typer) så har LIR et mere primitivt typesystem. I MIR, ligeledes i resten af det high-level typesystem er der forskel på signed og unsigned integers. I LIR er der ingen forskel, istedet er det signed og unsigned instruktioner. I dette trin sænkes programmet i MIR-form til en yderligere IR, LIR. MIR og LIR er ens på mange punkter, men med visse forskelle. Den største forskel er, at hvor MIR har high level-typer (`Ty`-typer) så har LIR et mere primitivt typesystem. I MIR, ligeledes i resten af det high-level typesystem er der forskel på signed og unsigned integers. I LIR er der ingen forskel, istedet er der signed og unsigned instruktioner.
Et eksempel på et program:
```rs
let a: i32 = 2 + 3;
let b: u32 = 2 + 3
```
i MIR-form:
```llvm
%a: *mut i32 = Alloca
%b: *mut u32 = Alloca
%0: i32 = Int 2
%1: i32 = Int 3
%2: i32 = Add %0, %1
Store [ptr %a] = %2
%3: u32 = Int 2
%4: u32 = Int 3
%5: u32 = Add %3, %4
Store [ptr %a] = %5
```
og i LIR-form:
```llvm
%a = Alloca i32, 1
%b = Alloca i32, 1
%0 = Int i32 2
%1 = Int i32 3
%2: i32 = Add signed %0, %1
Store [ptr %a] = %2
%3: u32 = Add unsigned %0, %1
Store [ptr %a] = %5
```
Dette er ikke implementeret. Pt. bliver MIR brugt de stedet LIR skal bruges.
## LIR-optimering
Formålet med dette trin er at forbedre outputtet af programmet. I det fleste tilfælde betyder dette laver ressourceforbrug, hurtigere afvikling og færre instruktioner. Dette trin består af en serie af undertrin. Undertrinnene samler specifikke informationer om programmet og omskriver repræsentationen. Trinnet kører igennem serien af undertrin flere gange.
Nogle optimeringer er platformuafhængige, mens andre er platformspecifikke eller er meget egnet til specifikke platforme. Hvilke optimizations man vælger at anvende, afhænger derfor af hvilket target man kompilerer til.
Ikke implementeret.
## Kodegenerering
De næste trin er platformafhængige. Formålet med kodegenerering er at producere et output ud fra LIR, som kan assembles og afvikles på target-platformen.
### X86_64
#### Instruction Selection
I dette trin bliver LIR sænket til X86_64 assembly-instruktioner. Outputtet af instruction selection kaldes ISEL. Stortset hver LIR-instruktion har en 1-til-1 assembly-konstruktion. Ofte bliver enkelte LIR-instruktioner til flere assembly-instruktioner.
![](./images/mir_isel_example.png)<br>**Figur:** Forhold mellem MIR og X86_64 ISEL.
![](./images/mir_isel_example.png)<br>**Figur:** Eksempelprogram med MIR og output fra Instruction Selection. Her med compilerens syntaks-highlighting.
Ligesom MIR og LIR har ISEL virtuelle registre (`%_`-registre). X86_64 har visse registre, som er reserverede. Derfor kan ISEL også specificere konkrete registre.
LIR er SSA, dvs. registre kun må assignes til én gang. I X86_64 er der tilfælde, hvor registre bruges som både input- og output-registre. Dette gælder eksempelvis `add`-instruktionen, hvor første operand både er venstre side og output. Derfor tillader ISEL at registre kan re-assignes.
Dette er implementeret i `selectFnInstructions`-funktionen defineret i [`src/codegen/x86_64/isel.ts`](/src/codegen/x86_64/isel.ts).
#### Peephole optimizations
I dette trin foretages der omskrivninger af ISEL-instruktionerne. Formålet er at omskrive konstruktioner, så programmet forbedres, uden at semantikkerne ændres.
Dette er ikke implementeret.
#### Register Allocation
I dette trin vælges hvilke registre programmet skal bruge. I ISEL-repræsentationen er nogle registre konkrete registre, og andre er virtuelle registre. Formålet med dette trin er at vælge hvilke konkrete registre, der skal bruges, istedet hvor virtuelle registre.
![](./images/isel_registor_allocation.jpg)<br>**Figur:** Forhold mellem ISEL og register allocation.
Dette er ikke implementeret.
[^1]: https://en.wikipedia.org/wiki/Interning_(computer_science) [^1]: https://en.wikipedia.org/wiki/Interning_(computer_science)