1 ! Copyright (C) 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: namespaces sequences math math.order kernel assocs
5 compiler.machine.linear-scan.live-intervals
7 IN: compiler.machine.linear-scan.allocation
9 ! Mapping from vregs to machine registers
10 SYMBOL: register-allocation
12 ! Mapping from vregs to spill locations
13 SYMBOL: spill-locations
15 ! Vector of active live intervals, in order of increasing end point
16 SYMBOL: active-intervals
18 : add-active ( live-interval -- )
19 active-intervals get push ;
21 : delete-active ( live-interval -- )
22 active-intervals get delete ;
24 ! Mapping from register classes to sequences of machine registers
25 SYMBOL: free-registers
27 ! Counter of spill locations
30 : next-spill-location ( -- n )
31 spill-counter [ dup 1+ ] change ;
33 : assign-spill ( live-interval -- )
34 next-spill-location swap vreg>> spill-locations get set-at ;
36 : free-registers-for ( vreg -- seq )
37 reg-class>> free-registers get at ;
39 : free-register ( vreg -- )
40 #! Free machine register currently assigned to vreg.
41 [ register-allocation get at ] [ free-registers-for ] bi push ;
43 : expire-old-intervals ( live-interval -- )
45 swap '[ end>> _ start>> < ] partition
47 [ vreg>> free-register ] each ;
49 : interval-to-spill ( -- live-interval )
50 #! We spill the interval with the longest remaining range.
51 active-intervals get unclip-slice [
52 [ [ end>> ] bi@ > ] most
55 : reuse-register ( live-interval to-spill -- )
57 register-allocation get
58 tuck [ at ] [ set-at ] 2bi* ;
60 : spill-at-interval ( live-interval -- )
62 2dup [ end>> ] bi@ > [
65 [ [ add-active ] [ delete-active ] bi* ]
67 ] [ drop assign-spill ] if ;
69 : init-allocator ( -- )
70 H{ } clone register-allocation set
71 H{ } clone spill-locations set
72 V{ } clone active-intervals set
73 machine-registers [ >vector ] assoc-map free-registers set
76 : assign-register ( live-interval register -- )
77 swap vreg>> register-allocation get set-at ;
79 : allocate-register ( live-interval -- )
80 dup vreg>> free-registers-for [
83 [ pop assign-register ]
88 : allocate-registers ( live-intervals -- )
90 [ [ expire-old-intervals ] [ allocate-register ] bi ] each ;