跳轉到

LLVM

起源

典型的編譯器可以分成 Frontend、Optimizer(Middle-End)、Backend 三個部分,但傳統編譯器即使架構上遵循 Frontend、Optimizer、Backend 分工,三者之間還是會做得密不可分,在互相交換資料時,都走內部私有 API。

在傳統編譯器的開發,三個部份的耦合性太高,模組的可複用性低,使得要修改現有編譯器來做出自己的編譯器相當困難,必須得重新造輪子才行。

我們希望可以透過抽換前端跟後端就可以生出一個新的編譯器,而不想要重新開始一條龍,我們也希望可以重複使用前端跟後端封裝好的函數庫或是物件。

img

Modern Compiler Design

在現代 Compiler 設計中,加入了和平台獨立的中間語言(Intermediate Representation, 簡稱 IR),改變了 Compiler 開發的生態。這一種設計的好處是,當我們要支持多種語言時,只需要添加多個前端。當需要支持多種硬體架構時,只需要添加多個後端。對於中間的最佳化器,我們可以使用通用的 IR。

這種加入 IR 後的三段式結構還有一個好處,開發前端的人只 ​​ 需要知道如何將原始碼轉換為 Optimizer 能夠理解的 IR 就可以了,他不需要知道 Optimizer 的工作原理,也不需要了解目標硬體架構的知識。這大幅降低了編譯器的開發難度,使更多的開發人員能夠參與。

LLVM 的核心 - LLVM IR

LLVM 正是實現了這種設計的編譯器工具包。

LLVM 定義了一個通用的 IR。LLVM IR 是一種類似機器語言,但為了給 Compiler 設計者方便而簡化過的版本。在 LLVM 的世界裡,Frontend 把原始語言的邏輯翻譯成 LLVM IR、Optimizer 把 LLVM IR 整理成效率更好的 LLVM IR、Backend 拿到 LLVM IR 後生成目標平台的機器語言。

如此一來,無論是語言設計者想要創造一個新語言、演算法設計師想改進程式的效能、或是硬體或虛擬機製造者要做一個新的平台,都能得益於 LLVM。

img

img

Reference