量)
倉頡 LLVM 測試體系完全指南lit 與 FileCheck 如何保障 CJ Pass 質(zhì)量【免費下載鏈接】llvm-projectLLVM 項目是一個模塊化、可復用的編譯器及工具鏈技術的集合。此fork用于添加倉頡編譯器的功能并支持倉頡編譯器項目。項目地址: https://gitcode.com/Cangjie/llvm-project倉頡 LLVM 測試體系基于 LLVM 項目成熟的 lit FileCheck 測試框架為本倉頡編譯器 fork 中新增的 CJ 系列優(yōu)化 Pass 提供自動化的正確性驗證每提交一次代碼llvm/test/Transforms/ 下的測試就會驅(qū)動opt執(zhí)行 Pass再用 FileCheck 逐行比對 IR 輸出確保 CJ Pass 行為穩(wěn)定可控。本文帶你快速理解這套測試體系的構成與原理。為什么 CJ Pass 需要專門的測試體系CJ PassCangjie Pass是倉頡編譯器 fork 在標準 LLVM 之上新增的一系列 IR 優(yōu)化 Pass源碼集中在 llvm/lib/Transforms/Scalar/ 與 llvm/lib/Transforms/IPO/ 目錄下例如Pass源碼位置作用CJBarrierOptCJBarrierOpt.cpp內(nèi)存屏障優(yōu)化CJSimpleOptCJSimpleOpt.cpp通用簡單指令優(yōu)化CJStringPoolMergeCJStringPoolMerge.cpp字符串池合并CJDevirtualOptCJDevirtualOpt.cpp去虛函數(shù)調(diào)用優(yōu)化CJPartialEscapeAnalysisCJPartialEscapeAnalysis.cpp部分逃逸分析編譯器 Pass 的輸入輸出是復雜的中間表示IR一次錯誤的變換可能悄悄破壞程序語義。因此倉頡 LLVM 測試體系借鑒 LLVM 的做法用可復現(xiàn)的 IR 輸入 期望的輸出片段把每個 Pass 的行為釘死。下圖展示了編譯器工具鏈的整體流程Pass 正是作用在 IR 變換這一環(huán)節(jié)lit自動化測試執(zhí)行器llvm/test/lit.cfg.py 是 LLVM 測試套件的總配置文件它告訴 litLLVM Integrated Tester識別哪些后綴是測試文件默認包含.ll、.c、.s、.mir、.yaml等見 lit.cfg.py 中的config.suffixes準備運行環(huán)境把構建出的opt、FileCheck等工具加入 PATH解析每個測試頭部的RUN行按指令執(zhí)行并收集結果。CJ Pass 的測試目錄與 Pass 一一對應例如 llvm/test/Transforms/CJBarrierOpt/、llvm/test/Transforms/CJInlineCache/ 等共 17 個 CJ 相關測試目錄。運行方式通常是lit llvm/test/Transforms/CJBarrierOpt # 只跑某個 Pass 的測試 lit llvm/test/Transforms -v # 帶詳細輸出調(diào)試 小技巧lit 支持按路徑篩選測試新增 CJ Pass 時先跑舊測試確認全綠再補充新測試可顯著降低誤判成本。FileCheck逐行驗證編譯器輸出FileCheck 是 lit 測試體系中的判卷老師。它不關心完整的輸出只檢查期望的模式是否按順序出現(xiàn)。以最典型的 vcall.ll 為例它測試內(nèi)聯(lián)緩存 Pass 能否把虛調(diào)用改寫為直接調(diào)用; RUN: opt -S --iv-call-inline-cache-enabletrue -passescj-runtime-lowering \ ; --cj-ic-input-file%S/inputfile/VCallProfileOutput.txt %s | FileCheck %sRUN 行把opt的執(zhí)行結果通過管道交給 FileCheck。隨后測試文件里散布著一組CHECK斷言vcall.ll; CHECK: %2 call i8* CJ_MCC_GetObjClass(i8 addrspace(1)* %a) ; CHECK: br i1 %4, label %if.true.call_direct, label %if.false.call_virtual ; CHECK: if.true.call_direct:這 3 行斷言的含義是變換后的 IR 中必須依次出現(xiàn)獲取對象類 → 條件分支 → 直接調(diào)用塊。任何一個模式缺失或順序錯亂測試即失敗。這種片段式檢查非常靈活既避免了維護整份期望 IR 的繁瑣又能精確定位是哪一步變換出了問題。下圖示意了 Pass 變換 IR 指令的典型場景LLVM 中 load/store 向量操作的位寬匹配過程FileCheck 驗證的正是這類變換結果是否符合預期編寫 CJ Pass 測試三步走結合 CJInlineCache 等現(xiàn)有測試可以為新 Pass 編寫測試準備輸入 IR在測試目錄中創(chuàng)建.ll文件寫出最小可復現(xiàn)的輸入 IR可加%S/inputfile/存放輔助數(shù)據(jù)文件如上例中的 profile 文件編寫 RUN 行指定opt的 Pass 參數(shù)末尾接| FileCheck %s補充 CHECK 斷言先真實運行一次拿到輸出再把關鍵片段固化為CHECK行——注意斷言要少而準只鎖定 Pass 的核心行為避免測試過度脆弱。此外測試頭部的注釋還能聲明平臺限制如XFAIL: *標記已知失敗保證同一套測試在不同環(huán)境下的可解釋性。性能維度不止正確還要夠快除了正確性測試體系還需關注 Pass 的性能回歸。LLVM 提供了 locstats 工具統(tǒng)計各 Pass 耗時并用 llvm/tools/locstats/ 生成對比圖幫助開發(fā)者發(fā)現(xiàn)這次提交讓某個 Pass 變慢了相關組件與延伸閱讀本 fork 的倉頡適配不止于優(yōu)化 Pass調(diào)試器一側(cè)也有對應架構如表達式解析器支持 Clang 與 Cangjie關鍵路徑速查表內(nèi)容路徑lit 總配置llvm/test/lit.cfg.pyCJ Pass 源碼llvm/lib/Transforms/Scalar/CJ Pass 測試llvm/test/Transforms/內(nèi)聯(lián)緩存測試樣例vcall.ll屏障優(yōu)化測試樣例CJBarrierOpt總結倉頡 LLVM 測試體系 lit負責跑 FileCheck負責判 與 Pass 一一對應的測試目錄負責覆蓋。理解了這三者的分工你既能讀懂現(xiàn)有 CJ 測試也能為自己新寫的 CJ Pass 快速補上可靠的質(zhì)量護欄?!久赓M下載鏈接】llvm-projectLLVM 項目是一個模塊化、可復用的編譯器及工具鏈技術的集合。此fork用于添加倉頡編譯器的功能并支持倉頡編譯器項目。項目地址: https://gitcode.com/Cangjie/llvm-project創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考