LLVM PC 區段 Metadata

簡介

PC 區段 Metadata 可以附加到指令和函數,它們的位址,即程式計數器 (PC),將會被發射到特別編碼的二進位區段中。Metadata 被指定為 MD_pcsections (!pcsections) 類型的 MDNode;以下章節描述 metadata 格式。

Metadata 格式

可以加入任意數量的交錯 MDString 和常數運算元,其中新的 MDString 總是表示區段名稱,後跟著沿著指令或函數 PC 編碼的任意數量的輔助常數資料。第一個運算元必須是表示第一個區段的 MDString

!0 = !{
  !"<section#1>"
  [ , !1 ... ]
  [ !"<section#2">
    [ , !2 ... ]
    ... ]
}
!1 = !{ iXX <aux-consts#1>, ... }
!2 = !{ iXX <aux-consts#2>, ... }
...

在 metadata 中出現 section#1section#2、…、section#N 會導致後端將相關指令或函數的 PC 發射到所有命名的區段。對於在區段 #N 中發射的每個 PC,tuple !N 中的常數 aux-consts#N 將在 PC 之後發射。可以在區段名稱字串之後提供具有常數資料的多個 tuple (例如 !0 = !{"s1", !1, !2}),並且單個常數 tuple 可以重複用於不同的區段 (例如 !0 = !{"s1", !1, "s2", !1})。

二進位編碼

指令 會導致發射單個 PC,而函數 會導致發射函數的起始位址和 32 位元大小。 接下來是 MD_pcsections metadata 中各區段名稱之後的輔助常數。

為了避免在最終二進位檔案中進行重定位,儲存在 entry 的每個 PC 位址都是相對重定位,計算方式為 pc - entry。 若要解碼,使用者必須計算 entry + *entry

每個 entry 的大小取決於程式碼模型。 對於大型和中型程式碼模型,entry 大小與指標大小相符。 對於任何較小的程式碼模型,entry 大小僅為 32 位元。

編碼選項

可選的編碼選項可以在第一個 MDString 運算元中傳遞:<區段>!<選項>。 以下選項可用

  • C – 將大小為 2-8 位元組的常數整數壓縮為 ULEB128; 這包括函數大小(但不包括 PC entry)。

例如,foo!C 將發射到區段 foo,其中所有常數都編碼為 ULEB128。

程式碼產生的保證

!pcsections metadata 附加到 LLVM IR 指令不應影響請求的 PC 區段之外的最佳化或程式碼產生。

雖然依賴 LLVM IR metadata 來請求 PC 區段使上述保證相對簡單,但 metadata 通過最佳化和程式碼產生管線的傳播具有以下保證。

Metadata 傳播

一般來說,LLVM 不對通過 IR 轉換保留 IR metadata(附加到 Instruction)做出任何保證。 當使用 PC 區段 metadata 時,此保證保持不變,並且 !pcsections metadata 在降低到機器 IR (MIR) 之前仍然是可選的

程式碼產生注意事項

與其他 LLVM IR metadata 一樣,LLVM IR 轉換 pass 沒有保留 !pcsections metadata 的要求,但以下例外情況除外

  • AtomicExpandPass 應根據以下規則 1-4 保留 !pcsections metadata。

當將 LLVM IR 轉換為 MIR 時,!pcsections metadata 應從來源 Instruction 複製到目標 MachineInstr(使用 MachineInstr::setPCSections() 設定)。 指令選擇器和 MIR 最佳化 pass 應按如下方式保留 PC 區段 metadata

  1. 替換將保留被替換指令的 PC 區段 metadata。

  2. 複製將保留複製指令的 PC 區段 metadata。

  3. 合併將保留兩個指令之一的 PC 區段 metadata(不保證使用哪個指令的 metadata)。

  4. 刪除將遺失 PC 區段 metadata。

這與 debug info 類似,並且 BuildMI() helper 提供了一種方便的方法,可在 MIMetadata bundle 中傳播 debug info 和 !pcsections metadata。

Metadata 使用者注意事項

!pcsections metadata 的用例應完全容忍遺失的 metadata,或者插入 !pcsections metadata 的 pass 應在所有 LLVM IR 最佳化 pass 之後運行,以保留 metadata 直到轉換為 MIR。