LLVM: Die problematischen Seiten
(npopov.com)- Analysiert die strukturellen Grenzen und technischen Schulden des LLVM-Projekts aus verschiedenen Blickwinkeln und benennt konkret Bereiche mit Verbesserungsbedarf
- Zeigt Engpässe beim Betrieb eines großen Open-Source-Projekts auf, darunter fehlende Reviews, API-Instabilität, Build- und Kompilierzeiten sowie instabile CI
- Zu den Problemen im IR-Design zählen die Behandlung von
undef-Werten, die Kodierung von Einschränkungen, die Semantik von Gleitkommazahlen und unvollständige Spezifikationen - Weist auf langfristige strukturelle Probleme hin, etwa Heterogenität der Backends, Verwirrung bei der ABI-Behandlung und verzögerte Migration von GlobalISel und Pass-Manager
- Stellt LLVM nicht pauschal negativ dar, sondern als Chance für kontinuierliche Verbesserungen und breitere Beiträge
Wichtige strukturelle Probleme
-
Mangelnde Review-Kapazität wird als größter Engpass genannt
- Es gibt viele Autoren, aber zu wenige Reviewer, sodass in manchen Fällen nicht ausreichend geprüfte Änderungen gemergt werden
- Da Review-Anfragen in der Verantwortung der Autoren liegen, fällt es neuen Beitragenden schwer, die passenden Reviewer zu finden
- Als mögliche Verbesserung wird die Einführung des automatischen PR-Zuweisungssystems von Rust genannt
-
Häufige Änderungen (Churn) an API und IR belasten die Nutzer
- Die C-API ist vergleichsweise stabil, die C++-API ändert sich jedoch häufig, was die Wartungskosten für Frontends und Backends erhöht
- Durch die Philosophie „Upstream or GTFO“ fließt nicht geteilter Code nicht in Entscheidungen ein
-
Problematisch sind die langen Build-Zeiten
- LLVM besteht aus mehr als 2,5 Millionen Zeilen C++-Code, wodurch Builds sehr lange dauern; bei Debug-Builds steigen Speicher- und Festplattenverbrauch stark an
- Als Verbesserungsansätze werden Precompiled Headers (PCH), dylib als Standard-Build und Daemonisierung von Tests diskutiert
-
Instabile CI
- Mehr als 200 Buildbots testen in unterschiedlichen Umgebungen, können aber nicht dauerhaft einen „grünen Zustand“ halten
- Flaky Tests und Probleme mit Buildbots verwässern Warnsignale, sodass echte Fehler schwer zu erkennen sind
- Die Einführung von Tests vor dem PR-Merge hat teilweise geholfen, eine grundlegende Lösung fehlt jedoch weiterhin
-
Mangel an End-to-End-Tests
- Unit-Tests für einzelne Optimierungen sind solide, aber Tests für die gesamte Pipeline oder die Integration mit Backends fehlen fast vollständig
llvm-test-suiteexistiert zwar, deckt grundlegende Kombinationen aus Operationen und Datentypen aber nicht ausreichend ab
Probleme bei Backends und Performance
-
Heterogenität zwischen Backends
- Die mittleren Ebenen sind vereinheitlicht, bei den Backends gibt es jedoch viele targetspezifische Einzelanpassungen, was Duplizierung und Verzweigung erhöht
- Statt gemeinsamer Optimierungen werden häufig target-spezifische Hooks ergänzt
-
Kompilierzeit
- Langsam bei JITs und bei Sprachen, die große IR-Mengen erzeugen (Rust, C++)
-O0-Builds sind besonders langsam; das TPDE-Backend wird als bis zu 10- bis 20-mal schnellere Alternative genannt
-
Fehlendes Performance-Tracking
- Es gibt keine offizielle Infrastruktur zur Verfolgung der Laufzeit-Performance
- Das LNT-System ist wegen instabilem Betrieb, UX-Problemen und Datenmangel nur eingeschränkt wirksam
Probleme im IR-Design
-
Komplexe Behandlung von
undef-Werten- Sie können bei jeder Verwendung einen anderen Wert annehmen und dadurch bei Optimierungen Fehler verursachen
- Künftig könnten sie durch poison-Werte ersetzt werden, allerdings ist die Behandlung von poison im Speicher noch unzureichend
-
Unvollständige und inkonsistente Spezifikation
- Es gibt seit Langem ungelöste Fehlverhaltensfälle
- Hinzu kommen konzeptionell schwierige Probleme wie das Provenance-Modell
- Zu deren Lösung wurde eine Arbeitsgruppe für formale Spezifikation eingerichtet
-
Fehlende Konsistenz bei der Kodierung von Einschränkungen
- Poison-Flags, Metadaten, Attribute und Assumes werden in unterschiedlichen Formen parallel verwendet
- Informationsverlust oder übermäßiger Erhalt von Informationen wirken sich negativ auf Optimierungen aus
-
Probleme bei der Gleitkomma-(FP-)Semantik
- Bei signaling NaNs, nicht standardisierten Umgebungen, Denormal-Behandlung und x87-Überpräzision treten Inkonsistenzen auf
- Die separate Behandlung über eingeschränkte FP-Intrinsics erhöht die Komplexität zusätzlich
Weitere technische Probleme
-
Verzögerte partielle Migrationen
- Der neue Pass-Manager wird nur bis zur mittleren Ebene eingesetzt, Backends verwenden weiterhin die alte Variante
- GlobalISel ist auch nach zehn Jahren nicht vollständig umgestellt und existiert parallel zu SDAG
-
Verwirrung bei ABI- und Calling-Convention-Behandlung
- Die Aufgabentrennung zwischen Frontend und Backend ist unklar und schlecht dokumentiert
- Die Einführung einer ABI-Bibliothek sowie ein Prototyp befinden sich in Arbeit
- Es gibt zudem das Problem, dass sich die ABI je nach aktivierten Target-Features ändert
-
Inkonsistente Verwaltung von Built-in-Funktionen und libcalls
- TargetLibraryInfo und RuntimeLibcalls sind getrennt, was zu mangelnder Konsistenz führt
- Es gibt kein Bewusstsein für die Verfügbarkeit je nach Laufzeitbibliothekstyp (
libgcc,compiler-rtusw.) - Es fehlen Anpassungspunkte für externe Laufzeiten wie Rust
-
Ineffiziente Context-/Module-Struktur
- Typen und Konstanten liegen im Context, Funktionen und Globals im Module
- Da kein Zugriff auf das Data Layout möglich ist, ist etwa Constant Folding umständlich
- Kontextübergreifendes Linken ist nicht möglich; die Struktur muss vereinfacht werden
-
Registerdruck durch LICM (Loop-Invariant Code Motion)
- Hoisting wird bedingungslos ohne Kostenmodell durchgeführt
- Da das Backend nicht erneut sinkt, nehmen Spills und Reloads zu
Fazit
- Die aufgelisteten Probleme sind strukturelle Herausforderungen, die aus Reifegrad und Größe von LLVM resultieren, und werden als Chance zur Verbesserung der Projektqualität und der Erfahrung von Beitragenden dargestellt
- In einigen Bereichen (Build-Optimierung, ABI-Bibliothek, Performance-Tracking usw.) laufen bereits Verbesserungsarbeiten
- Insgesamt ist LLVM weiterhin leistungsfähig, aber kontinuierliches Refactoring und eine Bereinigung der Spezifikation sind unerlässlich
Noch keine Kommentare.