125 lines
4.8 KiB
ReStructuredText
125 lines
4.8 KiB
ReStructuredText
.. _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.
|