Define live range splitting instructions.
The copy/spill/fill instructions will be used by the register allocator for splitting live ranges. The copy instruction is also useful when rewriting values: If a primary value is rewritten as a secondary result, a copy instruction can be used instead: a = foo x => t, vx1 = call ... a = copy vx1 Since a primary value must be the first value of an instruction, this doesn't work: a = foo x => t, a = call ...
This commit is contained in:
@@ -633,11 +633,35 @@ A few instructions have variants that take immediate operands (e.g.,
|
|||||||
:inst:`band` / :inst:`band_imm`), but in general an instruction is required to
|
:inst:`band` / :inst:`band_imm`), but in general an instruction is required to
|
||||||
load a constant into an SSA value.
|
load a constant into an SSA value.
|
||||||
|
|
||||||
|
.. autoinst:: select
|
||||||
|
|
||||||
|
Constant materialization
|
||||||
|
------------------------
|
||||||
|
|
||||||
.. autoinst:: iconst
|
.. autoinst:: iconst
|
||||||
.. autoinst:: f32const
|
.. autoinst:: f32const
|
||||||
.. autoinst:: f64const
|
.. autoinst:: f64const
|
||||||
.. autoinst:: vconst
|
.. autoinst:: vconst
|
||||||
.. autoinst:: select
|
|
||||||
|
Live range splitting
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Cretonne's register allocator assigns each SSA value to a register or a spill
|
||||||
|
slot on the stack for its entire live range. Since the live range of an SSA
|
||||||
|
value can be quite large, it is sometimes beneficial to split the live range
|
||||||
|
into smaller parts.
|
||||||
|
|
||||||
|
A live range is split by creating new SSA values that are copies or the
|
||||||
|
original value or each other. The copies are created by inserting :inst:`copy`,
|
||||||
|
:inst:`spill`, or :inst:`fill` instructions, depending on whether the values
|
||||||
|
are assigned to registers or stack slots.
|
||||||
|
|
||||||
|
This approach permits SSA form to be preserved throughout the register
|
||||||
|
allocation pass and beyond.
|
||||||
|
|
||||||
|
.. autoinst:: copy
|
||||||
|
.. autoinst:: spill
|
||||||
|
.. autoinst:: fill
|
||||||
|
|
||||||
Vector operations
|
Vector operations
|
||||||
-----------------
|
-----------------
|
||||||
|
|||||||
@@ -204,6 +204,40 @@ select = Instruction(
|
|||||||
""",
|
""",
|
||||||
ins=(c, x, y), outs=a)
|
ins=(c, x, y), outs=a)
|
||||||
|
|
||||||
|
x = Operand('x', Any)
|
||||||
|
|
||||||
|
copy = Instruction(
|
||||||
|
'copy', r"""
|
||||||
|
Register-register copy.
|
||||||
|
|
||||||
|
This instruction copies its input, preserving the value type.
|
||||||
|
|
||||||
|
A pure SSA-form program does not need to copy values, but this
|
||||||
|
instruction is useful for representing intermediate stages during
|
||||||
|
instruction transformations, and the register allocator needs a way of
|
||||||
|
representing register copies.
|
||||||
|
""",
|
||||||
|
ins=x, outs=a)
|
||||||
|
|
||||||
|
spill = Instruction(
|
||||||
|
'spill', r"""
|
||||||
|
Spill a register value to a stack slot.
|
||||||
|
|
||||||
|
This instruction behaves exactly like :inst:`copy`, but the result
|
||||||
|
value is assigned to a spill slot.
|
||||||
|
""",
|
||||||
|
ins=x, outs=a)
|
||||||
|
|
||||||
|
fill = Instruction(
|
||||||
|
'fill', r"""
|
||||||
|
Load a register value from a stack slot.
|
||||||
|
|
||||||
|
This instruction behaves exactly like :inst:`copy`, but the input
|
||||||
|
value is assigned to a spill slot.
|
||||||
|
""",
|
||||||
|
ins=x, outs=a)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Vector operations
|
# Vector operations
|
||||||
#
|
#
|
||||||
|
|||||||
Reference in New Issue
Block a user