OCaml 編譯器 - 2021 年 6 月至 9 月
我很樂意發布第三期「OCaml 編譯器開發電子報」。(這絕非詳盡無遺:許多人最終沒有時間寫些東西,這沒關係。)
當然,歡迎評論或提問!
如果您一直在研究 OCaml 編譯器並想說些什麼,請隨時在此討論串中發文!如果您希望我下次準備電子報時與您聯繫(未來某個隨機時間點),請透過電子郵件(gabriel.scherer at gmail)告知我。
先前發行
Nicolás Ojeda Bär (@nojb)
標準函式庫中的通道
-
#10545 將模組
In_channel
和Out_channel
新增至標準函式庫。(已合併) -
#10538 新增
Out_channel.set_buffered
和Out_channel.is_buffered
以控制和查詢輸出通道的緩衝模式。(已合併) -
#10596 新增
In_channel.input_all
、In_channel.with_open_{bin,text,gen}
和Out_channel.with_open_{bin,text,gen}
。(已合併)
編譯器使用者介面
-
#10654 提出一種方法,讓使用
-output-complete-exe
編譯的 bytecode 二進位檔能夠使用除錯資訊。(等待審查)這是第二輪工作,可能會對獨立 bytecode 二進位檔的可用性產生重大影響 - 使-output-complete-exe
的功能與-custom
一致,並棄用後者這種較為脆弱的方法。 -
#10555 改善並清理與「簡寫」詞彙(例如
{x; y}
或< x; y >
)相關聯的 AST 位置儲存。(已合併) -
#10560 編譯器現在會遵循
NO_COLOR
環境變數。(已合併)
內部變更
-
#10624 修復 4.08 中引入的編譯時間效能衰退問題(此修復由 Leo White 提出)。(已合併)
-
#10606 清理
non-unit-statement
和ignored-partial-application
警告的實作。(已合併)
David Allsopp (@dra27)
- 可重定位的編譯器。我於 8 月和 9 月研究了此修補程式集。適用於 Windows 和 Unix 的原型已重新基於 4.12 和 4.13。有了這些修補程式,如果您有多個版本的編譯器散落在各處(即 opam!),bytecode 可執行檔現在幾乎不可能載入錯誤的 C stub 函式庫(例如
dllunix.so
)或叫用錯誤版本的ocamlrun
。此外,至少從編譯器的角度來看,現在可以將本機 opam 切換移動到新的位置。這項變更的主要功能是複製現有的編譯器,以便在不重寫任何二進位檔的情況下建立新的 opam 切換。有了這些修補程式,新的本機切換會在 5-10 秒內建置完成(其中大部分時間由 opam 佔用,現在有更多誘因來改進 opam!)。 - 4.13 包含減少在建置系統中使用腳本語言的初步工作,這提高了建置系統的穩定性和可移植性。Cygwin 發行版本最近預設停止發布
iconv
命令,這破壞了所有 Windows 版本的 OCaml 建置(請參閱 [#10451](https://github.com/ocaml/ocaml/pull/10451 - [404 Not Found]))。這方面還有更多工作要做,但其餘部分可能會暫緩,直到 OCaml 5.00 之後。隨著腳本的使用大幅減少,可以使用原生 Windows 編譯的 GNU make(即make.exe
,沒有其他相依性)並在沒有 Cygwin/MSYS2/WSL 的情況下完成建置的相當長的一段時間。 - 4.13 包含 FlexDLL 引導和偵測的完整修訂(在我的 4 月更新中提及);希望隨機選取錯誤的 flexlink 或突然發現 FlexDLL 遺失的日子已經過去。當引導 FlexDLL 時,Windows 建置的速度也應該明顯加快(這是 opam 的來源建置必須執行的操作)。
- 目前正在進行一些「現代化」我們使用 POSIX 的工作,以移除 Unix 函式庫中的一些較舊的相容性程式碼,如 #10505 所示。移除程式碼總是令人高興!
- 逐漸完成並關閉我一些較舊的 PR,通常會以更簡單的實作取代它們。有趣的是,回到 PR 通常會導致意識到更簡單的方法;就像讓茶葉沖泡一樣!:tea
Xavier Leroy (@xavierleroy)
我研究了一個關於原生程式碼編譯器處理尾呼叫的舊問題:如果呼叫有很多引數,且它們並非全部都符合保留用於傳遞引數的處理器暫存器,則會將剩餘的引數放在堆疊上,並執行常規的非尾呼叫。自 OCaml 問世以來,一直存在此限制。我過去曾多次嘗試在堆疊上傳遞引數的情況下實作正確的尾呼叫,但由於 GC 用來遍歷堆疊的堆疊框架描述項的困難而失敗。
在 #10595 中,我採用更簡單的方法,概括了先前特定於 OCaml 的 i386 埠的 hack,該方法使用「網域狀態」結構中的記憶體,而不是堆疊。一旦用於傳遞函式引數的可用暫存器用盡,接下來的 64 個引數會傳遞到屬於網域狀態一部分的記憶體區域中。此引數傳遞與尾呼叫相容,因此我們保證至少有 70 個引數的尾呼叫。
為合併 Multicore OCaml 而引入的網域狀態結構是一個每個執行網域的記憶體區域,可以從暫存器有效地定址。因此,透過網域狀態傳遞引數對於平行處理而言是安全的,並且與透過堆疊傳遞引數一樣有效。
享受您 70 個引數的尾呼叫吧!
建構函式拆箱 (Nicolas Chataing @nchataing, Gabriel Scherer @gasche)
Nicolas Chataing 關於建構函式拆箱的實習(在上一期中提到)於 6 月底結束。我們一直以較慢的速度斷斷續續地工作,以使原型達到我們可以提交 PR 的狀態。第一步是提出我們的規格(與 Jeremy Yallop 的原始提案不同),現在已以 RFC 註解形式發布。
針對此主題的 hack 產生了一系列小型上游 PR,主要是清理和重構,使其更容易實作,以及一些關於現有程式碼庫的微妙方面的文件 PR,我們必須透過閱讀程式碼來弄清楚:#10500、#10512(尚未合併,引發了有趣的討論)、#10516、#10637、#10646。
Vincent Laviron (@lthls(github)/@vlaviron(discuss))
Léo Boitel 關於偵測和簡化恆等函式的實習於 6 月結束(請在 OCamlPro 上找到相關的部落格文章,並在 Discuss 上找到相關的討論)。目前將結果推向上游並非優先事項,但我計劃基於該工作並將其整合到主編譯器中,或在未來某個時間點整合到 Flambda 2 分支中。
除此之外,我還記錄了我們在 Flambda 2 簡化步驟中用於近似的抽象網域(您可以在這裡找到結果),並且我已與 Keryan Dider (@Keryan-dev) 合作開發與 Flambda 2 的 -Oclassic
模式等效的功能。
我也提出並審查了上游和 Flambda 2 儲存庫中的一些小型修復,從修復晦澀的錯誤(例如 這個 Flambda 錯誤)到程式碼產生的小幅改進。
Jacques Garrigue (@garrigue)
繼續與 Takafumi Saikawa (@t6s) 合作加強統一演算法中使用的資料類型。
- #10337 使類型節點抽象化,確保始終看到正規形式。於 6 月合併。
- #10474 對多型變體列執行相同的操作。於 9 月合併。
- #10627 對多型變體欄位類型執行相同的操作。
- #10541 對物件欄位類型和函式交換旗標執行相同的操作。
也繼續開發產生 Coq 程式碼的後端 GitHub - COCTI/ocaml at ocaml_in_coq。現在已使用許多範例。