1 ! Copyright (C) 2008, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors assocs heaps kernel namespaces sequences fry math
4 math.order combinators arrays sorting compiler.utilities locals
5 compiler.cfg.linear-scan.live-intervals
6 compiler.cfg.linear-scan.allocation.spilling
7 compiler.cfg.linear-scan.allocation.splitting
8 compiler.cfg.linear-scan.allocation.state ;
9 IN: compiler.cfg.linear-scan.allocation
11 : active-positions ( new assoc -- )
12 [ vreg>> active-intervals-for ] dip
13 '[ [ 0 ] dip reg>> _ add-use-position ] each ;
15 : inactive-positions ( new assoc -- )
16 [ [ vreg>> inactive-intervals-for ] keep ] dip
18 [ _ relevant-ranges intersect-live-ranges 1/0. or ] [ reg>> ] bi
22 : register-status ( new -- free-pos )
24 [ inactive-positions ] [ active-positions ] [ nip ] 2tri
27 : no-free-registers? ( result -- ? )
30 : assign-register ( new -- )
32 { [ dup no-free-registers? ] [ drop assign-blocked-register ] }
33 { [ 2dup register-available? ] [ register-available ] }
34 [ drop assign-blocked-register ]
37 : handle-sync-point ( n -- )
38 [ active-intervals get values ] dip
39 [ '[ [ _ spill ] each ] each ]
40 [ drop [ delete-all ] each ]
43 :: handle-progress ( n sync? -- )
46 [ deactivate-intervals ]
47 [ sync? [ handle-sync-point ] [ drop ] if ]
48 [ activate-intervals ]
51 GENERIC: handle ( obj -- )
53 M: live-interval handle ( live-interval -- )
54 [ start>> f handle-progress ] [ assign-register ] bi ;
56 M: sync-point handle ( sync-point -- )
57 n>> t handle-progress ;
59 : smallest-heap ( heap1 heap2 -- heap )
60 ! If heap1 and heap2 have the same key, favors heap1.
61 [ [ heap-peek nip ] bi@ <= ] most ;
63 : (allocate-registers) ( -- )
65 { [ unhandled-intervals get heap-empty? ] [ unhandled-sync-points get ] }
66 { [ unhandled-sync-points get heap-empty? ] [ unhandled-intervals get ] }
67 ! If a live interval begins at the same location as a sync point,
68 ! process the sync point before the live interval. This ensures that the
69 ! return value of C function calls doesn't get spilled and reloaded
71 [ unhandled-sync-points get unhandled-intervals get smallest-heap ]
72 } cond dup heap-empty? [ drop ] [ heap-pop drop handle (allocate-registers) ] if ;
74 : finish-allocation ( -- )
75 active-intervals inactive-intervals
76 [ get values [ handled-intervals get push-all ] each ] bi@ ;
78 : allocate-registers ( live-intervals sync-point machine-registers -- live-intervals )
83 handled-intervals get ;