FatLTO

簡介

FatLTO 物件是一種特殊的 胖二進制檔案,它除了包含生成的目標代碼外,還包含與 LTO 相容的 IR,而不是包含多個目標架構的目標代碼。這允許使用者將是否使用 LTO 的選擇延遲到連結時,並且這項功能在其他編譯器(例如 GCC)中已經存在一段時間了。

在 FatLTO 下,編譯器可以發出標準目標檔案,這些檔案同時包含 .text 區段中的機器代碼和 .llvm.lto 區段中的 LLVM 位元碼。

概述

在 LLVM 中,通過選擇 FatLTODefaultPipeline 來支援 FatLTO。此管道將

  1. 在當前模組上運行預連結(Thin)LTO 管道。

  2. 將預連結位元碼嵌入到特殊的 .llvm.lto 區段中。

  3. 使用 ModuleOptimization 管道完成模組的優化。

  4. 發出目標檔案,包括新的 .llvm.lto 區段。

在內部,.llvm.lto 區段是通過在 ThinLTOPreLinkDefaultPipeline 之後運行 EmbedBitcodePass 來創建的。此遍負責發出 .llvm.lto 區段。之後,ThinLTODefaultPipeline 運行,編譯器可以發出胖目標檔案。

限制

連結器

目前,LLD 和 GNU 連結器(通過 LLVM gold 外掛)支援使用帶有 LLVM 胖 lto 物件的 LTO。這在將來可能會改變,但目前沒有計劃擴展對其他連結器的支援。

支援的檔案格式

目前的實現僅支援 ELF 檔案。在撰寫本文時,尚不清楚是否需要支援其他目標檔案格式,例如 COFFMach-O

用法

Clang 使用者可以在使用 -flto-flto=thin 時指定 -ffat-lto-objects。如果沒有 -flto 選項,-ffat-lto-objects 將不會有任何效果。

使用 FatLTO 編譯一個物件檔案

$ clang -flto -ffat-lto-objects example.c -c -o example.o

在沒有 LTO 的情況下,使用 fat 物件中的物件碼進行連結。當指定 -fno-lto 時,這會使 -ffat-lto-objects 成為無效操作。

$ clang -fno-lto -ffat-lto-objects -fuse-ld=lld example.o

或者,您可以省略對包含 fat 物件的 LTO 的任何引用,並保留標準連結器行為。

$ clang -fuse-ld=lld example.o

使用來自 fat 物件的 LLVM 位元碼與完整 LTO 進行連結。

$ clang -flto -ffat-lto-objects -fuse-ld=lld example.o  # clang will pass --lto=full --fat-lto-objects to ld.lld

使用來自 fat 物件的 LLVM 位元碼與精簡 LTO 進行連結。

$ clang -flto=thin -ffat-lto-objects -fuse-ld=lld example.o  # clang will pass --lto=thin --fat-lto-objects to ld.lld