Index: docs/GlobalISel.rst
===================================================================
--- docs/GlobalISel.rst
+++ docs/GlobalISel.rst
@@ -340,62 +340,78 @@
essentially a tuple consisting of ``(Opcode, TypeIdx, Type)`` and mapping to a
suggested course of action.
-An example use might be:
-
- .. code-block:: c++
-
- // The CPU can't deal with an s1 result, do something about it.
- setAction({G_ICMP, 0, s1}, WidenScalar);
- // An s32 input (the second type) is fine though.
- setAction({G_ICMP, 1, s32}, Legal);
-
+There are 2 broad categories of actions: those that change the size of the
+type, and those that don't change the size of the type. Both are specified
+slightly differently. An example is:
+
+.. code-block:: c++
+
+ // s32 and s64 inputs (the second type) are fine.
+ for (auto Ty : {s32, s64})
+ setAction({G_ICMP, 1, Ty}, Legal);
+ // The CPU can't deal with other sizes:
+ setLegalizeScalarToDifferentSizeStrategy(
+ G_ICMP, 1, widenToLargerAndNarrowToLargest);
+
+Actions that don't change the size of the type are specified using calls to
+``setAction``. Actions that specify how to change types of an illegal size to a
+legal size are specified using calls to
+``setLegalizeScalarToDifferentSizeStrategy``, indicating which
+``SizeChangeStrategy`` to follow. In the example, the
+``widenToLargerAndNarrowToLargest`` SizeChangeStrategy will widen the type to
+the next bigger legal size if there is such one; otherwise, it will narrow the
+type to the largest legal one. For example, a G_ICMP on s16 would be widened to
+a G_ICMP on s32. A G_ICMP on s96 will be narrowed to a sequence of G_ICMPs on
+s64.
+
+``TODO``: Many of the actual lowerings to narrower or wider types haven't been
+implemented yet for non-power-of-2 types.
``TODO``:
-An alternative worth investigating is to generalize the API to represent
-actions using ``std::function`` that implements the action, instead of explicit
-enum tokens (``Legal``, ``WidenScalar``, ...).
-
-``TODO``:
-Moreover, we could use TableGen to initially infer legality of operation from
-existing patterns (as any pattern we can select is by definition legal).
-Expanding that to describe legalization actions is a much larger but
-potentially useful project.
-
-.. _milegalizer-non-power-of-2:
-
-Non-power of 2 types
-^^^^^^^^^^^^^^^^^^^^
-
-``TODO``:
-Types which have a size that isn't a power of 2 aren't currently supported.
-The setAction API will probably require changes to support them.
-Even notionally explicitly specified operations only make suggestions
-like "Widen" or "Narrow". The eventual type is still unspecified and a
-search is performed by repeated doubling/halving of the type's
-size.
-This is incorrect for types that aren't a power of 2. It's reasonable to
-expect we could construct an efficient set of side-tables for more general
-lookups though, encoding a map from the integers (i.e. the size of the current
-type) to types (the legal size).
+We could use TableGen to initially infer legality of operation from existing
+patterns (as any pattern we can select is by definition legal). Expanding that
+to describe legalization actions is a much larger but potentially useful
+project.
.. _milegalizer-vector:
Vector types
^^^^^^^^^^^^
-Vectors first get their element type legalized: ```` becomes
-```` such that at least one operation is legal with ``sC``.
+For vector types, the specification of what the legally-sized types are is very
+similar to the scalar types, for example:
+
+.. code-block:: c++
-This is currently specified by the function ``setScalarInVectorAction``, called
-for example as:
+ setAction({G_ADD, LLT::vector(8, 8)}, LegalizerInfo::Legal);
+ setAction({G_ADD, LLT::vector(16, 8)}, LegalizerInfo::Legal);
+ setAction({G_ADD, LLT::vector(4, 16)}, LegalizerInfo::Legal);
+ setAction({G_ADD, LLT::vector(8, 16)}, LegalizerInfo::Legal);
+ setAction({G_ADD, LLT::vector(2, 32)}, LegalizerInfo::Legal);
+ setAction({G_ADD, LLT::vector(4, 32)}, LegalizerInfo::Legal);
+ setLegalizeVectorElementToDifferentSizeStrategy(
+ G_ADD, 0, widenToLargerTypesUnsupportedOtherwise);
- setScalarInVectorAction(G_ICMP, s1, WidenScalar);
+Vectors first get their element type legalized: ```` becomes
+```` such that at least one operation is legal with ``sC``.
+The strategy to follow for deciding the type ``sC`` is set by a call
+to ``setLegalizeVectorElementToDifferentSizeStrategy``.
Next the number of elements is chosen so that the entire operation is
legal. This aspect is not controllable at the moment, but probably
should be (you could imagine disagreements on whether a ``<2 x s8>``
operation should be scalarized or extended to ``<8 x s8>``).
+For the above example specification, the following example legalizations
+will happen:
+
+* ``getAction({G_ADD, LLT::vector(3, 3)})``
+ returns ``{WidenScalar, LLT::vector(3, 8)}``
+* ``getAction({G_ADD, LLT::vector(3, 8)})``
+ then returns ``{MoreElements, LLT::vector(8, 8)}``
+* ``getAction({G_ADD, LLT::vector(20, 8)})``
+ returns ``{FewerElements, LLT::vector(16, 8)}``
+
.. _regbankselect: