看板 CompilerDev 關於我們 聯絡資訊
LLVM大概是現在最受產業界以及學術界歡迎的編譯器框架之一了 很可惜的由於貢獻與參與的人數以接近指數倍的速度增長 專案本身結構的複雜度 也逐年增高,這邊就來提供一個簡單的專案結構導覽。 你主要可以學到兩個重點: - 常見的元件(e.g.優化演算法、register allocator)可以在哪邊找到? - LLVM命名以及安排資料夾的習慣是什麼 (這邊只涵蓋LLVM,其他子專案例如Clang,礙於篇幅以及筆者也不怎麼熟悉,就留到 未來再說吧) Top Level Strucutre (llvm-project/llvm) 有幾個資料夾是一定要知道的 /lib: LLVM 最大的優點之一就是模組化:所有的功能與演算法都被包成個別 的函式庫,使用者只需挑選他們需要的函式庫就可以了。而這個資料夾底下放的就是所有 LLVM的演算法。從非常專門的編譯器演算法(e.g. instruction selection),到非常通用 、可以給其他子專案用的的功能(e.g. FileSystem API)。等一下會就個別的子資料夾 進行介紹 /include: 所有的標頭檔都放在這兒。這底下還有兩個資料夾、llvm和llvm-c ,分別是 C++ 和 C API。LLVM 的API介面穩定性以及相容性(compability)一直都是個 有點大的問題,主要是因為核心成員希望整個計畫在開發上能夠越靈活越好、必然的結果 就是API interface會變化的非常快,導致其他使用者(downstream user)苦不堪言。目前 一個暫時的解決辦法就是不保證 C++ API 的穩定性、只維護 C API 的相容性,所以才會 有兩套 API 系統。(其實LLVM不只API,ABI介面的穩定性也是個長年困擾大家的問題 ,但那又是另外一個故事了) /test 與 /unittests: 前者是 regression test,後者是 unit tests 的資 料夾。Regression test 又暱稱 IR test,因為裡面大部分的測試輸入檔都是 textual IR。仍會叫 regression test 是因為那些 test case 大多源自於 bug。 Regression test是用一套叫做 llvm-lit 的 test runner 來跑的(以及一些附註工具 像是 FileCheck)。llvm-lit 還有 FileCheck 個人認為神好用,而且非常容易用在一般 的專案裡面,有機會可以寫一篇專門的文章。筆者認為這兩個資料夾很重要的原因在於 很多時候如果不知道某個元件的行為或用法(e.g. 不知道對應Pass的CLI option 怎麼下) 可以直接去查閱這些 test,還蠻實用的。 /tools: 只要是使用 LLVM libraries 的 command line tools 基本上都放 這邊。例如大家所熟知的 opt 和 llc,雖然這些 tools 原始碼量都不多、畢竟主要功能 都放在 library 裡面,但有些時候特定的功能,例如某個 CLI option,其實是放在這裡 。Clang 以前也是放在 tools 資料夾底下,但現在已經移到llvm-project最上層了 LLVM Libraries (llvm-project/llvm/lib) 這邊也是挑幾個重要的資料夾來講。大部分元件的標頭檔都會放在 include/llvm 裡 對應的資料夾、因此除非有特例要不然就不多贅述: /IR: 顧名思義這個資料夾放的就是所有的 IR 實作。但其實還不止那些, 其他重要的元件包括新的 PassManager(如大家所知,LLVM 目前已經快要完成遷移 到新的 PassManager,因此舊的 PassManager 現在已經改名為 IR/LegacyPassManager.cpp,而且將在不久之後完全移除),還有一些 "builder",例如 比較多人所熟知的 IRBuilder 以及 debug info builder (DIBuilder) /Passes: 承接上方關於新的PassManager的話題,這個資料夾放的是其他 有關(新版)Pass的元件,例如 PassBuilder 以及 PassRegistry.def。前者很重要是因為 很多時候你會想知道、例如 -O3 到底跑了哪些 Pass,這裡就可以給你一些指引。後者 則是新 PassManager 特有的東西,基本上就是新版的Pass註冊表。 /Transforms: 所有IR層級(也就是 target-independent)的優化演算法。 底下的資料夾簡介如下: - /InstCombine: 就是LLVM的 peephole optimization。老實講我還真的 不知到為啥最初不要命名成 peephole。 - /Vectorize: 顧名思義就是放所有關於 vectorize 的演算法。小弟在這 方面沒有研究得很透徹,但基本上目前 LLVM 使用兩大 vectorize 演算法:SLP 和 VPlan。SLP算是蠻經典的,沒記錯的話GCC也有,VPlan 則是比較新。 - /IPO: 所有的 inter-procedure 優化演算法。 - /Scalar: 基本上所有非前述類別的演算法都丟在這邊XDD (包括loop相關) 所以要找某個演算法就先從這個資料夾開始找吧。 其他蠻重要的還有 /Utils,放了很多超級實用的小功能、像是切割 basic block、還有 把特定一群的 basic block 抓出來變成獨立的函式。 ============= 本篇就先到這邊吧,下一篇會涵蓋剩下的 /lib 重要子資料夾(e.g. CodeGen, Analysis) 。還有其他實用的 utilities (e.g. include/llvm/ADT) -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 169.234.228.195 (美國) ※ 文章網址: https://www.ptt.cc/bbs/CompilerDev/M.1593371133.A.EA4.html
sonicyang: 好文推 06/29 18:36
frank030310: 感謝分享 讓我更了解llvm的架構 06/30 19:55
jerry0715no1: 感謝大神分享好文 07/01 12:51
Dracarys: 感謝分享 07/01 21:14
kishow01: 推推分享 07/02 04:40
SMMIT: 推分享 07/03 21:49
poolongkong: 感謝分享 順便勘誤一下,InstCombine的不知"到" 07/09 21:31
JameC: 推,受益良多 07/10 20:51
unimaybe: 用心,推推!! 06/26 03:56
eopXD: 推好文~~ 07/11 19:39