LLVM PC 區段中繼資料¶
簡介¶
PC 區段中繼資料可以附加到指令和函數,其地址,即程式計數器 (PC),將在特殊編碼的二進制區段中發出。中繼資料被賦予為 MD_pcsections
(!pcsections
) 類型的 MDNode
;下一節將描述中繼資料格式。
中繼資料格式¶
可以添加任意數量的交錯 MDString
和常量運算符,其中新的 MDString
總是表示一個區段名稱,後跟任意數量的沿著指令或函數的 PC 編碼的輔助常量數據。第一個運算符必須是表示第一個區段的 MDString
。
!0 = !{
!"<section#1>"
[ , !1 ... ]
[ !"<section#2">
[ , !2 ... ]
... ]
}
!1 = !{ iXX <aux-consts#1>, ... }
!2 = !{ iXX <aux-consts#2>, ... }
...
中繼資料中出現 區段#1
、區段#2
、…、區段#N
會導致後端將關聯指令或函數的 PC 發送到所有命名的區段。對於區段 #N 中的每個發出的 PC,元組 !N
中的常量 輔助常量#N
將在 PC 之後發出。可以在區段名稱字符串後提供多個具有常量數據的元組(例如 !0 = !{"s1", !1, !2}
),並且可以將單個常量元組重複用於不同的區段(例如 !0 = !{"s1", !1, "s2", !1}
)。
二進制編碼¶
指令 會導致發出單個 PC,而 函數 會導致發出函數的起始地址和一個 32 位的大小。之後是 MD_pcsections
中繼資料中各自區段名稱後面的輔助常量。
為了避免最終二進制文件中的重定位,存儲在 entry
的每個 PC 地址都是一個相對重定位,計算方式為 pc - entry
。要進行解碼,使用者必須計算 entry + *entry
。
每個項目的尺寸取決於程式碼模型。對於大型和中型程式碼模型,項目尺寸與指標尺寸相符。對於任何較小的程式碼模型,項目尺寸僅為 32 位元。
編碼選項¶
可以在第一個 MDString
運算子中傳遞可選的編碼選項:<section>!<options>
。可以使用以下選項
C
- 將大小為 2-8 位元組的常數整數壓縮為 ULEB128;這包括函數大小(但不包括 PC 項目)。
例如,foo!C
將發射到區段 foo
,所有常數都編碼為 ULEB128。
程式碼生成的保證¶
將 !pcsections
中繼資料附加到 LLVM IR 指令「不應」影響所請求 PC 區段之外的優化或程式碼生成。
雖然依靠 LLVM IR 中繼資料來請求 PC 區段使得上述保證相對微不足道,但通過優化和程式碼生成管道傳播中繼資料具有以下保證。
中繼資料傳播¶
一般來說,LLVM「不保證」通過 IR 轉換保留 IR 中繼資料(附加到 Instruction
)。當使用 PC 區段中繼資料時,此保證保持不變,並且 !pcsections
中繼資料在降級到機器 IR (MIR) 之前仍然是「可選的」。
程式碼生成注意事項¶
與其他 LLVM IR 中繼資料一樣,LLVM IR 轉換過程不需要保留 !pcsections
中繼資料,但以下情況除外
AtomicExpandPass
應根據以下規則 1-4 保留!pcsections
中繼資料。
將 LLVM IR 轉換為 MIR 時,!pcsections
中繼資料應從來源 Instruction
複製到目標 MachineInstr
(使用 MachineInstr::setPCSections()
設置)。指令選擇器和 MIR 優化過程應保留 PC 區段中繼資料,如下所示
替換將保留被替換指令的 PC 區段中繼資料。
複製將保留被複製指令的 PC 區段中繼資料。
合併將保留兩個指令之一的 PC 區段中繼資料(不保證使用哪個指令的中繼資料)。
刪除將丟失 PC 區段中繼資料。
這類似於偵錯資訊,BuildMI()
輔助程式提供了一種在 MIMetadata
套件中傳播偵錯資訊和 !pcsections
中繼資料的便捷方法。
中繼資料使用者注意事項¶
使用 !pcsections
中繼資料的案例應該完全容許遺漏的中繼資料,或者插入 !pcsections
中繼資料的過程應該在所有 LLVM IR 優化過程「之後」執行,以便在轉換為 MIR 之前保留中繼資料。