IRTranslator¶
このパスは、入力LLVM-IR Function
を 汎用マシンIR MachineFunction
に変換します。これは通常、直接的な変換ですが、場合によってはもう少し複雑になることもあります。例えば
%2 = add i32 %0, %1
は
%2:_(s32) = G_ADD %0:_(s32), %1:_(s32)
となりますが、
call i32 @puts(i8* %cast210)
はターゲットのABI規則に従って変換されます。
注意
現在実装されている LLVM言語リファレンスマニュアル の部分は、多くのコンパイルには十分ですが、100%完全ではありません。まれな機能を含むLLVM-IRをコンパイルしようとするユーザーは、変換を実装する必要がある場合があります。
ターゲット固有の組込み関数¶
ターゲット固有の組込み関数の変換のためのターゲットフックを追加するかどうかについて、(メーリングリスト以外で)議論がありました。議論に参加した人々の間では、IRTranslatorはカスタマイズ可能な方法でターゲット固有の組込み関数をローワーできる必要があるという点で一般的に合意されましたが、執筆時点ではこれを実装するための作業は行われていません。
関数呼び出しの変換¶
IRTranslator
は、呼び出し、戻り、引数を適切な物理レジスタの使用と命令シーケンスにローワーすることにより、ABIの呼び出し規約も実装します。これは、ターゲットが実装する必要があるいくつかのフックを提供する CallLowering
インターフェースを使用して実現されます。 lowerFormalArguments
、lowerReturn
、lowerCall
など。
本質的に、これらのフックはすべて、関数の残りの部分で使用される仮想レジスタと、物理レジスタまたはスタックのどちらかに、ABIによって指示された引数/戻り値を移動する方法を見つける必要があります。これには、大きな型を小さな型に分割したり、符号拡張/ゼロ拡張を導入したりすることが含まれる場合があります。異なるバックエンド間でこのコードをできるだけ共有するために、CallLowering
はいくつかのヘルパーとインターフェースを提供します。
ArgInfo
- 仮引数だけでなく、戻り値、実際の引数、呼び出し結果にも使用されます。IR型、仮想レジスタなどの情報が含まれます。大きな値は、複数のArgInfo
オブジェクトに分割する必要がある可能性があります(CallLowering::splitToValueTypes
が役立ちます)。ValueAssigner
- 通常はTableGenによって生成されるCCAssignFn
(呼び出し規約を参照)を使用して、各ArgInfo
をどこに配置するか(物理レジスタまたはスタック)を決定します。バックエンドは提供されているIncomingValueAssigner
(仮引数と呼び出し結果用)とOutgoingValueAssigner
(実際の引数と関数戻り値用)を使用できますが、それらをサブクラス化することも可能です。ValueHandler
- 各値を適切な場所に配置するために必要な命令を挿入します。レジスタまたはアドレスへの値の割り当てのための純粋仮想メソッドと、その他の多くのヘルパーがあります。determineAndHandleAssignments
(またはより細かい制御のために、determineAssignments
とhandleAssignments
)- 指定されたValueAssigner
とValueHandler
を一連のArgInfo
オブジェクトに呼び出すためのいくつかのボイラープレートを含みます。
集約型¶
注意
これは記述されて以来変更されており、もはや正確ではありません。このドキュメントの改善において、このコードベースのこの部分でそれほど作業をしていないため、更新されていません。より詳しい知識を持つ人が注意を払うべきです。
集約型は、GetValueVTs
を介してSelectionDAGの複数の仮想レジスタと同様に、複数の仮想レジスタにローワーされます。
TODO
: ビットの一部が未定義(パディング)であるため、追加のメタデータを使用して表現を拡張することを検討する必要があります(効果的に、vregsに関するcomputeKnownBits情報をキャッシュする)。PR26161を参照してください。[GlobalISel] 集約型へのIRからMachineInstr変換中の値を仮想レジスタに変換する
定数の変換¶
定数オペランドは、G_CONSTANT
またはG_FCONSTANT
命令によって定義される仮想レジスタの使用として変換されます。これらの命令はエントリブロックに配置され、連続的なCSE実装(CSEMIRBuilder
)の対象となります。デバッガを混乱させるのを防ぐために、デバッグ位置情報は削除されます。
これは、命令選択中に定数を即値オペランドに折りたたむことを可能にしつつ、高価な折りたたみ不可能な定数に対して冗長なマテリアライゼーションを回避するためにも有益です。ただし、これらの仮想レジスタは長い有効範囲を持つ可能性があるため、-O0パイプラインでは不要なスピルとリロードにつながる可能性があります。これは、トランスレータの後でローカライザを実行することで軽減できます。