官方文檔:Go 編譯的四個階段
Go 編譯器簡介
cmd/compile 目錄包含構成 Go 編譯器的主包。編譯器在邏輯上可以分爲四個階段,我們將在包含其代碼的包列表中簡要描述這四個階段。
在提到編譯器時,有時可能會聽到術語front-end|前端和back-end|後端。粗略地說,這些轉化爲我們將在此列出的前兩個和後兩個階段。第三個術語,“middle-end | 中間端”,通常指的是在第二階段進行的大部分工作。
請注意 go/* 路徑下的包系列,例如 go/parser 和 go/types,與編譯器沒有關係。由於編譯器最初是用 C 編寫的,所以開發 go/* 包是爲了支持編寫使用 Go 代碼的工具,比如 gofmt 和 vet。
需要澄清一下,名稱gc這裏代表Go compiler,與大寫的GC(garbage collection垃圾回收) 沒有什麼關係。
- 語法分析
cmd/compile/internal/syntax(詞法分析器,解析器,語法樹)
在編譯的第一階段,對每個源文件代碼進行標記 (詞法分析) ,解析 (語法分析) ,並構建一個語法樹。
每個語法樹都精準地展現了源文件相對應的內容,其中的節點對應於源文件的各種元素,如表達式、聲明和語句。語法樹還包括了用於錯誤報告和創建調試信息的位置信息。
- 類型檢查和 AST 轉換
cmd/compile/internal/gc(創建編譯器AST、類型檢查、AST轉換)
gc 包包含一個 AST 定義,是用 C 語言編寫的。所有代碼都是用它編寫的,所以 gc 包必須做的第一件事就是將語法包的語法樹轉換爲編譯器的 AST 表示。這個額外的步驟將來可能會被重構。
然後對 AST 進行類型檢查。第一步是名稱解析和類型推斷,確定哪個對象屬於哪個標識符,以及每個表達式具有哪個類型。類型檢查包括某些額外的檢查,例如 “聲明瞭且未使用的” 的變量檢查,以及確定函數是否停止。
某些轉換也在 AST 上完成的。有些節點根據類型信息進行了細化,例如將字符串添加從算術加法節點類型中分離出來。其他一些例子包括無效代碼刪除分析、函數調用內聯和逃逸分析。
- 通用 SSA
-
cmd/compile/internal/gc(轉換爲SSA) -
cmd/compile/internal/ssa(SSA傳遞和規則)
在這個階段,AST 被轉換爲 Static Single Assignment (SSA)形式,這是一種具有特定屬性的較低級的中間表現形式,可以更容易地實現優化並最終從中生成機器代碼。
在此轉換過程中,將會使用函數的內置函數。這些都是特殊的函數,編譯器已經學會了在個別例子的基礎上使用經過大量優化的代碼來替代它。
在 AST 到 SSA 的轉換過程中,某些節點也會被降級爲更簡單的組件,這樣編譯器的其餘部分就可以使用它們。例如,內置的copy函數會被內存移動替代,range循環被重寫爲 for 循環。由於歷史原因,其中一些情況目前是發生在轉換爲 SSA之前,但長期計劃是將所有這些放到這裏處理。
然後,應用一系列與機器無關的通行證和規則。它們不會涉及任何單一的計算機體系結構,因此可以在所有 GOARCH 變體上運行。
這些通用通過的一些例子包括無效代碼刪除,移除不必要的零值檢查,以及移除未使用的分支。通用重寫規則主要涉及表達式,例如用常量值替換某些表達式,以及優化乘法和浮點運算。
- 生成機器代碼
-
cmd/compile/internal/ssa(SSA 降低和特定架構傳遞) -
cmd/internal/obj(機器代碼生成)
編譯器與機器相關的階段從lower開始,它將通用的值重寫爲它們與機器相關的變量。例如,在 amd64架構上可以使用內存操作數,因此可以組合很多負載存儲操作。
請注意,下層的傳遞運行所有特定機器的重寫規則,因此它當前也做了許多優化。
一旦 SSA 被lower且更特定於目標體系架構,就會運行最終的代碼優化傳遞。這包括另一個無效代碼刪除 / 值傳遞,移動更接近其用途的值,刪除永遠不會讀取的本地變量,以及寄存器分配。
作爲這個步驟的一部分,其他重要的工作還包括棧幀佈局,該佈局爲局部變量分配堆棧偏移量,以及指針存活分析,它計算堆棧上哪些指針在每個GC 安全點處於活躍狀態。
在 SSA 生成階段的末尾,Go 函數會被轉換爲一系列 obj程序指令。它們被傳遞給彙編程序 (cmd/internal/obj) ,然後將它們轉換爲機器代碼並寫出最終的目標文件。對象文件還將包含反射數據、導出數據和調試信息。
進一步閱讀
如果你想要更深入瞭解 SSA 包的工作原理,包括它的傳遞和規則,請訪問 cmd/compile/internal/ssa/README.md[1].
參考資料
cmd/compile/internal/ssa/README.md: https://golang.org/src/cmd/compile/internal/ssa/README.md
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/3PfUde60Swv106eNdrcvfA