簡介
LLVM 是一個編譯框架工具,是把編譯過程拆解成了高度標準化的組件。
本教程所使用的環境是windows11, vs2022
認識LLVM
LLVM 最成功的地方在於它定義了一種極其完美的中間語言LLVM IR,LLVM分為前端,優化器,後端:
- 前端:負責把源代碼(C/C++、Rust、Go)翻譯成 LLVM IR。比如
Clang。 - 優化器:這是 LLVM 的靈魂。它只處理 IR,不關心源碼是什麼語言,也不關心目標是什麼機器。你寫的 Pass 就運行在這裏。
- 後端:負責把優化後的 IR 翻譯成具體的機器碼(x86、ARM、RISC-V)。比如
LLC。
LLVM的三端架構,我們能夠很方便的自定義編譯器,本系類教程主要教學優化器的pass編寫
環境配置
需要準備的工具
- git : https://git-scm.com/install/ 拉取項目
- visual studio : https://visualstudio.microsoft.com/zh-hans/ 需要安裝
c/c++桌面開發組件,編譯環境 - cmake: https://cmake.org/ 構建項目
- ninja : https://github.com/ninja-build/ninja 加速編譯
拉取LLVM並配置
這裏我保存在D盤
#創建文件夾
mkdir D:\LLVM
cd D:\LLVM
#拉取源碼 (只拉取核心倉庫,不需要 submodule,現在 LLVM 是 monorepo)
#這一步比較大,網絡不好請掛梯子
git clone --depth=1 https://github.com/llvm/llvm-project.git
#創建構建目錄
cd llvm-project
mkdir build
cd build
構建並編譯
這裏需要打開剛剛下載好visual studio的工作台,我這裏是x64 Native Tools Command Prompt for VS 2022
注意:開始編譯需要預留30-60G硬盤空間,編譯需要30分鐘左右
#利用cmake構建項目
cmake -G "Ninja" ^ #使用ninja編譯
-DLLVM_ENABLE_PROJECTS="clang" ^ #只編譯clang節省空間
-DLLVM_TARGETS_TO_BUILD="X86" ^ #只編譯x86後端,這節省大部分編譯時間,除非要搞arm或者安卓
-DCMAKE_BUILD_TYPE="RelWithDebInfo" ^ #Relase版本無法調試,debug版本太大太慢了,這裏選擇帶調試符號的relase版本
-DLLVM_OPTIMIZED_TABLEGEN=ON ^
-DLLVM_ENABLE_ASSERTIONS=ON ^ #開啓代碼斷言。當pass寫錯時,會報錯而不是直接崩潰
../llvm
#編譯
ninja
添加環境變量
這一步方便之後的使用
#將剛剛編譯好的環境加入環境變量
D:\LLVM\llvm-project\build\bin
簡單驗證環境
clang --version
opt --version
一般來説,跟着上面步驟走 並且 系統和vs版本一樣到這是不會報錯的。
驗證環境
下面編譯一個test.c來驗證環境是否正常。
#include <stdio.h>
int add(int a, int b) {
return a + b + 5;
}
int main(){
printf("add(1, 2) = %d\n", add(1, 2));
return 0;
}
編譯代碼
C 編譯為LLVM IR
clang -S -emit-llvm -O0 test.c -o test.ll
觀察IR:
......
define dso_local i32 @main() #0 {
entry:
%retval = alloca i32, align 4
store i32 0, ptr %retval, align 4
%call = call i32 @add(i32 noundef 1, i32 noundef 2)
%call1 = call i32 (ptr, ...) @printf(ptr noundef @"??_C@_0BA@OMPDDIF@add?$CI1?0?52?$CJ?5?$DN?5?$CFd?6?$AA@", i32 noundef %call)
ret i32 0
}
......
LLVM IR 編譯為可執行文件
編譯為可執行文件並正常運行
clang test.c -o test.exe
如果❤喜歡❤本系列教程,就點個關注吧,後續不定期更新~