Track allocatable registers both locally and globally: Add a second AllocatableSet which tracks registers allocated to global values without accounting for register diversions. Since diversions are only local to an EBB, global values must be assigned un-diverted locations that don't interfere. Handle the third "global" interference domain in the constraint solver in addition to the existing "input" and "output" domains. Extend the solver error code to indicate when a global define just can't be allocated because there are not enough available global registers. Resolve this problem by replacing the instruction's global defines with local defines that are copied into their global destinations afterwards.
28 lines
688 B
Plaintext
28 lines
688 B
Plaintext
test compile
|
|
isa intel
|
|
|
|
; This test covers the troubles when values with global live ranges are defined
|
|
; by instructions with constrained register classes.
|
|
;
|
|
; The icmp_imm instrutions write their b1 result to the ABCD register class on
|
|
; 32-bit Intel. So if we define 5 live values, they can't all fit.
|
|
function %global_constraints(i32) {
|
|
ebb0(v0: i32):
|
|
v1 = icmp_imm eq v0, 1
|
|
v2 = icmp_imm ugt v0, 2
|
|
v3 = icmp_imm sle v0, 3
|
|
v4 = icmp_imm ne v0, 4
|
|
v5 = icmp_imm sge v0, 5
|
|
brnz v5, ebb1
|
|
return
|
|
|
|
ebb1:
|
|
; Make sure v1-v5 are live in.
|
|
v10 = band v1, v2
|
|
v11 = bor v3, v4
|
|
v12 = bor v10, v11
|
|
v13 = bor v12, v5
|
|
trapnz v13, user0
|
|
return
|
|
}
|