InstructionSelect¶
このパスは、汎用マシン命令を同等のターゲット固有の命令に変換します。 `MachineFunction` をボトムアップでトラバースし、定義の前に使用を選択することで、簡単なデッドコードの削除を可能にします。
API: InstructionSelector¶
ターゲットは、ターゲット固有の選択ロジックを適切に含む `InstructionSelector` クラスを実装します。
インスタンスはサブターゲットによって提供されるため、サブターゲット機能によってセレクターを特殊化できます(たとえば、ベクトルセレクターが汎用共通セレクターの一部をオーバーライドします)。 また、`MachineFunction` によってパラメータ化して、optsize などの関数属性に基づいてセレクターのバリアントを有効にすることもできます。
単純なAPIは以下で構成されます。
virtual bool select(MachineInstr &MI)
このターゲット提供のメソッドは、おそらく汎用的なMIを完全にターゲット固有の同等のものに変異(または置換)させる役割を担います。 また、gvregsを適切なレジスタクラスに制約し、COPY命令をレジスタアロケータに渡す役割も担います。
`InstructionSelector` は、vregオペランドの使用定義チェーンをたどることで、他の命令を選択されたMIに畳み込むことができます。 GlobalISelはグローバルであるため、この畳み込みは基本ブロックをまたいで行うことができます。
SelectionDAGルールのインポート¶
TableGenはSelectionDAGルールをインポートし、それらを実行するための次の関数を提供します。
bool selectImpl(MachineInstr &MI)
`--stats` オプションを使用すると、正常にインポートされたルールの割合を判断できます。 これを使用する最も簡単な方法は、`ninja -v` から `-gen-globalisel` tablegenコマンドをコピーして変更することです。
同様に、`--warn-on-skipped-patterns` オプションを使用すると、ルールがインポートされなかった理由を取得できます。 これは、最も重要な拒否理由に焦点を当てるために使用できます。
PatLeaf述語¶
PatLeafsは、C++が`SDNode`オブジェクトに関して実装されているため、インポートできません。 即値述語を処理するPatLeafsは、必要に応じて`ImmLeaf`、`IntImmLeaf`、または`FPImmLeaf`に置き換える必要があります。
他のPatLeafsに対する標準的な回答はありません。 いくつかの標準的な述語がTableGenに組み込まれていますが、これは一般的には行われるべきではありません。
カスタムSDノード¶
カスタムSDノードは、`GINodeEquiv`を使用してターゲット疑似命令にマップする必要があります。 これにより、命令セレクターはそれらをインポートしますが、命令セレクターの前にターゲット疑似命令がMIRに導入されていることを確認する必要もあります。 前のパスはどれでも適切ですが、リーガライザーが特に一般的な選択肢になります。
ComplexPatterns¶
ComplexPatternsは、C++が`SDNode`オブジェクトに関して実装されているため、インポートできません。 GlobalISelバージョンは、`GIComplexOperandMatcher`で定義し、`GIComplexPatternEquiv`でComplexPatternにマップする必要があります。
ComplexPatternの移植には、次の述語が役立ちます。
isBaseWithConstantOffset() - base+offset構造をチェックします
isOperandImmEqual() - 特定の定数があるかどうかをチェックします
isObviouslySafeToFold() - 命令を沈めて別の命令に畳み込むことができない理由をチェックします。
C++実装にはいくつかの重要なポイントがあります。
述語でMIRを変更しないでください
レンダラーラムダは、解放後使用を避けるために値でキャプチャする必要があります。 それらは述語が返された後に使用されます。
レンダラーラムダでのみ命令を作成します。 GlobalISelは、作成したが使用していないものをクリーンアップしません。