追溯llvm的歷史要追溯到10年前(2014),起初它着眼於編譯器的後端算法和中間表述(今天依然是llvm的重點),當時其餘部分還要依賴gcc。其中最重要的是它的IR,llvm在整個編譯的過程當中有不少種中間表示,如AST(C/C++轉換成IR的過程)、DAG(IR轉換成特定機器的彙編語言的過程)、某種特定的中間表示(彙編器和連接器使用)等其餘中間表示依然起到很重要的做用,可是,真正讓llvm不同凡響的仍是它的IR,甚至llvm這個名字的由來還和IR有很大的關係。html
首先看IR(intermediate representation)的特色:前端
其存在方式有兩種,一種在內存中,一種是在磁盤上,SSA可以更方便的優化,再加上保存在磁盤上的這種編碼方式可以達到幾近全時優化的效果,這也是llvm的做者在最先介紹llvm的論文中提出的目標,可是IR的描述能力畢竟有限,要想實現全時優化,就要求對諸如程序分佈這種行爲作出描述,這也意味着實現了此功能的llvm要像jvm那樣可以成爲一個運行平臺,相似jvm的名字,llvm這個名字就是這麼來的。java
隨着llvm項目的發展,其設計目標已經重點放在了經過磁盤上的IR操做實現連接時優化等功能,而不是全時優化,最終只保留了llvm這個名字,可是llvm已經成了一個強大的編譯器框架,而不是一個相似jvm的那樣的平臺。算法
說到這,說一下我的理解吧,感受是llvm起初提出了一個比較精妙的編碼表示方案,有利於一些編譯優化,進而發現能夠憧憬的的目標——全時優化,可是又發現實現全時優化比較困難,在llvm的mail list上有人專門就此發起了一個很詳細的討論,詳細闡述了llvm不能像java那樣成爲一個platform或者vm的緣由,重點仍是要作編譯器。後端
無論怎樣,llvm這麼名字仍是保留下來了,如今若是有人跟你提起「LLVM」,多是指如下內容:架構
LLVM框架主要包括三個方面的核心內容:框架
LLVM的編譯流程如圖:
每一個步驟中間交互有兩種介質:1) in-memory; 2) by-file,前者變現出來經過一些高層的工具如clang,自動進行指定的動做;後者能夠每一步每一步分離開來,經過一個個獨立的工具完成。frontend
如前文所述,可使用driver來自動完成一系列動做,對於代碼hello.c:jvm
#include <stdio.h> int main() { printf("Hello, World!\n"); return 0; }
直接編譯:工具
clang hello.c -o hello
便可經過clang來執行一系列編譯器的功能,直接生成可執行文件。
-###參數能夠查看clang調用了哪些工具:
clang -### hello.c -o hello