.. _irtranslator:
IRTranslator
============
.. contents::
:local:
This pass translates the input LLVM-IR ``Function`` to a :doc:`GMIR`
``MachineFunction``. This is typically a direct translation but does
occasionally get a bit more involved. For example:
.. code-block:: llvm
%2 = add i32 %0, %1
becomes:
.. code-block:: none
%2:_(s32) = G_ADD %0:_(s32), %1:_(s32)
whereas
.. code-block:: llvm
call i32 @puts(i8* %cast210)
is translated according to the ABI rules of the target.
.. note::
The currently implemented portion of the :doc:`../LangRef` is sufficient for
many compilations but it is not 100% complete. Users seeking to compile
LLVM-IR containing some of the rarer features may need to implement the
translation.
Target Intrinsics
-----------------
There has been some (off-list) debate about whether to add target hooks for
translating target intrinsics. Among those who discussed it, it was generally
agreed that the IRTranslator should be able to lower target intrinsics in a
customizable way but no work has happened to implement this at the time of
writing.
.. _translator-call-lower:
Translating Function Calls
--------------------------
The ``IRTranslator`` also implements the ABI's calling convention by lowering
calls, returns, and arguments to the appropriate physical register usage and
instruction sequences. This is achieved using the ``CallLowering`` interface,
which provides several hooks that targets should implement:
``lowerFormalArguments``, ``lowerReturn``, ``lowerCall`` etc.
In essence, all of these hooks need to find a way to move the argument/return
values between the virtual registers used in the rest of the function and either
physical registers or the stack, as dictated by the ABI. This may involve
splitting large types into smaller ones, introducing sign/zero extensions etc.
In order to share as much of this code as possible between the different
backends, ``CallLowering`` makes available a few helpers and interfaces:
* ``ArgInfo`` - used for formal arguments, but also return values, actual
arguments and call results; contains info such as the IR type, the virtual
registers etc; large values will likely have to be split into several
``ArgInfo`` objects (``CallLowering::splitToValueTypes`` can help with that);
* ``ValueAssigner`` - uses a ``CCAssignFn``, usually generated by TableGen (see
:ref:`backend-calling-convs`), to decide where to put each
``ArgInfo`` (physical register or stack); backends can use the provided
``IncomingValueAssigner`` (for formal arguments and call results) and
``OutgoingValueAssigner`` (for actual arguments and function returns), but
it's also possible to subclass them;
* ``ValueHandler`` - inserts the necessary instructions for putting each value
where it belongs; it has pure virtual methods for assigning values to
registers or to addresses, and a host of other helpers;
* ``determineAndHandleAssignments`` (or for more fine grained control,
``determineAssignments`` and ``handleAssignments``) - contains some boilerplate
for invoking a given ``ValueAssigner`` and ``ValueHandler`` on a series of
``ArgInfo`` objects.
.. _irtranslator-aggregates:
Aggregates
^^^^^^^^^^
.. caution::
This has changed since it was written and is no longer accurate. It has not
been refreshed in this pass of improving the documentation as I haven't
worked much in this part of the codebase and it should have attention from
someone more knowledgeable about it.
Aggregates are lowered into multiple virtual registers, similar to
SelectionDAG's multiple vregs via ``GetValueVTs``.
``TODO``:
As some of the bits are undef (padding), we should consider augmenting the
representation with additional metadata (in effect, caching computeKnownBits
information on vregs).
See `PR26161 <https://llvm.org/PR26161>`_: [GlobalISel] Value to vreg during
IR to MachineInstr translation for aggregate type
.. _irtranslator-constants:
Translation of Constants
------------------------
Constant operands are translated as a use of a virtual register that is defined
by a ``G_CONSTANT`` or ``G_FCONSTANT`` instruction. These instructions are
placed in the entry block to allow them to be subject to the continuous CSE
implementation (``CSEMIRBuilder``). Their debug location information is removed
to prevent this from confusing debuggers.
This is beneficial as it allows us to fold constants into immediate operands
during :ref:`instructionselect`, while still avoiding redundant materializations
for expensive non-foldable constants. However, this can lead to unnecessary
spills and reloads in an -O0 pipeline, as these virtual registers can have long
live ranges. This can be mitigated by running a `localizer <https://github.com/llvm/llvm-project/blob/main/llvm/lib/CodeGen/GlobalISel/Localizer.cpp>`_
after the translator.