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>, ... }
...

メタデータ内のsection#1section#2、…、section#Nの出現は、バックエンドに関連付けられた命令または関数のPCを、名前付きのすべてのセクションに出力させます。セクション#Nに出力された各PCについて、タプル!N内の定数aux-consts#NがPCの後にエミットされます。セクション名文字列の後に複数の定数データを持つタプルを指定できます(例:!0 = !{"s1", !1, !2})、単一の定数タプルを異なるセクションで再利用できます(例:!0 = !{"s1", !1, "s2", !1})。

バイナリエンコード

命令は単一のPCの出力になり、関数は関数の開始と32ビットのサイズの出力になります。これに続いて、MD_pcsectionsメタデータ内のそれぞれのセクション名の後に続く補助定数が続きます。

最終バイナリでの再配置を避けるために、entryに格納された各PCアドレスは、pc - entryとして計算される相対再配置です。デコードするには、ユーザーはentry + *entryを計算する必要があります。

各エントリのサイズはコードモデルによって異なります。大規模および中規模のコードモデルでは、エントリサイズはポインタサイズと一致します。それよりも小さいコードモデルの場合、エントリサイズはわずか32ビットです。

エンコードオプション

オプションのエンコードオプションは、最初のMDStringオペレータで渡すことができます:<セクション>!<オプション>。次のオプションを利用できます。

  • C – 2〜8バイトのサイズの定数整数をULEB128として圧縮します。これには関数サイズ(ただしPCエントリは除外)が含まれます。

たとえば、foo!Cは、すべての定数がULEB128としてエンコードされたセクションfooに出力します。

コード生成に関する保証

LLVM IR命令に!pcsectionsメタデータを付加しても、要求されたPCセクション以外での最適化またはコード生成に影響を与えてはなりません

上記の保証は、PCセクションを要求するためにLLVM IRメタデータに依存すると比較的些細なことになりますが、最適化とコード生成パイプラインを通じたメタデータの伝播には、次の保証があります。

メタデータの伝播

一般に、LLVMは、IR変換を通じて(Instructionに付加された)IRメタデータを保持することについて一切の保証をしません。PCセクションメタデータを使用する場合、この保証は変更されず、!pcsectionsメタデータはマシンIR(MIR)への降格までオプションのままです。

コード生成に関する注意

他のLLVM IRメタデータと同様に、LLVM IR変換パスが!pcsectionsメタデータを保持するための要件はありません。ただし、次の例外があります。

  • AtomicExpandPassは、以下のルール1〜4に従って!pcsectionsメタデータを保持するものとします。

LLVM IRをMIRに変換する場合、!pcsectionsメタデータは、ソースInstructionからターゲットMachineInstrMachineInstr::setPCSections()で設定)にコピーされるものとします。命令セレクタとMIR最適化パスは、次のようにPCセクションメタデータを保持するものとします。

  1. 置換は、置換された命令のPCセクションメタデータを保持します。

  2. 複製は、コピーされた命令のPCセクションメタデータを保持します。

  3. マージは、2つの命令のいずれかのPCセクションメタデータを保持します(どの命令のメタデータが使用されるかの保証はありません)。

  4. 削除は、PCセクションメタデータを失います。

これはデバッグ情報と同様であり、BuildMI()ヘルパーは、MIMetadataバンドルでデバッグ情報と!pcsectionsメタデータを伝播する便利な方法を提供します。

メタデータユーザーに関する注意

!pcsectionsメタデータのユースケースは、メタデータが欠落していても完全に許容できるか、!pcsectionsメタデータを挿入するパスが、MIRに変換されるまでメタデータを保持するために、すべてのLLVM IR最適化パスのに実行される必要があります。