Avoid interference on CFG edges.

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.
This commit is contained in:
Jakob Stoklund Olesen
2017-10-10 09:45:06 -07:00
parent ba52a38597
commit 994af598f5
4 changed files with 378 additions and 90 deletions

View File

@@ -0,0 +1,27 @@
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
}