| |
| .. _instructionselect: |
| |
| InstructionSelect |
| ----------------- |
| |
| This pass transforms generic machine instructions into equivalent |
| target-specific instructions. It traverses the ``MachineFunction`` bottom-up, |
| selecting uses before definitions, enabling trivial dead code elimination. |
| |
| .. _api-instructionselector: |
| |
| API: InstructionSelector |
| ^^^^^^^^^^^^^^^^^^^^^^^^ |
| |
| The target implements the ``InstructionSelector`` class, containing the |
| target-specific selection logic proper. |
| |
| The instance is provided by the subtarget, so that it can specialize the |
| selector by subtarget feature (with, e.g., a vector selector overriding parts |
| of a general-purpose common selector). |
| We might also want to parameterize it by MachineFunction, to enable selector |
| variants based on function attributes like optsize. |
| |
| The simple API consists of: |
| |
| .. code-block:: c++ |
| |
| virtual bool select(MachineInstr &MI) |
| |
| This target-provided method is responsible for mutating (or replacing) a |
| possibly-generic MI into a fully target-specific equivalent. |
| It is also responsible for doing the necessary constraining of gvregs into the |
| appropriate register classes as well as passing through COPY instructions to |
| the register allocator. |
| |
| The ``InstructionSelector`` can fold other instructions into the selected MI, |
| by walking the use-def chain of the vreg operands. |
| As GlobalISel is Global, this folding can occur across basic blocks. |
| |
| SelectionDAG Rule Imports |
| ^^^^^^^^^^^^^^^^^^^^^^^^^ |
| |
| TableGen will import SelectionDAG rules and provide the following function to |
| execute them: |
| |
| .. code-block:: c++ |
| |
| bool selectImpl(MachineInstr &MI) |
| |
| The ``--stats`` option can be used to determine what proportion of rules were |
| successfully imported. The easiest way to use this is to copy the |
| ``-gen-globalisel`` tablegen command from ``ninja -v`` and modify it. |
| |
| Similarly, the ``--warn-on-skipped-patterns`` option can be used to obtain the |
| reasons that rules weren't imported. This can be used to focus on the most |
| important rejection reasons. |
| |
| PatLeaf Predicates |
| ^^^^^^^^^^^^^^^^^^ |
| |
| PatLeafs cannot be imported because their C++ is implemented in terms of |
| ``SDNode`` objects. PatLeafs that handle immediate predicates should be |
| replaced by ``ImmLeaf``, ``IntImmLeaf``, or ``FPImmLeaf`` as appropriate. |
| |
| There's no standard answer for other PatLeafs. Some standard predicates have |
| been baked into TableGen but this should not generally be done. |
| |
| Custom SDNodes |
| ^^^^^^^^^^^^^^ |
| |
| Custom SDNodes should be mapped to Target Pseudos using ``GINodeEquiv``. This |
| will cause the instruction selector to import them but you will also need to |
| ensure the target pseudo is introduced to the MIR before the instruction |
| selector. Any preceding pass is suitable but the legalizer will be a |
| particularly common choice. |
| |
| ComplexPatterns |
| ^^^^^^^^^^^^^^^ |
| |
| ComplexPatterns cannot be imported because their C++ is implemented in terms of |
| ``SDNode`` objects. GlobalISel versions should be defined with |
| ``GIComplexOperandMatcher`` and mapped to ComplexPattern with |
| ``GIComplexPatternEquiv``. |
| |
| The following predicates are useful for porting ComplexPattern: |
| |
| * isBaseWithConstantOffset() - Check for base+offset structures |
| * isOperandImmEqual() - Check for a particular constant |
| * isObviouslySafeToFold() - Check for reasons an instruction can't be sunk and folded into another. |
| |
| There are some important points for the C++ implementation: |
| |
| * Don't modify MIR in the predicate |
| * Renderer lambdas should capture by value to avoid use-after-free. They will be used after the predicate returns. |
| * Only create instructions in a renderer lambda. GlobalISel won't clean up things you create but don't use. |
| |
| |