LLVM自己並非編譯器,只是一套用於開發編譯器、解釋器等程序語言相關工具的庫,主要聚焦於編譯器後端功能,如代碼生成、代碼優化、JIT等。前端
LLVM1 an umbrella project that hosts and develops a set of close-knit low-level toolchain components (e.g., assemblers, compilers, debuggers, etc.) LLVM 是一個涵蓋和開發一系列緊密結合的低級工具鏈組件(例如,彙編器,編譯器,調試器等)的綜合項目objective-c
傳統的編譯器一般分爲三個部分,前端(frontEnd),優化器(Optimizer)和後端(backEnd),在編譯過程當中,前端主要負責詞法和語法分析,將源代碼轉化爲抽象語法樹;優化器則是在前端的基礎上,對獲得的中間代碼進行優化,使代碼更加高效;後端則是將已經優化的中間代碼轉化爲針對各自平臺的機器代碼。編程
Clang 是一個C、C++、Objective-C和Objective-C++編程語言的編譯器前端。它採用了LLVM做爲其後端。swift
Clang是2005年由蘋果電腦發起,是LLVM編譯器工具集的前端(front-end),目的是輸出代碼對應的抽象語法樹(Abstract Syntax Tree, AST),並將代碼編譯成LLVM Bitcode。接着在後端(back-end)使用LLVM編譯成平臺相關的機器語言 。Clang支持C、C++、Objective C。後端
Clang自己性能優異,其生成的AST所耗用掉的內存僅僅是GCC的20%左右,測試證實Clang編譯Objective-C代碼時速度爲GCC的3倍,還能針對用戶發生的編譯錯誤準確地給出建議。bash
Objective C採用Clang做爲前端,而Swift則採用swift()做爲前端,兩者LLVM(Low level vritual machine)做爲編譯器後端。編譯過程以下圖架構
來看看一個文件的編譯過程,新建Test.mapp
#import <Foundation/Foundation.h>
int main(){
@autoreleasepool {
NSLog(@"%@",@"Hello Leo");
}
return 0;
}
複製代碼
在終端輸入: clang -ccc-print-phases -framework Foundation test.m -o test
會看到下列的:編程語言
0: input, "Foundation", object
1: input, "test.m", objective-c
2: preprocessor, {1}, objective-c-cpp-output//預處理
3: compiler, {2}, ir //編譯生成IR(中間代碼)
4: backend, {3}, assembler//彙編器生成彙編代碼
5: assembler, {4}, object//生成機器碼
6: linker, {0, 5}, image//連接
7: bind-arch, "x86_64", {6}, image//生成Image,也就是最後的可執行文件
複製代碼
編譯器前端的任務是進行:語法分析,語義分析,生成中間代碼(intermediate representation )。在這個過程當中,會進行類型檢查,若是發現錯誤或者警告會標註出來在哪一行。函數
LVVM優化器會進行BitCode的生成,連接期優化等等
LLVM機器碼生成器會針對不一樣的架構,好比arm64等生成不一樣的機器碼
咱們在每次編譯事後,都會生成一個dsym文件。dsym文件中,存儲了16進制的函數地址映射。
在App實際執行的二進制文件中,是經過地址來調用方法的。在App crash的時候,第三方工具(Fabric,友盟等)會幫咱們抓到崩潰的調用棧,調用棧裏會包含crash地址的調用信息。而後,經過dSYM文件,咱們就能夠由地址映射到具體的函數位置。
咱們須要一個途徑,可以看到編譯的時間,這樣纔能有個對比,知道咱們的優化究竟有沒有效果。 對於XCode 8,關閉XCode,終端輸入如下指令 $ defaults write com.apple.dt.Xcode ShowBuildOperationDuration YES
@class CLASSNAME,而不是#import CLASSNAME.h。這樣,編譯器能大大提升#import的替換速度。
打包成Framework或者靜態庫,這樣編譯的時候這部分代碼就不須要從新編譯了。
XCode的pch文件是預編譯文件,這裏的內容在執行XCode build以前就已經被預編譯,而且引入到每個.m文件裏了。
上文提到了,dysm文件裏存儲了調試信息,在Debug模式下,咱們能夠藉助XCode和LLDB進行調試。因此,不須要生成額外的dsym文件來下降編譯速度。
在XCode -> Build Settings -> Build Active Architecture Only 改成YES。這樣作,能夠只編譯當前的版本,好比arm7/arm64等等,記得只開啓Debug模式。這個選項在高版本的XCode中自動開啓了。