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:
Jakob Stoklund Olesen
2016-10-20 15:34:16 -07:00
parent bb0bb1e91c
commit 84172ddf98
2 changed files with 59 additions and 1 deletions

View File

@@ -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
load a constant into an SSA value.
.. autoinst:: select
Constant materialization
------------------------
.. autoinst:: iconst
.. autoinst:: f32const
.. autoinst:: f64const
.. 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
-----------------

View File

@@ -204,6 +204,40 @@ select = Instruction(
""",
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
#