Confirmed users
156
edits
mNo edit summary |
mNo edit summary |
||
| Line 1: | Line 1: | ||
= LIR = | = LIR = | ||
| Line 108: | Line 106: | ||
*<tt>REDEFINED</tt>, which says that this <tt>LDefinition</tt> is actually the same as another <tt>LDefinition</tt>. When <tt>REDEFINED</tt> is used, the <tt>LDefinition</tt> is completely ignored. The instruction is informing the register allocator that, rather than producing a new output, it is a "pass-through" mechanism (like boxes and unboxes on x86). | *<tt>REDEFINED</tt>, which says that this <tt>LDefinition</tt> is actually the same as another <tt>LDefinition</tt>. When <tt>REDEFINED</tt> is used, the <tt>LDefinition</tt> is completely ignored. The instruction is informing the register allocator that, rather than producing a new output, it is a "pass-through" mechanism (like boxes and unboxes on x86). | ||
If the <tt>LDefinition</tt> does not have a <tt>PRESET</tt> or <tt>REDEFINED</tt> policy, its <tt>LAllocation</tt> is filled in during register allocation. | If the <tt>LDefinition</tt> does not have a <tt>PRESET</tt> or <tt>REDEFINED</tt> policy, its <tt>LAllocation</tt> is filled in during register allocation.and are effectively removed during register allocation. | ||
= Lowering = | = Lowering = | ||
== Class Hierarchy == | |||
The process of converting MIR to LIR is Lowering. Lowering is implemented by LIRGenerator, which defines functions to lower each MIR instruction. To maximize the amount of code we can share between all platforms, LIRGenerator has a somewhat roundabout class hierarchy: | The process of converting MIR to LIR is Lowering. Lowering is implemented by LIRGenerator, which defines functions to lower each MIR instruction. To maximize the amount of code we can share between all platforms, LIRGenerator has a somewhat roundabout class hierarchy: | ||
| Line 119: | Line 119: | ||
We try to move as much logic into the derived-most <tt>LIRGenerator</tt> as possible. For example, math operations almost always have a conceptual three-register form (two inputs and an output), but on x86 generate two-register form code. Rather than exposing these differences in the structure of LIR, we expose them in allocation policies, and thus math-oriented policies are simply exposed on a per-architecture basis. | We try to move as much logic into the derived-most <tt>LIRGenerator</tt> as possible. For example, math operations almost always have a conceptual three-register form (two inputs and an output), but on x86 generate two-register form code. Rather than exposing these differences in the structure of LIR, we expose them in allocation policies, and thus math-oriented policies are simply exposed on a per-architecture basis. | ||
== Process == | |||
LIR is generated by iterating over MIR in reverse-postorder. Mapping from MIR to LIR is basically 1:1. When lowering an instruction, we first create <tt>LAllocations</tt> for its inputs. Depending on what the architecture allows, an operand begins as either a virtual register or a constant. Virtual registers are allocated when defining LIR definitions, and also attached to corresponding MIR nodes for later uses. | |||
If a LIR instruction defines a Value, and values are two definitions (as is the case on nunboxing platforms), then two virtual registers are allocated. However, only the first is associated with its corresponding MIR node - we assume virtual registers are contiguous and thus the distance between two virtual registers defining one Value is 1. | |||
Below is an example of how MIR might lower on x86 versus x64: | |||
[[Image:Ionmonkey_lir.png]] | |||
== Emitting at Uses == | |||
If some value has trivial rematerialization, for example, emitting an integer constant, or a box on x86, we can elect to emit the instruction at each point it is used, rather than when it is defined. The facility for doing this is to call <tt>emitAtUses()</tt> on the MIR being lowered. This informs the <tt>LIRGenerator</tt> to defer lowering. | |||
Later, if another instruction actually requires a virtual register for an input that has yet to be lowered, it will attempt to immediately lower that input. The visitor can check <tt>isEmittedAtUses</tt> on the instruction to see whether it must actually create LIR. | |||
== Phis == | |||
Phis in LIR define exactly one virtual register, and have an input virtual register for each predecessor block. On nunboxing platforms, an untyped (boxed) phi produces two LIR phi nodes: one for the type, and another for the payload. Phis are ignored during code generation, as register allocation breaks SSA form. | |||