探索 Rust 編譯器:GCC 與 LLVM

Rust 編譯器使用借用檢查器來優化代碼性能和內存管理,Rust 代碼是使用該語言的官方編譯器 rustc 編譯的。

rustc 在後端使用 LLVM 優化並將高級 Rust 代碼轉換爲底層機器代碼。然而,最近出現了一種用於替代 rustc 編譯器的 GCC 前端,稱爲 gccrs。

在本文中,我們將探索 Rust 編譯器的發展前景,重點關注兩個本地編譯器項目:LLVM 和 GCC。

什麼是 LLVM?

LLVM 是由可重用的編譯器和工具鏈組件組成的編譯器基礎架構集合。LLVM 在技術上是底層虛擬機的縮寫,但隨着時間的推移,這個縮寫本身已經成爲項目的品牌。LLVM 以其優化代碼和跨各種編程語言生成高性能機器代碼的能力而聞名。

標準編譯器基礎結構可以分爲前端、中端和後端。前端將作爲高級編程語言之間的轉換層,這在不同的編譯器 (包括 LLVM 和 GCC) 之間是相似的。

中端對代碼應用各種優化,例如循環展開和函數內聯。LLVM IR 是 LLVM 的中間表示,可以根據目標架構直接優化編譯多個不同的後端。

從一開始,LLVM 就一直是 Rust 編譯器的默認後端,rustc 本質上是一個 LLVM 前端。事實證明,Rust 和 LLVM 之間的合作是成功的,因爲 LLVM 的先進優化技術提高了 Rust 程序的性能,並允許它們在多個平臺上運行。

什麼是 GCC?

GCC 代表 GNU 編譯器集合,是一個開源編譯器集合,支持各種編程語言,如 C、C++、Fortran 等。它以其穩定性、可靠性以及對不同體系結構和操作系統的廣泛支持而聞名。

除了上面列出的語言之外,GCC 已經發展到支持許多其他語言,包括 Ada、Java、Go,以及最近 (仍在開發中) 的 Rust。

有多個前端支持各種語言,每個前端都將編程語言轉換爲抽象語法樹 (AST)。AST 是前端和中端之間的中介。

LLVM 有 IR 作爲它的中介表示,而 GCC 有 GIMPLE 和 RTL。GIMPLE 是由 GCC 中間端處理的高級中介表示。GIMPLE 提供了程序的簡化表示,保留了高級語義並簡化了優化任務。

然後,在 GIMPLE 表示之後,將代碼進一步轉換爲 RTL。這種底層表示非常類似於彙編語言指令,在用於生成機器代碼之前進行了進一步的優化。

目前正在爲 Rust 開發一個名爲 gccrs 的 GCC 前端。該項目還不穩定,尚未正式集成到 GCC 中。

GCC 與 LLVM:架構上的差異

作爲一個編譯器集合,與 LLVM 相比,GCC 有不同的編譯方法。GCC 採用更傳統的方法,使用前端來解析源代碼並生成 AST。

然後將此 AST 轉換爲稱爲 GIMPLE 的高級中介表示,GIMPLE 保留程序的高級語義。與 LLVM 不同,GCC 增加了一箇中間表示:RTL。

這兩種優化的目標是不同的。GIMPLE 側重於高級優化,而 RTL 側重於底層優化和轉換爲類似彙編的指令。

LLVM 直接從前端到它的中間表示 LLVM IR,LLVM IR 優化與語言無關,與體系結構無關。這允許 LLVM 執行各種優化,這可以使不同的編程語言和目標體系結構受益:

然而,GCC 和 LLVM 之間最驚人的區別在於它們如何構建源代碼。LLVM 是模塊化的,從一開始,它就被構建爲可擴展的,並被多種語言使用,目標是廣泛的後端機器。

另一方面,GCC 被設計爲具有緊耦合組件的單片編譯器。可以爲 GCC 創建擴展,但它的大多數代碼都是緊密結合的,需要下載整個 GCC 代碼庫才能進行更改或添加。

安裝 gccrs

Rust 編程語言主要使用 LLVM 作爲默認的編譯器基礎結構。如上所述,rustc 是使用 LLVM 的前端,這意味着 Rust 代碼默認使用 LLVM 的優化和轉換來生成機器碼。

要在 Rust 中使用 GCC,需要使用 gccrs。gccrs 是 Rust 編譯器的另一個前端,它使用本地 GCC 作爲後端。

要安裝和使用 gccrs,請參考 https://github.com/Rust-GCC/gccrs,根據不同的操作系統進行安裝。

gccrs 仍處於早期開發階段,因此它不能支持大多數 Rust 語法,特別是與帶有 LLVM 的 Rust 相比。例如,目前 gccrs 不支持 Rust 宏,因此很難在 GCC 和 LLVM 之間仔細比較 Rust。

未來前景:正在進行的項目和開發

用 GCC 和 LLVM 編譯 Rust 代碼在性能和優化方面可能會產生不同的結果,這兩種方法都有其獨特的優勢。以 GCC 爲例,它可以針對各種體系結構進行編譯,並且已經存在了很長時間,使其在某些領域更加成熟和穩定。它有一個經過幾十年優化的成熟代碼庫。

有兩個項目正在努力使 Rust 與 gcc 兼容。當然,第一個是 gccrs,第二個是 rustc_codegen_gcc。

兩者之間的區別在於,rustc_codegen_gcc 使用 rustc 前端爲 GCC 後端生成中間表示。與 gccrs 相比,它更穩定,可以爲使用 GCC 後端的 Rust 代碼提供更好的編譯體驗。

爲什麼 gccrs 對 Rust 社區很重要

首先,它還處於社區主導的早期階段,rustc 仍然是主要的 Rust 編譯器。但是有一個社區主導的編譯器爲 Rust 生態系統增加了更多的多樣性,幫助 Rust 在多個生態系統中更加通用。

擁有 gccr 也有助於促進更多的社區創新,Rust 在大多數目標平臺上已經是一種高性能語言,但是在一些小衆平臺中,使用 GCC 的體系結構進行優化可能會更有效。

GCC 比較老,相對穩定,它針對的是與 LLVM 不兼容的遺留系統——例如,摩托羅拉 68000 (m68k),一種在 20 世紀 80 年代和 90 年代普遍使用的遺留微處理器。通過 GCC 可以很容易地訪問許多這樣的遺留微處理器。考慮到技術的過時程度,讓 LLVM 支持它們是不合理的。

總結

今天,我們探索了 Rust 編譯的發展前景,重點關注兩個項目:LLVM 和 GCC。這兩個項目在 Rust 編譯方法上都有獨特的優點、設計理念和目標。但是,應該注意到 gccrs 項目仍處於開發的早期階段,並不能完全支持 Rust 語言的所有特性。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/dWRCU0uGMEtc67rXXaR97w