The old coalescing algorithm had some algorithmic complexity issues when dealing with large virtual registers. Reimplement to use a proper union-find algorithm so we only need one pass through the dominator forests for virtual registers that are interference free. Virtual registers that do have interference are split and new registers built. This pass is about twice as fast as the old one when dealing with complex virtual registers.
38 lines
711 B
Plaintext
38 lines
711 B
Plaintext
test regalloc
|
|
isa riscv
|
|
|
|
; Here, the coalescer initially builds vreg0 = [v1, v2, v3]
|
|
;
|
|
; There's interference between v1 and v2 at the brz instruction. Isolating v2 is not going to
|
|
; resolve that conflict since v1 will just interfere with the inserted copy too.
|
|
|
|
;function %c1(i32) -> i32 {
|
|
;ebb0(v0: i32):
|
|
; v1 = iadd_imm v0, 1
|
|
; v2 = iconst.i32 1
|
|
; brz v1, ebb1(v2)
|
|
; jump ebb2
|
|
;
|
|
;ebb1(v3: i32):
|
|
; return v3
|
|
;
|
|
;ebb2:
|
|
; jump ebb1(v1)
|
|
;}
|
|
|
|
; Same thing with v1 and v2 swapped to reverse the order of definitions.
|
|
|
|
function %c2(i32) -> i32 {
|
|
ebb0(v0: i32):
|
|
v1 = iadd_imm v0, 1
|
|
v2 = iconst.i32 1
|
|
brz v2, ebb1(v1)
|
|
jump ebb2
|
|
|
|
ebb1(v3: i32):
|
|
return v3
|
|
|
|
ebb2:
|
|
jump ebb1(v2)
|
|
}
|