| (irtranslator)= |
| |
| # IRTranslator |
| |
| 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: |
| |
| ```llvm |
| %2 = add i32 %0, %1 |
| ``` |
| |
| becomes: |
| |
| ```none |
| %2:_(s32) = G_ADD %0:_(s32), %1:_(s32) |
| ``` |
| |
| whereas |
| |
| ```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. |
| |
| (irtranslator-byte-type)= |
| |
| ## Translation of the Byte Type |
| |
| The {ref}`byte type <t_byte>` (`bN`) has no distinct GMIR representation and |
| is translated as the `LLT::integer(N)`. This mirrors the |
| SelectionDAG behaviour, where `bN` maps to the same `EVT` as `iN`. |
| |
| - `getLLTForType` lowers `ByteType` to `LLT::integer(N)`. |
| - `ConstantByte` is materialised via `G_CONSTANT` using the underlying |
| `APInt`, the same path as `ConstantInt`. |
| - A `bitcast` between a byte type and a pointer (the only ptr/non-ptr |
| `bitcast` IR permits with byte) is lowered to `G_INTTOPTR` or |
| `G_PTRTOINT` rather than `G_BITCAST`, since `G_BITCAST` cannot cross |
| the pointer/non-pointer boundary under `MachineVerifier`. |
| |
| The mid-end semantics of the byte type (per-bit poison, conditional pointer |
| provenance preservation) are not representable in MIR and are not consumed by |
| any backend pass; they are lost at the IR-to-MIR boundary. |
| |