架构编译器框架系统 LLVM 使用简介
2019獨角獸企業重金招聘Python工程師標準>>>
LLVM 是什么
LLVM 是 low level virtual machine(底層虛擬機)的簡稱,它是一個開源的編譯器架構,已經被成功應用到多個應用領域。LLVM 的主要作用是它可以作為多種語言的后端,它可以提供可編程語言無關的優化和針對很多種CPU的代碼生成功能。LLVM 核心庫提供了與編譯器相關的支持,可以作為多種語言編譯器的后臺來使用。能夠進行程序語言的編譯期優化、鏈接優化、在線編譯優化、代碼生成。LLVM的項目是一個模塊化和可重復使用的編譯器和工具技術的集合。LLVM是伊利諾伊大學的一個研究項目,提供一個現代化的,基于SSA的編譯策略能夠同時支持靜態和動態的任意編程語言的編譯目標。自那時以來,已經成長為LLVM的主干項目,由不同的子項目組成,其中許多正在生產中使用的各種 商業和開源的項目,以及被廣泛用于學術研究。
LLVM 常用命令工具
llvm-as 將可讀的 .ll 文件匯編成字節代碼
llvm-dis 將字節代碼文件反編成可讀的 .ll 文件
opt 在一個字節代碼文件上運行一系列的 LLVM 到 LLVM 的優化
llc 為一個字節代碼文件生成本機器代碼
lli 直接運行使用 JIT 編譯器或者解釋器編譯成字節代碼的程序
llvm-link 將幾個字節代碼文件連接成一個
llvm-ar 打包字節代碼文件
llvm-ranlib 為 llvm-ar 打包的文件創建索引
llvm-nm 在 字節代碼文件中打印名字和符號類型
llvm-prof 將 'llvmprof.out' raw 數據格式化成人類可讀的報告
llvm-ld 帶有可裝載的運行時優化支持的通用目標連接器
llvm-config 打印出配置時 LLVM 編譯選項、庫、等等
llvmc 一個通用的可定制的編譯器驅動
llvm-diff 比較兩個模塊的結構
bugpoint 自動案例測試減速器
llvm-extract 從 LLVM 字節代碼文件中解壓出一個函數
llvm-bcanalyzer 字節代碼分析器 (分析二進制編碼本身,而不是它代表的程序)
FileCheck 靈活的文件驗證器,廣泛的被測試工具利用
tblgen 目標描述閱讀器和生成器
lit??? LLVM 集成測試器,用于運行測試
LLVM IR
根據編譯原理可知,編譯器不是直接將源語言翻譯為目標語言,而是翻譯為一種“中間語言”,即“IR”。之后再由中間語言,利用后端程序和設備翻譯為目標平臺的匯編語言。由于中間語言相當于一款編譯器前端和后端的“橋梁”,不同編譯器的中間語言IR是不一樣的,而IR可以說是集中體現了這款編譯器的特征。
LLVM IR主要有三種格式:一種是在內存中的編譯中間語言;一種是硬盤上存儲的二進制中間語言(以.bc結尾),最后一種是可讀的中間格式(以.ll結尾)。這三種中間格式是完全相等的。
LLVM IR是LLVM優化和進行代碼生成的關鍵。根據可讀的IR,我們可以知道再最終生成目標代碼之前,我們已經生成了什么樣的代碼。而且根據IR,我們可以選擇使用不同的后端而生成不同的可執行代碼。同時,因為使用了統一的IR,所以我們可以重用LLVM的優化功能,即使我們使用的是自己設計的編程語言。
結構化編譯器前端 Clang 介紹
Clang ( 發音為 /kl??/) 是 LLVM 的一個編譯器前端,它目前支持 C, C++, Objective-C 以及 Objective-C++ 等編程語言。Clang 對源程序進行詞法分析和語義分析,并將分析結果轉換為 Abstract Syntax Tree ( 抽象語法樹 ) ,最后使用 LLVM 作為后端代碼的生成器。
Clang 的開發目標是提供一個可以替代 GCC 的前端編譯器。與 GCC 相比,Clang 是一個重新設計的編譯器前端,具有一系列優點,例如模塊化,代碼簡單易懂,占用內存小以及容易擴展和重用等。由于 Clang 在設計上的優異性,使得 Clang 非常適合用于設計源代碼級別的分析和轉化工具。Clang 也已經被應用到一些重要的開發領域,如 Static Analysis 是一個基于 Clang 的靜態代碼分析工具。
由于 GNU 編譯器套裝 (GCC) 系統龐大,而且 Apple 大量使用的 Objective-C 在 GCC 中優先級較低,同時 GCC 作為一個純粹的編譯系統,與 IDE 配合并不優秀,Apple 決定從零開始寫 C family 的前端,也就是基于 LLVM 的 Clang 了。Clang 由 Apple 公司開發,源代碼授權使用 BSD 的開源授權。
Clang 的特性:
相比于 GCC,Clang 具有如下優點:
1. 編譯速度快:在某些平臺上,Clang 的編譯速度顯著的快過 GCC。
2. 占用內存小:Clang 生成的 AST 所占用的內存是 GCC 的五分之一左右。
3. 模塊化設計:Clang 采用基于庫的模塊化設計,易于 IDE 集成及其他用途的重用。
4. 診斷信息可讀性強:在編譯過程中,Clang 創建并保留了大量詳細的元數據 (metadata),有利于調試和錯誤報告。
5. 設計清晰簡單,容易理解,易于擴展增強。與代碼基礎古老的 GCC 相比,學習曲線平緩。
當前 Clang 還處在不斷完善過程中,相比于 GCC, Clang 在以下方面還需要加強:
1. 支持更多語言:GCC 除了支持 C/C++/Objective-C, 還支持 Fortran/Pascal/Java/Ada/Go 和其他語言。Clang 目前支持的語言有 C/C++/Objective-C/Objective-C++。
2. 加強對 C++ 的支持:Clang 對 C++ 的支持依然落后于 GCC,Clang 還需要加強對 C++ 提供全方位支持。
3. 支持更多平臺:GCC 流行的時間比較長,已經被廣泛使用,對各種平臺的支持也很完備。Clang 目前支持的平臺有 Linux/Windows/Mac OS。
本段內容參考:http://www.ibm.com/developerworks/cn/opensource/os-cn-clang/
Clang 編譯選項
clang??? [-c|-S|-E] -std=standard -g
???????? [-O0|-O1|-O2|-O3|-Ofast|-Os|-Oz|-O|-O4]
???????? -Wwarnings... -pedantic
???????? -Idir... -Ldir...
???????? -Dmacro[=defn]
???????? -ffeature-option...
???????? -mmachine-option...
???????? -o output-file
???????? -stdlib=library
???????? input-filenames
大部分選項與 gcc 類似:
-c 只是編譯不鏈接,生成目標文件“.o”
-S 只是編譯不匯編,生成匯編代碼
-E 只進行預編譯,不做其他處理
-g 在可執行程序中包含標準調試信息
-o file 把輸出文件輸出到file里
-I dir 在頭文件的搜索路徑列表中添加dir目錄
-L dir 在庫文件的搜索路徑列表中添加dir目錄
中間碼的創建與轉化
編譯生成二進制的 .bc 文件(bitcode file): clang -emit-llvm -c xx.c -o xx.bc
編譯生成 LLVM 的匯編代碼 .ll 文件( LLVM assembly code): clang -emit-llvm -S xx.c -o xx.ll
.bc 和 .ll 文件都可以直接用 lli 來執行。
將 .ll 文件轉化為 .bc 文件: llvm-as test.ll
將 .bc 文件轉化為 .ll 文件: llvm-dis test.bc
將 .bc 或 .ll 文件轉化為本機平臺的匯編代碼: llc test.bc llc test.ll llc test.bc -o test.s
即時編譯器 JIT 簡介
LLVM 中間碼的執行需要用到 Jit。那么,JIT到底是個什么東西呢。其實,JIT 是一個即時編譯器,即 Just-in-time Compiler。對于 JIT 的了解我也知之勝少,它的作用大概就是對中間碼進行編譯作業,像 JAVA 這種跨平臺的語言也是通過 JIT 實現的。在執行 LLVM 的 lli 工具時,會去調用 JIT 將中間碼編譯成本機架構的機器碼再執行。
至于 jit 與 mcjit 的區別,大概是 jit 是 LLVM 舊版本的支持,而 mcjit 是對 jit 新的支持。mc是機器碼的意思,即 Machine Code。在 Wikipedia 看到說,以前的 LLVM 會依賴與本機系統的匯編器或者提供一套工具鏈,然后再翻譯成機器碼。而通過整合過的 LLVM MC 能夠支持大多數的機器架構,包括 x86, x86-64, ARM, ARM64 以及 大部分的 MIPS 架構等。
轉載于:https://my.oschina.net/kuanghy/blog/495084
總結
以上是生活随笔為你收集整理的架构编译器框架系统 LLVM 使用简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转载-ubuntu搭建Git 服务器
- 下一篇: 关于Yii2中CSS,JS文件的引入心得