我真的想知道,AI編譯器中的IR是什么?
隨著深度學習的不斷發展,AI 模型結構在快速演化,底層計算硬件技術更是層出不窮,對于廣大開發者來說不僅要考慮如何在復雜多變的場景下有效的將算力發揮出來,還要應對 AI 框架的持續迭代。
AI 編譯器就成了應對以上問題廣受關注的技術方向,讓用戶僅需專注于上層模型開發,降低手工優化性能的人力開發成本,進一步壓榨硬件性能空間。IR對于AI編譯器來說是非常重要的一種數據結構鴨?。?!
IR 中間表達
什么是IR
IR(Intermediate Representation)中間表示,是編譯器中很重要的一種數據結構。編譯器在完成前端工作以后,首先生成其自定義的 IR,并在此基礎上執行各種優化算法,最后再生成目標代碼。
從廣義上看,編譯器的運行過程中,中間節點的表示,都可以統稱為 IR。從狹義上講編譯器的 IR,是指該編譯器明確定義的一種具體的數據結構,這個數據結構通常還伴隨著一種語言來表達程序,這個語言程序用來實現這個明確定義的 IR。大部分時間,不太嚴格區分這個明確定義的 IR 以及其伴隨的語言程序,將其統稱為 IR。
如圖所示,在編譯原理中,通常將編譯器分為前端和后端。其中,前端會對所輸入的程序進行詞法分析、語法分析、語義分析,然后生成中間表達形式 IR。后端會對 IR 進行優化,然后生成目標代碼。
例如:LLVM 把前端和后端給拆分出來,在中間層明確定義一種抽象的語言,這個語言就叫做 IR。定義了 IR 以后,前端的任務就是負責最終生成 IR,優化器則是負責優化生成的IR,而后端的任務就是把 IR 給轉化成目標平臺的語言。LLVM 的 IR 使用 LLVM assembly language 或稱為 LLVM language 來實現 LLVM IR的類型系統,就指的是 LLVM assembly language 中的類型系統。
因此,編譯器的前端,優化器,后端之間,唯一交換的數據結構類型就是 IR,通過 IR 來實現不同模塊的解耦。有些IR還會為其專門起一個名字,比如:Open64的IR通常叫做WHIRL IR,方舟編譯器的IR叫做MAPLE IR,LLVM則通常就稱為LLVM IR。
IR的定義
IR 在通常情況下有兩種用途,1)一種是用來做分析和變換,2)一種是直接用于解釋執行。
編譯器中,基于 IR 的分析和處理工作,前期階段可以基于一些抽象層次比較高的語義,此時所需的 IR 更接近源代碼。而在編譯器后期階段,則會使用低層次的、更加接近目標代碼的語義?;谏鲜鰪母叩降偷膶哟纬橄?,IR 可以歸結為三層:高層 HIR、中間層 MIR 和 底層 LIR。
- HIR
HIR(High IR)高層 IR,其主要負責基于源程序語言執行代碼的分析和變換。假設要開發一款 IDE,主要功能包括:發現語法錯誤、分析符號之間的依賴關系(以便進行跳轉、判斷方法的重載等)、根據需要自動生成或修改一些代碼(提供重構能力)。此時對 IR 的需求是能夠準確表達源程序語言的語義即可。
其實,AST 和符號表就可以滿足上述需求。也就是說,AST 也可以算作一種特殊的 IR。如果要開發 IDE、代碼翻譯工具(從一門語言翻譯到另一門語言)、代碼生成工具、代碼統計工具等,使用 AST(加上符號表)即可。基于 HIR,可以執行高層次的代碼優化,比如常數折疊、內聯關聯等。在 Java 和 Go 的編譯器中,有不少基于 AST 執行的優化工作。
- MIR
MIR(Middle IR),獨立于源程序語言和硬件架構執行代碼分析和具體優化。大量的優化算法是通用的,沒有必要依賴源程序語言的語法和語義,也沒有必要依賴具體的硬件架構。這些優化包括部分算術優化、常量和變量傳播、死代碼刪除等,實現分析和優化功能。
因為 MIR 跟源程序代碼和目標程序代碼都無關,所以在編譯優化算法(Pass)過程中,通常是基于 MIR,比如三地址代碼(Three Address Code,TAC)。
三地址代碼 TAC 的特點:最多有三個地址(也就是變量),其中賦值符號的左邊是用來寫入,右邊最多可以有兩個地址和一個操作符,用于讀取數據并計算。
- LIR
LIR(Low IR),依賴于底層具體硬件架構做優化和代碼生成。其指令通??梢耘c機器指令一一對應,比較容易翻譯成機器指令或匯編代碼。因為 LIR 體現了具體硬件(如 CPU)架構的底層特征,因此可以執行與具體 CPU 架構相關的優化。
多層 IR 和單層 IR 比較起來,具有較為明顯的優點:
- 可以提供更多的源程序語言的信息
- IR表達上更加地靈活,更加方便優化
- 使得優化算法和優化Pass執行更加高效
如在 LLVM 編譯器里,會根據抽象層次從高到低,采用了前后端分離的三段結構,這樣在為編譯器添加新的語言支持或者新的目標平臺支持的時候,就十分方便,大大減小了工程開銷。而 LLVM IR 在這種前后端分離的三段結構之中,主要分開了三層 IR,IR 在整個編譯器中則起著重要的承上啟下作用。從便于開發者編寫程序代碼的理解到便于硬件機器的理解。
浙公網安備 33010602011771號