150
|
1
|
|
2 .. _instructionselect:
|
|
3
|
|
4 InstructionSelect
|
|
5 -----------------
|
|
6
|
|
7 This pass transforms generic machine instructions into equivalent
|
|
8 target-specific instructions. It traverses the ``MachineFunction`` bottom-up,
|
|
9 selecting uses before definitions, enabling trivial dead code elimination.
|
|
10
|
|
11 .. _api-instructionselector:
|
|
12
|
|
13 API: InstructionSelector
|
|
14 ^^^^^^^^^^^^^^^^^^^^^^^^
|
|
15
|
|
16 The target implements the ``InstructionSelector`` class, containing the
|
|
17 target-specific selection logic proper.
|
|
18
|
|
19 The instance is provided by the subtarget, so that it can specialize the
|
|
20 selector by subtarget feature (with, e.g., a vector selector overriding parts
|
|
21 of a general-purpose common selector).
|
|
22 We might also want to parameterize it by MachineFunction, to enable selector
|
|
23 variants based on function attributes like optsize.
|
|
24
|
|
25 The simple API consists of:
|
|
26
|
|
27 .. code-block:: c++
|
|
28
|
|
29 virtual bool select(MachineInstr &MI)
|
|
30
|
|
31 This target-provided method is responsible for mutating (or replacing) a
|
|
32 possibly-generic MI into a fully target-specific equivalent.
|
|
33 It is also responsible for doing the necessary constraining of gvregs into the
|
|
34 appropriate register classes as well as passing through COPY instructions to
|
|
35 the register allocator.
|
|
36
|
|
37 The ``InstructionSelector`` can fold other instructions into the selected MI,
|
|
38 by walking the use-def chain of the vreg operands.
|
|
39 As GlobalISel is Global, this folding can occur across basic blocks.
|
|
40
|
|
41 SelectionDAG Rule Imports
|
|
42 ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
43
|
|
44 TableGen will import SelectionDAG rules and provide the following function to
|
|
45 execute them:
|
|
46
|
|
47 .. code-block:: c++
|
|
48
|
|
49 bool selectImpl(MachineInstr &MI)
|
|
50
|
|
51 The ``--stats`` option can be used to determine what proportion of rules were
|
|
52 successfully imported. The easiest way to use this is to copy the
|
|
53 ``-gen-globalisel`` tablegen command from ``ninja -v`` and modify it.
|
|
54
|
|
55 Similarly, the ``--warn-on-skipped-patterns`` option can be used to obtain the
|
|
56 reasons that rules weren't imported. This can be used to focus on the most
|
|
57 important rejection reasons.
|
|
58
|
|
59 PatLeaf Predicates
|
|
60 ^^^^^^^^^^^^^^^^^^
|
|
61
|
|
62 PatLeafs cannot be imported because their C++ is implemented in terms of
|
|
63 ``SDNode`` objects. PatLeafs that handle immediate predicates should be
|
|
64 replaced by ``ImmLeaf``, ``IntImmLeaf``, or ``FPImmLeaf`` as appropriate.
|
|
65
|
|
66 There's no standard answer for other PatLeafs. Some standard predicates have
|
|
67 been baked into TableGen but this should not generally be done.
|
|
68
|
|
69 Custom SDNodes
|
|
70 ^^^^^^^^^^^^^^
|
|
71
|
|
72 Custom SDNodes should be mapped to Target Pseudos using ``GINodeEquiv``. This
|
|
73 will cause the instruction selector to import them but you will also need to
|
|
74 ensure the target pseudo is introduced to the MIR before the instruction
|
|
75 selector. Any preceding pass is suitable but the legalizer will be a
|
|
76 particularly common choice.
|
|
77
|
|
78 ComplexPatterns
|
|
79 ^^^^^^^^^^^^^^^
|
|
80
|
|
81 ComplexPatterns cannot be imported because their C++ is implemented in terms of
|
|
82 ``SDNode`` objects. GlobalISel versions should be defined with
|
|
83 ``GIComplexOperandMatcher`` and mapped to ComplexPattern with
|
|
84 ``GIComplexPatternEquiv``.
|
|
85
|
|
86 The following predicates are useful for porting ComplexPattern:
|
|
87
|
|
88 * isBaseWithConstantOffset() - Check for base+offset structures
|
|
89 * isOperandImmEqual() - Check for a particular constant
|
|
90 * isObviouslySafeToFold() - Check for reasons an instruction can't be sunk and folded into another.
|
|
91
|
|
92 There are some important points for the C++ implementation:
|
|
93
|
|
94 * Don't modify MIR in the predicate
|
|
95 * Renderer lambdas should capture by value to avoid use-after-free. They will be used after the predicate returns.
|
|
96 * Only create instructions in a renderer lambda. GlobalISel won't clean up things you create but don't use.
|
|
97
|
|
98
|