348 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
			
		
		
	
	
			348 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
.. _milegalizer:
 | 
						|
 | 
						|
Legalizer
 | 
						|
---------
 | 
						|
 | 
						|
This pass transforms the generic machine instructions such that they are legal.
 | 
						|
 | 
						|
A legal instruction is defined as:
 | 
						|
 | 
						|
* **selectable** --- the target will later be able to select it to a
 | 
						|
  target-specific (non-generic) instruction. This doesn't necessarily mean that
 | 
						|
  :doc:`InstructionSelect` has to handle it though. It just means that
 | 
						|
  **something** must handle it.
 | 
						|
 | 
						|
* operating on **vregs that can be loaded and stored** -- if necessary, the
 | 
						|
  target can select a ``G_LOAD``/``G_STORE`` of each gvreg operand.
 | 
						|
 | 
						|
As opposed to SelectionDAG, there are no legalization phases.  In particular,
 | 
						|
'type' and 'operation' legalization are not separate.
 | 
						|
 | 
						|
Legalization is iterative, and all state is contained in GMIR.  To maintain the
 | 
						|
validity of the intermediate code, instructions are introduced:
 | 
						|
 | 
						|
* ``G_MERGE_VALUES`` --- concatenate multiple registers of the same
 | 
						|
  size into a single wider register.
 | 
						|
 | 
						|
* ``G_UNMERGE_VALUES`` --- extract multiple registers of the same size
 | 
						|
  from a single wider register.
 | 
						|
 | 
						|
* ``G_EXTRACT`` --- extract a simple register (as contiguous sequences of bits)
 | 
						|
  from a single wider register.
 | 
						|
 | 
						|
As they are expected to be temporary byproducts of the legalization process,
 | 
						|
they are combined at the end of the :ref:`milegalizer` pass.
 | 
						|
If any remain, they are expected to always be selectable, using loads and stores
 | 
						|
if necessary.
 | 
						|
 | 
						|
The legality of an instruction may only depend on the instruction itself and
 | 
						|
must not depend on any context in which the instruction is used. However, after
 | 
						|
deciding that an instruction is not legal, using the context of the instruction
 | 
						|
to decide how to legalize the instruction is permitted. As an example, if we
 | 
						|
have a ``G_FOO`` instruction of the form::
 | 
						|
 | 
						|
  %1:_(s32) = G_CONSTANT i32 1
 | 
						|
  %2:_(s32) = G_FOO %0:_(s32), %1:_(s32)
 | 
						|
 | 
						|
it's impossible to say that G_FOO is legal iff %1 is a ``G_CONSTANT`` with
 | 
						|
value ``1``. However, the following::
 | 
						|
 | 
						|
  %2:_(s32) = G_FOO %0:_(s32), i32 1
 | 
						|
 | 
						|
can say that it's legal iff operand 2 is an immediate with value ``1`` because
 | 
						|
that information is entirely contained within the single instruction.
 | 
						|
 | 
						|
.. _api-legalizerinfo:
 | 
						|
 | 
						|
API: LegalizerInfo
 | 
						|
^^^^^^^^^^^^^^^^^^
 | 
						|
 | 
						|
The recommended [#legalizer-legacy-footnote]_ API looks like this::
 | 
						|
 | 
						|
  getActionDefinitionsBuilder({G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR, G_SHL})
 | 
						|
      .legalFor({s32, s64, v2s32, v4s32, v2s64})
 | 
						|
      .clampScalar(0, s32, s64)
 | 
						|
      .widenScalarToNextPow2(0)
 | 
						|
      .clampNumElements(0, v2s32, v4s32)
 | 
						|
      .clampNumElements(0, v2s64, v2s64)
 | 
						|
      .moreElementsToNextPow2(0);
 | 
						|
 | 
						|
and describes a set of rules by which we can either declare an instruction legal
 | 
						|
or decide which action to take to make it more legal.
 | 
						|
 | 
						|
At the core of this ruleset is the ``LegalityQuery`` which describes the
 | 
						|
instruction. We use a description rather than the instruction to both allow other
 | 
						|
passes to determine legality without having to create an instruction and also to
 | 
						|
limit the information available to the predicates to that which is safe to rely
 | 
						|
on. Currently, the information available to the predicates that determine
 | 
						|
legality contains:
 | 
						|
 | 
						|
* The opcode for the instruction
 | 
						|
 | 
						|
* The type of each type index (see ``type0``, ``type1``, etc.)
 | 
						|
 | 
						|
* The size in bytes and atomic ordering for each MachineMemOperand
 | 
						|
 | 
						|
.. note::
 | 
						|
 | 
						|
  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``, ...) that instruct it to call a
 | 
						|
  function. This would have some benefits, most notable being that Custom could
 | 
						|
  be removed.
 | 
						|
 | 
						|
.. rubric:: Footnotes
 | 
						|
 | 
						|
.. [#legalizer-legacy-footnote] An API is broadly similar to
 | 
						|
   SelectionDAG/TargetLowering is available but is not recommended as a more
 | 
						|
   powerful API is available.
 | 
						|
 | 
						|
Rule Processing and Declaring Rules
 | 
						|
"""""""""""""""""""""""""""""""""""
 | 
						|
 | 
						|
The ``getActionDefinitionsBuilder`` function generates a ruleset for the given
 | 
						|
opcode(s) that rules can be added to. If multiple opcodes are given, they are
 | 
						|
all permanently bound to the same ruleset. The rules in a ruleset are executed
 | 
						|
from top to bottom and will start again from the top if an instruction is
 | 
						|
legalized as a result of the rules. If the ruleset is exhausted without
 | 
						|
satisfying any rule, then it is considered unsupported.
 | 
						|
 | 
						|
When it doesn't declare the instruction legal, each pass over the rules may
 | 
						|
request that one type changes to another type. Sometimes this can cause multiple
 | 
						|
types to change but we avoid this as much as possible as making multiple changes
 | 
						|
can make it difficult to avoid infinite loops where, for example, narrowing one
 | 
						|
type causes another to be too small and widening that type causes the first one
 | 
						|
to be too big.
 | 
						|
 | 
						|
In general, it's advisable to declare instructions legal as close to the top of
 | 
						|
the rule as possible and to place any expensive rules as low as possible. This
 | 
						|
helps with performance as testing for legality happens more often than
 | 
						|
legalization and legalization can require multiple passes over the rules.
 | 
						|
 | 
						|
As a concrete example, consider the rule::
 | 
						|
 | 
						|
  getActionDefinitionsBuilder({G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR, G_SHL})
 | 
						|
      .legalFor({s32, s64, v2s32, v4s32, v2s64})
 | 
						|
      .clampScalar(0, s32, s64)
 | 
						|
      .widenScalarToNextPow2(0);
 | 
						|
 | 
						|
and the instruction::
 | 
						|
 | 
						|
  %2:_(s7) = G_ADD %0:_(s7), %1:_(s7)
 | 
						|
 | 
						|
this doesn't meet the predicate for the :ref:`.legalFor() <legalfor>` as ``s7``
 | 
						|
is not one of the listed types so it falls through to the
 | 
						|
:ref:`.clampScalar() <clampscalar>`. It does meet the predicate for this rule
 | 
						|
as the type is smaller than the ``s32`` and this rule instructs the legalizer
 | 
						|
to change type 0 to ``s32``. It then restarts from the top. This time it does
 | 
						|
satisfy ``.legalFor()`` and the resulting output is::
 | 
						|
 | 
						|
  %3:_(s32) = G_ANYEXT %0:_(s7)
 | 
						|
  %4:_(s32) = G_ANYEXT %1:_(s7)
 | 
						|
  %5:_(s32) = G_ADD %3:_(s32), %4:_(s32)
 | 
						|
  %2:_(s7) = G_TRUNC %5:_(s32)
 | 
						|
 | 
						|
where the ``G_ADD`` is legal and the other instructions are scheduled for
 | 
						|
processing by the legalizer.
 | 
						|
 | 
						|
Rule Actions
 | 
						|
""""""""""""
 | 
						|
 | 
						|
There are various rule factories that append rules to a ruleset but they have a
 | 
						|
few actions in common:
 | 
						|
 | 
						|
.. _legalfor:
 | 
						|
 | 
						|
* ``legalIf()``, ``legalFor()``, etc. declare an instruction to be legal if the
 | 
						|
  predicate is satisfied.
 | 
						|
 | 
						|
* ``narrowScalarIf()``, ``narrowScalarFor()``, etc. declare an instruction to be illegal
 | 
						|
  if the predicate is satisfied and indicates that narrowing the scalars in one
 | 
						|
  of the types to a specific type would make it more legal. This action supports
 | 
						|
  both scalars and vectors.
 | 
						|
 | 
						|
* ``widenScalarIf()``, ``widenScalarFor()``, etc. declare an instruction to be illegal
 | 
						|
  if the predicate is satisfied and indicates that widening the scalars in one
 | 
						|
  of the types to a specific type would make it more legal. This action supports
 | 
						|
  both scalars and vectors.
 | 
						|
 | 
						|
* ``fewerElementsIf()``, ``fewerElementsFor()``, etc. declare an instruction to be
 | 
						|
  illegal if the predicate is satisfied and indicates reducing the number of
 | 
						|
  vector elements in one of the types to a specific type would make it more
 | 
						|
  legal. This action supports vectors.
 | 
						|
 | 
						|
* ``moreElementsIf()``, ``moreElementsFor()``, etc. declare an instruction to be illegal
 | 
						|
  if the predicate is satisfied and indicates increasing the number of vector
 | 
						|
  elements in one of the types to a specific type would make it more legal.
 | 
						|
  This action supports vectors.
 | 
						|
 | 
						|
* ``lowerIf()``, ``lowerFor()``, etc. declare an instruction to be illegal if the
 | 
						|
  predicate is satisfied and indicates that replacing it with equivalent
 | 
						|
  instruction(s) would make it more legal. Support for this action differs for
 | 
						|
  each opcode.
 | 
						|
 | 
						|
* ``libcallIf()``, ``libcallFor()``, etc. declare an instruction to be illegal if the
 | 
						|
  predicate is satisfied and indicates that replacing it with a libcall would
 | 
						|
  make it more legal. Support for this action differs for
 | 
						|
  each opcode.
 | 
						|
 | 
						|
* ``customIf()``, ``customFor()``, etc. declare an instruction to be illegal if the
 | 
						|
  predicate is satisfied and indicates that the backend developer will supply
 | 
						|
  a means of making it more legal.
 | 
						|
 | 
						|
* ``unsupportedIf()``, ``unsupportedFor()``, etc. declare an instruction to be illegal
 | 
						|
  if the predicate is satisfied and indicates that there is no way to make it
 | 
						|
  legal and the compiler should fail.
 | 
						|
 | 
						|
* ``fallback()`` falls back on an older API and should only be used while porting
 | 
						|
  existing code from that API.
 | 
						|
 | 
						|
Rule Predicates
 | 
						|
"""""""""""""""
 | 
						|
 | 
						|
The rule factories also have predicates in common:
 | 
						|
 | 
						|
* ``legal()``, ``lower()``, etc. are always satisfied.
 | 
						|
 | 
						|
* ``legalIf()``, ``narrowScalarIf()``, etc. are satisfied if the user-supplied
 | 
						|
  ``LegalityPredicate`` function returns true. This predicate has access to the
 | 
						|
  information in the ``LegalityQuery`` to make its decision.
 | 
						|
  User-supplied predicates can also be combined using ``all(P0, P1, ...)``.
 | 
						|
 | 
						|
* ``legalFor()``, ``narrowScalarFor()``, etc. are satisfied if the type matches one in
 | 
						|
  a given set of types. For example ``.legalFor({s16, s32})`` declares the
 | 
						|
  instruction legal if type 0 is either s16 or s32. Additional versions for two
 | 
						|
  and three type indices are generally available. For these, all the type
 | 
						|
  indices considered together must match all the types in one of the tuples. So
 | 
						|
  ``.legalFor({{s16, s32}, {s32, s64}})`` will only accept ``{s16, s32}``, or
 | 
						|
  ``{s32, s64}`` but will not accept ``{s16, s64}``.
 | 
						|
 | 
						|
* ``legalForTypesWithMemSize()``, ``narrowScalarForTypesWithMemSize()``, etc. are
 | 
						|
  similar to ``legalFor()``, ``narrowScalarFor()``, etc. but additionally require a
 | 
						|
  MachineMemOperand to have a given size in each tuple.
 | 
						|
 | 
						|
* ``legalForCartesianProduct()``, ``narrowScalarForCartesianProduct()``, etc. are
 | 
						|
  satisfied if each type index matches one element in each of the independent
 | 
						|
  sets. So ``.legalForCartesianProduct({s16, s32}, {s32, s64})`` will accept
 | 
						|
  ``{s16, s32}``, ``{s16, s64}``, ``{s32, s32}``, and ``{s32, s64}``.
 | 
						|
 | 
						|
Composite Rules
 | 
						|
"""""""""""""""
 | 
						|
 | 
						|
There are some composite rules for common situations built out of the above facilities:
 | 
						|
 | 
						|
* ``widenScalarToNextPow2()`` is like ``widenScalarIf()`` but is satisfied iff the type
 | 
						|
  size in bits is not a power of 2 and selects a target type that is the next
 | 
						|
  largest power of 2. 
 | 
						|
 | 
						|
.. _clampscalar:
 | 
						|
 | 
						|
* ``minScalar()`` is like ``widenScalarIf()`` but is satisfied iff the type
 | 
						|
  size in bits is smaller than the given minimum and selects the minimum as the
 | 
						|
  target type. Similarly, there is also a ``maxScalar()`` for the maximum and a
 | 
						|
  ``clampScalar()`` to do both at once. 
 | 
						|
 | 
						|
* ``minScalarSameAs()`` is like ``minScalar()`` but the minimum is taken from another
 | 
						|
  type index.
 | 
						|
 | 
						|
* ``moreElementsToNextMultiple()`` is like ``moreElementsToNextPow2()`` but is based on
 | 
						|
  multiples of X rather than powers of 2.
 | 
						|
 | 
						|
.. _min-legalizerinfo:
 | 
						|
 | 
						|
Minimum Rule Set
 | 
						|
^^^^^^^^^^^^^^^^
 | 
						|
 | 
						|
GlobalISel's legalizer has a great deal of flexibility in how a given target
 | 
						|
shapes the GMIR that the rest of the backend must handle. However, there are
 | 
						|
a small number of requirements that all targets must meet.
 | 
						|
 | 
						|
Before discussing the minimum requirements, we'll need some terminology:
 | 
						|
 | 
						|
Producer Type Set
 | 
						|
  The set of types which is the union of all possible types produced by at
 | 
						|
  least one legal instruction.
 | 
						|
 | 
						|
Consumer Type Set
 | 
						|
  The set of types which is the union of all possible types consumed by at
 | 
						|
  least one legal instruction.
 | 
						|
 | 
						|
Both sets are often identical but there's no guarantee of that. For example,
 | 
						|
it's not uncommon to be unable to consume s64 but still be able to produce it
 | 
						|
for a few specific instructions.
 | 
						|
 | 
						|
Minimum Rules For Scalars
 | 
						|
"""""""""""""""""""""""""
 | 
						|
 | 
						|
* G_ANYEXT must be legal for all inputs from the producer type set and all larger
 | 
						|
  outputs from the consumer type set.
 | 
						|
* G_TRUNC must be legal for all inputs from the producer type set and all
 | 
						|
  smaller outputs from the consumer type set.
 | 
						|
 | 
						|
G_ANYEXT, and G_TRUNC have mandatory legality since the GMIR requires a means to
 | 
						|
connect operations with different type sizes. They are usually trivial to support
 | 
						|
since G_ANYEXT doesn't define the value of the additional bits and G_TRUNC is
 | 
						|
discarding bits. The other conversions can be lowered into G_ANYEXT/G_TRUNC
 | 
						|
with some additional operations that are subject to further legalization. For
 | 
						|
example, G_SEXT can lower to::
 | 
						|
 | 
						|
  %1 = G_ANYEXT %0
 | 
						|
  %2 = G_CONSTANT ...
 | 
						|
  %3 = G_SHL %1, %2
 | 
						|
  %4 = G_ASHR %3, %2
 | 
						|
 | 
						|
and the G_CONSTANT/G_SHL/G_ASHR can further lower to other operations or target
 | 
						|
instructions. Similarly, G_FPEXT has no legality requirement since it can lower
 | 
						|
to a G_ANYEXT followed by a target instruction.
 | 
						|
 | 
						|
G_MERGE_VALUES and G_UNMERGE_VALUES do not have legality requirements since the
 | 
						|
former can lower to G_ANYEXT and some other legalizable instructions, while the
 | 
						|
latter can lower to some legalizable instructions followed by G_TRUNC.
 | 
						|
 | 
						|
Minimum Legality For Vectors
 | 
						|
""""""""""""""""""""""""""""
 | 
						|
 | 
						|
Within the vector types, there aren't any defined conversions in LLVM IR as
 | 
						|
vectors are often converted by reinterpreting the bits or by decomposing the
 | 
						|
vector and reconstituting it as a different type. As such, G_BITCAST is the
 | 
						|
only operation to account for. We generally don't require that it's legal
 | 
						|
because it can usually be lowered to COPY (or to nothing using
 | 
						|
replaceAllUses()). However, there are situations where G_BITCAST is non-trivial
 | 
						|
(e.g. little-endian vectors of big-endian data such as on big-endian MIPS MSA and
 | 
						|
big-endian ARM NEON, see `_i_bitcast`). To account for this G_BITCAST must be
 | 
						|
legal for all type combinations that change the bit pattern in the value.
 | 
						|
 | 
						|
There are no legality requirements for G_BUILD_VECTOR, or G_BUILD_VECTOR_TRUNC
 | 
						|
since these can be handled by:
 | 
						|
* Declaring them legal.
 | 
						|
* Scalarizing them.
 | 
						|
* Lowering them to G_TRUNC+G_ANYEXT and some legalizable instructions.
 | 
						|
* Lowering them to target instructions which are legal by definition.
 | 
						|
 | 
						|
The same reasoning also allows G_UNMERGE_VALUES to lack legality requirements
 | 
						|
for vector inputs.
 | 
						|
 | 
						|
Minimum Legality for Pointers
 | 
						|
"""""""""""""""""""""""""""""
 | 
						|
 | 
						|
There are no minimum rules for pointers since G_INTTOPTR and G_PTRTOINT can
 | 
						|
be selected to a COPY from register class to another by the legalizer.
 | 
						|
 | 
						|
Minimum Legality For Operations
 | 
						|
"""""""""""""""""""""""""""""""
 | 
						|
 | 
						|
The rules for G_ANYEXT, G_MERGE_VALUES, G_BITCAST, G_BUILD_VECTOR,
 | 
						|
G_BUILD_VECTOR_TRUNC, G_CONCAT_VECTORS, G_UNMERGE_VALUES, G_PTRTOINT, and
 | 
						|
G_INTTOPTR have already been noted above. In addition to those, the following
 | 
						|
operations have requirements:
 | 
						|
 | 
						|
* At least one G_IMPLICIT_DEF must be legal. This is usually trivial as it
 | 
						|
  requires no code to be selected.
 | 
						|
* G_PHI must be legal for all types in the producer and consumer typesets. This
 | 
						|
  is usually trivial as it requires no code to be selected.
 | 
						|
* At least one G_FRAME_INDEX must be legal
 | 
						|
* At least one G_BLOCK_ADDR must be legal
 | 
						|
 | 
						|
There are many other operations you'd expect to have legality requirements but
 | 
						|
they can be lowered to target instructions which are legal by definition.
 |