Perché la rappresentazione intermedia di LLVM (LLVM IR) assomiglia piuttosto che ad un albero?
In alternativa, perché le implementazioni linguistiche hanno come obiettivo LLVM IR anziché l'AST di clang?
Non sto provando a fare due domande diverse contemporaneamente se sembra così. A me sembra semplicemente che sia i programmatori di client che quelli di biblioteche abbiano raggiunto il consenso sul fatto che l'API di LLVM, niente di più e niente di meno, è ovviamente una buona progettazione del software e la mia domanda è "perché?".
Il motivo per cui lo chiedo è che sembra che LLVM possa fornire più funzionalità ai frontend se l'IR fosse simile ad AST perché allora gli strumenti basati su AST di clang potrebbero essere usati per qualsiasi frontend. In alternativa, le lingue che hanno come target LLVM IR potrebbero ottenere più funzionalità se prendessero di mira l'AST di clang.
Clang ha classi e funzioni per creare e lavorare con AST ed è l' unico progetto frontend fortemente legato al progetto LLVM, quindi perché la funzionalità AST di clang è esterna a LLVM?
Dalla parte superiore della mia testa, so che Rust (rustc), D (ldc) e Haskell (GHC) possono tutti usare LLVM come backend ma non usano il Clang AST (per quanto ne so, potrei sbagliarsi). Non conosco tutti i dettagli interni di questi compilatori, ma almeno Rust e D sembrano certamente essere compilati per l'AST di Clang. Forse potrebbe anche Haskell, ma ne sono molto meno sicuro.
È a causa di ragioni storiche (LLVM era in origine una "macchina virtuale di basso livello" e il clanging arrivava più tardi)? Questo perché altri frontend vogliono avere il maggior controllo possibile su ciò che forniscono a LLVM? Ci sono ragioni fondamentali per cui l'AST di clang è inappropriato per le lingue "non-C-like"?
Non intendo che questa domanda sia un esercizio di lettura mentale. Voglio solo che sia utile per quelli di noi che sono curiosi di conoscere, ma non sono già fluenti, nel design del compilatore. Poiché i progetti LLVM e clang sono sviluppati in pubblico, spero che qualcuno che abbia familiarità con lo sviluppo di questi progetti possa rispondere o che la risposta sia abbastanza ovvia per alcuni nerd di compilazione che si sentono abbastanza sicuri per rispondere.
Per anticipare alcune risposte ovvie ma insoddisfacenti:
Sì, avere un IR simile ad un assembly dà più controllo a chiunque crea l'IR (forse X lang ha una base di codice e un formato AST migliori di clang) ma se questa è l'unica risposta, allora la domanda diventa "perché LLVM ha solo un assembly- come IR invece di un IR ad alto livello simile ad un albero e un IR di basso livello simile ad un assieme? ".
Sì, non è così difficile analizzare un linguaggio di programmazione in un AST (almeno rispetto alle altre fasi della compilazione). Anche così, perché usare AST separati? Se non altro, l'utilizzo dello stesso AST ti consente di utilizzare strumenti che funzionano su AST (anche solo cose semplici come le stampanti AST).
Sì, sono pienamente d'accordo sul fatto che essere più modulari sia una buona cosa, ma se questa è l'unica ragione, allora perché altre implementazioni linguistiche tendono a colpire LLVM IR anziché l'AST di clang?
Queste prelazioni potrebbero essere errate o trascurare i dettagli, quindi sentiti libero di dare queste risposte se hai maggiori dettagli o i miei presupposti sono sbagliati.
Per chiunque voglia rispondere a una domanda con una risposta più definitiva: quali sono i vantaggi e gli svantaggi di un IR simile ad un assemblaggio rispetto a un IR simile ad un albero?