99 lines
3.6 KiB
ReStructuredText
99 lines
3.6 KiB
ReStructuredText
|
|
.. _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.
|
|
|
|
|