diff --git a/basis/compiler/cfg/linear-scan/allocation/spilling/spilling-docs.factor b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling-docs.factor new file mode 100644 index 0000000000..46935be344 --- /dev/null +++ b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling-docs.factor @@ -0,0 +1,10 @@ +USING: compiler.cfg.linear-scan.live-intervals help.markup help.syntax ; +IN: compiler.cfg.linear-scan.allocation.spilling + +HELP: spill-intersecting-active +{ $values { "new" live-interval-state } { "reg" "register" } } +{ $description "If there is an active interval using 'reg' (there should be at most one) are split and spilled and removed from the inactive set." } ; + +HELP: spill-partially-available +{ $values { "new" live-interval-state } { "pair" "register availability status" } } +{ $description "A register would be available for part of the new interval's lifetime if all active and inactive intervals using that register were split and spilled." } ; diff --git a/basis/compiler/cfg/linear-scan/allocation/spilling/spilling-tests.factor b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling-tests.factor new file mode 100644 index 0000000000..57b3be8336 --- /dev/null +++ b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling-tests.factor @@ -0,0 +1,37 @@ +USING: compiler.cfg.instructions compiler.cfg.linear-scan.allocation.spilling +compiler.cfg.linear-scan.live-intervals cpu.architecture sequences tools.test ; +IN: compiler.cfg.linear-scan.allocation.spilling.tests + +! last-use-rep +{ + double-rep +} [ + T{ live-interval-state + { vreg 45 } + { spill-to T{ spill-slot { n 8 } } } + { spill-rep double-rep } + { start 22 } + { end 47 } + { ranges + T{ slice + { from 0 } + { to 1 } + { seq + { + T{ live-range { from 22 } { to 47 } } + T{ live-range { from 67 } { to 68 } } + T{ live-range { from 69 } { to 72 } } + } + } + } + } + { uses + { + T{ vreg-use + { n 28 } + { use-rep double-rep } + } + } + } + } last-use-rep +] unit-test diff --git a/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor index 104fbce16e..8d1e4fba5a 100644 --- a/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor +++ b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor @@ -114,9 +114,6 @@ ERROR: bad-live-ranges interval ; [ [ add-unhandled ] when* ] bi* ; :: spill-intersecting-active ( new reg -- ) - ! If there is an active interval using 'reg' (there should be at - ! most one) are split and spilled and removed from the inactive - ! set. new active-intervals-for [ [ reg>> reg = ] find swap dup ] keep '[ _ remove-nth! drop new start>> spill ] [ 2drop ] if ; @@ -144,14 +141,11 @@ ERROR: bad-live-ranges interval ; ! and spilled. [ first spill-intersecting ] [ register-available ] 2bi ; -: spill-partially-available ( new pair -- ) - ! A register would be available for part of the new - ! interval's lifetime if all active and inactive intervals - ! using that register were split and spilled. +: spill-partially-available ( live-interval pair -- ) [ second 1 - split-for-spill [ add-unhandled ] when* ] keep '[ _ spill-available ] when* ; -: assign-blocked-register ( new -- ) +: assign-blocked-register ( live-interval -- ) dup spill-status { { [ 2dup spill-new? ] [ spill-new ] } { [ 2dup register-available? ] [ spill-available ] }