Du befindest dich hier: FSI Informatik » Prüfungsfragen und Altklausuren » Hauptstudiumsprüfungen » Lehrstuhl 2 » CB3 vom 14.04.2025
Inhaltsverzeichnis
CB3 vom 14.04.2025
- Prüfer: David Schwarzbeck, Prof. Philippsen
- Raum: Büro von Prof. Philippsen
- Note: 1.0
Gedächtnisprotokoll
Praktikum
Was haben wir im Blockpraktikum gemacht?
TVM Interpreter und JIT in unterschiedlichen Stufen
Wieso TVM und nicht zB e2-Ast?
AST kompliziert, viele Fälle für Traversierung x86 etc unschön weil zB self-modifying code
Was macht der Interpreter?
Große Schleife Instruktion lesen Großes Switch-Case Ausführen
Wie kann man das schneller machen?
Durchfädeln (erklärt)
Wieso haben wir zwei Stacks?
Interpreter hat einen, Interpretier Code auch
Was passiert dann mit Argumenten, wo landen die?
Erstmal nur im Interpreter für FFI, landen dann als lokale Variablen auf dem emulierten Stack
Wie geht das alles mit nem JIT schneller?
Erstmal Stackvergabe
Was passiert bei Calls?
Trampolin, Behandlung von Argumenten (prepare_call), gff Check ob native-code schon vorhanden
Aber alles aufm Stack ist doch uncool
Registervergabe, mit SCC und Linear Scan
Hab Kontrollflussgraph bekommen (bzw dann nach Schritt 1 den umgedrehten), einmal Kosarajus für SCCs durchexerzieren (linear scan wurde ich nicht gefragt)
Lebensspannen gehen dann von?
SCC-Graph topologisch sortieren, von niedrigster verwendeter Nummer bis höchster
Aber ein Kontrollflussgraph hat doch Zyklen!
Ja, aber die haben wir mit den SCCs eliminiert, bleibt nur noch ein DAG.
Linker/Lader
e2 hat jetzt ne externe stdlib: was passiert bei statischem Binden?
Objektdateien haben Symboltabelle für unaufgelöste Symbole (zB printf). Linker klebt Objects aneinander und löst dabei Symbole auf.
Wie machen wir das wenn wir nicht jedes mal executable neu bauen wollen?
Shared Libs
Was sind die Unterschiede von static und dynamic shared Libs?
static: Adressraum bekannt, gff Relokation (wie das funktioniert wollten sie sehr genau wissen) dynamic: loader setzt Adressen, PIC wichtig damit lib überall liegen kann. Zugriffe über GOT und PLT.
LLVM
Was ist LLVM?
IR und ganze Toolchain
Was ist cool daran?
Müssen nur ein Frontend bauen
Und am LLVM-IR direkt? was macht den besonders?
self-contained, keine Abhängigkeit an Frontend-Strukturen (vgl Gimple) unbegrenzt viele Register in SSA-Form typisiert (kein implizites Fallthrough) wusste ich nicht mehr
Aber selber SSA bauen ist doch blöd!
mem2reg, man macht selber nur stackbasiert, da muss man kein SSA einhalten
gibt Code (ca)
struct B { double arr[10]; }; struct A { int foo; struct B* bar; }; double bazz(struct A* p) { return p->foo + p->bar->arr[3]; }
define double @bazz(ptr %0) { %2 = load i32, ptr %0, align 8 %3 = sitofp i32 %2 to double %4 = getelementptr %struct.A, ptr %0, i64 0, i32 1 %5 = load ptr, ptr %4, align 8 %6 = getelementptr [10 x double], ptr %5, i64 0, i64 3 %7 = load double, ptr %6, align 8 %8 = fadd double %7, %3 ret double %8 }
Guck mal hier, was passiert hier? grade bei getelementptr.
Unbegrenzt Argumente, cool für mehrdimensionale Arrays. Hier für structs
Und warum wird da so oft dereferenziert?
getelementptr gibt nen Pointer auf das indizierte Datum, muss dann dereferenziert werden.
Bewertung
Angekreidet wurden fehlende/falsche Fachbegriffe und dass ich nicht mehr wusste, dass LLVM-IR keine impliziten Fallthroughs hat. „Wie schlimm waren die Fehler? Nicht schlimm genug um was an der Note zu ändern.“
