LLVM編譯器的基礎(chǔ)知識
1.LLVM編譯器是什么?
LLVM是 Illinois 大學(xué)發(fā)起的一個開源項目,LLVM 是 Low Level Virtual Machine (低級虛擬機)的簡稱,這個庫提供了與編譯器相關(guān)的支持,可以作為多種語言編譯器的后臺來使用。能夠進行程序語言的編譯期優(yōu)化、鏈接優(yōu)化、在線編譯優(yōu)化、代碼生成。LLVM的項目是一個模塊化和可重復(fù)使用的編譯器和工具技術(shù)的集合。
2.框架結(jié)構(gòu)

(1)不同的前端后端使用統(tǒng)一的中間代碼LLVM Intermediate Representation (LLVM IR)
(2)如果需要支持一種新的編程語言,那么只需要實現(xiàn)一個新的前端
(3)如果需要支持一種新的硬件設(shè)備,那么只需要實現(xiàn)一個新的后端
(4)優(yōu)化階段是一個通用的階段,它針對的是統(tǒng)一的LLVM IR,不論是支持新的編程語言,還是支持新的硬件設(shè)備,都不需要對優(yōu)化階段做修改
(5)相比之下,GCC的前端和后端沒分得太開,前端后端耦合在了一起。所以GCC為了支持一門新的語言,或者為了支持一個新的目標(biāo)平臺,就 變得特別困難
(6)LLVM現(xiàn)在被作為實現(xiàn)各種靜態(tài)和運行時編譯語言的通用基礎(chǔ)結(jié)構(gòu)(GCC家族、Java、.NET、Python、Ruby、Scheme、Haskell、D等)
3.什么是Clang
LLVM項目的一個子項目,基于LLVM架構(gòu)的C/C++/Objective-C編譯器前端
相比于GCC,Clang具有如下優(yōu)點
編譯速度快:在某些平臺上,Clang的編譯速度顯著的快過GCC(Debug模式下編譯>OC速度比GGC快3倍)
占用內(nèi)存小:Clang生成的AST所占用的內(nèi)存是GCC的五分之一左右
模塊化設(shè)計:Clang采用基于庫的模塊化設(shè)計,易于 IDE 集成及其他用途的重用
診斷信息可讀性強:在編譯過程中,Clang 創(chuàng)建并保留了大量詳細的元數(shù)據(jù) >(metadata),有利于調(diào)試和錯誤報告
設(shè)計清晰簡單,容易理解,易于擴展增強

編譯過程:
源代碼(c/c++)經(jīng)過clang--> 中間代碼(經(jīng)過一系列的優(yōu)化,優(yōu)化用的是Pass) --> 機器碼
4.LLVM與Clang的關(guān)系
對應(yīng)到這個圖2中,可以非常明確的找出它們的對應(yīng)關(guān)系。LLVM與Clang是C/C++編譯器套件。對于整個LLVM的框架來說,包含了Clang,因為Clang是LLVM的框架的一部分,是它的一個C/C++的前端。Clang使用了LLVM中的一些功能,目前知道的就是針對中間格式代碼的優(yōu)化,或許還有一部分生成代碼的功能。從源代碼角度來講,clang是基于LLVM的一個工具。而功能的角度來說,LLVM可以認為是一個編譯器的后端,而clang是一個編譯器的前端,他們的關(guān)系更加的明了,一個編譯器前端想要程序最終變成可執(zhí)行文件,是缺少不了對編譯器后端的介紹的。
5.LLVM編譯流程
?LLVM編譯一個源文件的過程:預(yù)處理 -> 詞法分析 -> Token -> 語法分析 -> AST -> 代碼生成 -> LLVM IR -> 優(yōu)化 -> 生成匯編代碼 -> Link -> 目標(biāo)文件

?????完全需要我們手工,或者依靠其他工具如lex, yacc來做的事情,是從源代碼到token的詞法分析和從token到AST的語法分析;詞法分析的輸出是將源代碼解析成一個個的token。這些token就是有類型和值的一些小單元,比如是關(guān)鍵字,還是數(shù)字,還是標(biāo)識符,從AST轉(zhuǎn)LLVM開始,LLVM就開始提供一系列的工具幫助我們快速開發(fā)。從IR(中間指令代碼)到DAG(有向無環(huán)圖)再到機器指令,針對常用的平臺,LLVM有完善的后端。也就是說,我們只要完成了到IR這一步,后面的工作我們就享有和Clang一樣的先進生產(chǎn)力了。