LLVM è un livello inferiore rispetto alle macchine virtuali tipiche come JVM e CLR. Ad esempio, mentre ha hook per un garbage collector, non fornisce un garbage collector.
Allo stesso modo, la JVM ha un compilatore JIT incorporato (tranne che in versioni veramente antiche). LLVM ha alcuni compilatori JIT per LLVM IR, ma è ancora compito dello sviluppatore collegare le cose insieme e in realtà JIT il codice.
Quando la JVM incontra un esterno non risolto, si spegne e trova la classe giusta per soddisfarlo e sa come cercare i file .class direttamente nel file system e nei file .jar 1 . I compilatori JIT di LLVM hanno degli hook in cui puoi decidere come gestire queste cose. Come previsto, alcune persone hanno scritto alcune versioni predefinite, quindi può fare le cose più o meno nello stesso ordine della JVM - ma puoi anche ignorarle e fare le cose diversamente se si sceglie.
In poche parole, se stai sviluppando un compilatore (o qualcosa del genere) ha molti strumenti per semplificarti la vita. Invece di preoccuparti molto dell'ottimizzazione, puoi fare approssimativamente la traduzione più semplice che puoi gestire dal tuo codice sorgente a LLVM IR, quindi utilizzare le librerie LLVM per gestire l'ottimizzazione, JIT, il collegamento, ecc. Tuttavia, sono librerie - fornisce alcune funzioni davvero utili in modo da non dover gestire tutti i dettagli, ma sono comunque funzioni e stai ancora scrivendo il codice per invocarle. Non è un prodotto finito, solo strumenti utili per la costruzione di prodotti in modo relativamente rapido e semplice.
1 Tecnicamente, non tutto questo è incorporato nella JVM propriamente detta. Specifica ciò che in genere viene chiamato il caricatore di classi primordiali come parte della JVM corretta, e quindi ci sono caricatori di classi utente specificati in java.util.ClassLoader che gestiscono altre cose. Alcuni caricatori di classi sono inclusi per impostazione predefinita e, se lo desideri, puoi integrare quelli definendone uno tuo.