Files
wasmtime/filetests/regalloc/coalesce.cton
Jakob Stoklund Olesen cf967642a3 Add a coalescing pass to the register allocator.
Coalescing means creating virtual registers and transforming the code
into conventional SSA form. This means that every value used as a branch
argument will belong to the same virtual register as the corresponding
EBB argument value.

Conventional SSA form makes it easy to avoid memory-memory copies when
spilling values, and the virtual registers can be used as hints when
picking registers too. This reduces the number of register moves needed
for EBB arguments.
2017-06-22 15:03:48 -07:00

92 lines
2.1 KiB
Plaintext

test regalloc
isa riscv
; Test the coalescer.
; regex: V=v\d+
; regex: WS=\s+
; This function is already CSSA, so no copies should be inserted.
function %cssa(i32) -> i32 {
ebb0(v0: i32):
; not: copy
; v0 is used by the branch and passed as an arg - that's no conflict.
brnz v0, ebb1(v0)
; v0 is live across the branch above. That's no conflict.
v1 = iadd_imm v0, 7
jump ebb1(v1)
ebb1(v10: i32):
v11 = iadd_imm v10, 7
return v11
}
function %trivial(i32) -> i32 {
ebb0(v0: i32):
; check: $(cp1=$V) = copy $v0
; nextln: brnz $v0, $ebb1($cp1)
brnz v0, ebb1(v0)
; not: copy
v1 = iadd_imm v0, 7
jump ebb1(v1)
ebb1(v10: i32):
; Use v0 in the destination EBB causes a conflict.
v11 = iadd v10, v0
return v11
}
; A value is used as an SSA argument twice in the same branch.
function %dualuse(i32) -> i32 {
ebb0(v0: i32):
; check: $(cp1=$V) = copy $v0
; nextln: brnz $v0, $ebb1($v0, $cp1)
brnz v0, ebb1(v0, v0)
; not: copy
v1 = iadd_imm v0, 7
v2 = iadd_imm v1, 56
jump ebb1(v1, v2)
ebb1(v10: i32, v11: i32):
v12 = iadd v10, v11
return v12
}
; Interference away from the branch
; The interference can be broken with a copy at either branch.
function %interference(i32) -> i32 {
ebb0(v0: i32):
; not: copy
brnz v0, ebb1(v0)
v1 = iadd_imm v0, 7
; v1 and v0 interfere here:
trapnz v0
; check: $(cp1=$V) = copy $v1
; nextln: jump $ebb1($cp1)
jump ebb1(v1)
ebb1(v10: i32):
; not: copy
v11 = iadd_imm v10, 7
return v11
}
; A loop where one induction variable is used as a backedge argument.
function %fibonacci(i32) -> i32 {
ebb0(v0: i32):
; not: copy
v1 = iconst.i32 1
v2 = iconst.i32 2
jump ebb1(v1, v2)
ebb1(v10: i32, v11: i32):
; v11 needs to be isolated because it interferes with v10.
; check: $ebb1($v10: i32, $(nv11a=$V): i32)
; check: $v11 = copy $nv11a
v12 = iadd v10, v11
v13 = icmp ult v12, v0
; check: $(nv11b=$V) = copy $v11
; nextln: brnz $v13, $ebb1($nv11b, $v12)
brnz v13, ebb1(v11, v12)
return v12
}