LLVM
什么是LLVM?
官網(wǎng):https://llvm.org/
The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
LLVM項目是模塊化屡立,可重用的編譯器與及工具鏈技術的技術
美國計算協(xié)會(ACM)將其2012年軟件系統(tǒng)獎項頒給了LLVM念颈,之前曾經(jīng)獲得此獎項的軟件和技術包括:Java,Apache卵慰,Mosaic沙郭,the World Wide Web,Smalltalk,UNIX,Eclipse等等
傳統(tǒng)的編譯器架構
Frontend:前端
詞法分析,語法分析裳朋,語義分析病线,生成中間代碼
Optimizer:優(yōu)化器
中間代碼優(yōu)化
Backend:后端
生成機器碼
LLVM架構
不同的前端后端使用統(tǒng)一的中間代碼LVM Intermediate Repressentation(LLVM IR);
如果需要支持一種新的變成語言鲤嫡,那額只需要實現(xiàn)一個新的前端送挑;
如果需要支持一種新的硬件設備,那額只需要實現(xiàn)一個新的后端暖眼;
優(yōu)化階段是一個通用的極端惕耕,它針對的是統(tǒng)一的LLVM IR,不論是支持新的變成語言罢荡,還是支持新的硬件設備赡突,都不需要對優(yōu)化階段做修改对扶;
相比之下,GCC的前端和后端沒分得太開惭缰,前端后端耦合在一起浪南,所以GCC為了支持一門新的語言或者為了支持一個新的目標平臺,就變得特別困難漱受;
LLVM現(xiàn)在被作為實現(xiàn)各種靜態(tài)和運行時編譯語言的通用基礎結構(GCC家族络凿,Java,.NET,Python,Ruby,Scheme,Haskell,D等)
Clang
什么是Clang昂羡?
LLVM項目的一個子項目絮记;
基于LLVM架構的C/C++/Objective-C編譯器前端;(官網(wǎng):http://clang/llvm.org)
相比于GCC虐先,Clang具有如下優(yōu)點
編譯速度快怨愤,在某些平臺上,Clang的編譯速度顯著快過GCC(Debug模式下OC速度比GCC塊3倍)蛹批;
占用內(nèi)存凶础:Clang生成的AST所占用的內(nèi)存是GCC的五分之一左右;
模塊化設計:Clang采用基于庫的模塊化設計腐芍,易于IDE繼承及其他用途的重用差导;
診斷信息可讀性強:在編譯過程中若河,Clang創(chuàng)建并保留了大量詳細的元數(shù)據(jù)(metadata),有利于調(diào)試和錯誤報告勺择;
設計清晰簡單躬它,容易理解蒸播,易于擴張增強;
Clang與LLVM
OC源文件的編譯過程
clang -ccc-print-phases main.m
查看preprocessor預處理的結果:$clang -E main.m
可以發(fā)現(xiàn)在預編譯階段茎活,就已經(jīng)將宏定義給替換了
詞法分析
詞法分析仍劈,生成Token: $clang -fmodules -E -Xclang -dump-tokens main.m
語法樹-AST
語法分析娄猫,生成語法樹(AST,AbstractSyntax Tree):$clang -fmodules -fsyntax-only -Xclang -ast-dump main.m
LLVM IR
LLVM IR有3種表示形式(但本質(zhì)是等價的项玛,就好比水可以有氣體貌笨,液體,固體等3中形態(tài))
clang -S -emit-llvm main.m
text:便于閱讀的文本格式襟沮,類似于匯編語言,擴展名.II
參數(shù)解釋:
1.注釋以分號昌腰;開頭
2.全局標志符以@開頭开伏,局部標識符以%開頭
3.alloca,在當前函數(shù)棧幀中分配內(nèi)存
4.i32,32bit,4個字節(jié)的意思
5.align遭商,內(nèi)存對齊
6.store固灵,寫入數(shù)據(jù)
7.load,讀取數(shù)據(jù)
官方語法參考
https://llvm.org/docs/LangRefhtml
memory:內(nèi)存格式
clang -c -emit-llvm main.m
bitcode:二進制格式劫流,擴展名為.bc
LLVM 源碼下載
下載LLVM
$ git clone https://git.llvm.org/git/llvm.git/
下載clang
cd llvm/tools
git clone https://git.llvm.org/git/clang.git
源碼編譯
安裝cmake和ninja(先安裝brew巫玻,https://brew.sh)
brew install cmake
brew install ninja
ninja如果安裝失敗丛忆,可以直接從github獲取release版放入[/usr/local/bin]中
https://github.com/ninja-build/ninja/releases
在LLVM源碼同級目錄下新建一個[llvm_build]目錄(最終會在[llvm_build]目錄下生成[build.ninja])
cd llvm_build
cmake -G Ninja ../llvm -DCMAKE_INSTALL_PREFIX=LLVM的安裝路徑
更多cmake相關選項,可以參考:https://llvm.org/docs/CMake.html
依次執(zhí)行編譯仍秤,安裝指令
ninja
編譯完畢后熄诡,【llvm_build】目錄大概21.05G(僅供參考)
ninja install
安裝完畢后,安裝目錄大概11.92G(僅供參考)
源碼編譯
也可以生成Xcode項目再進行編譯诗力,但是速度很慢(可能需要1個多小時)
在llvm同級目錄下新建一個[llvm_xcode]目錄
cd llvm_xcode
cmake -G Xcode ../llvm
應用與實踐
libclang凰浮、libTooling
官方參考:https://clang.llvm.org/docs/Tooling.html
應用:語法樹分析,語言轉換等
Clang插件開發(fā)
官方參考
https://clang.llvm.org/docs/ClangPlugins.html
https://clang.llvm.org/docs/ExternalClangExamples.html
https://clang.llvm.org/docs/RAVFontendAction.html
引用:代碼檢查(命名規(guī)范苇本,代碼規(guī)范)
Pass開發(fā)
官方參考:https://llvm.org/docs/WritingAnLLVMPass.html
應用:代碼優(yōu)化袜茧,代碼混淆等
開發(fā)新的編程語言
https://llvm-tutorial-cn.readthedocs.io/en/latest/index.html
https://kaleidoscope-llvm-tutorial-zh-cn.readthedocs.io/zh_CN/latest/
參考資料
?關于AST的資料
https://clang.llvm.org/doxygen/namespaceclang.htmlp https://clang.llvm.org/doxygen/classclang_1_1Decl.htmlp https://clang.llvm.org/doxygen/classclang_1_1Stmt.html
參考書籍:
《編譯原理》
《LLVM CookBook》