2009-06-04 19:53:02 -04:00
|
|
|
! Copyright (C) 2008, 2009 Slava Pestov.
|
2008-09-10 23:11:03 -04:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2009-06-17 16:27:20 -04:00
|
|
|
USING: accessors assocs heaps kernel namespaces sequences fry math
|
|
|
|
combinators arrays sorting
|
2009-06-11 18:55:14 -04:00
|
|
|
compiler.cfg.linear-scan.allocation.coalescing
|
|
|
|
compiler.cfg.linear-scan.allocation.spilling
|
|
|
|
compiler.cfg.linear-scan.allocation.splitting
|
|
|
|
compiler.cfg.linear-scan.allocation.state ;
|
2008-09-11 03:05:22 -04:00
|
|
|
IN: compiler.cfg.linear-scan.allocation
|
2008-09-10 23:11:03 -04:00
|
|
|
|
2009-06-17 16:27:20 -04:00
|
|
|
: relevant-ranges ( new inactive -- new' inactive' )
|
|
|
|
! Slice off all ranges of 'inactive' that precede the start of 'new'
|
|
|
|
[ [ ranges>> ] bi@ ] [ nip start>> ] 2bi '[ to>> _ >= ] filter ;
|
|
|
|
|
|
|
|
: intersect-live-range ( range1 range2 -- n/f )
|
|
|
|
2dup [ from>> ] bi@ > [ swap ] when
|
|
|
|
2dup [ to>> ] [ from>> ] bi* >= [ nip from>> ] [ 2drop f ] if ;
|
|
|
|
|
|
|
|
: intersect-live-ranges ( ranges1 ranges2 -- n )
|
|
|
|
{
|
|
|
|
{ [ over empty? ] [ 2drop 1/0. ] }
|
|
|
|
{ [ dup empty? ] [ 2drop 1/0. ] }
|
|
|
|
[
|
|
|
|
2dup [ first ] bi@ intersect-live-range dup [ 2nip ] [
|
|
|
|
drop
|
|
|
|
2dup [ first from>> ] bi@ <
|
|
|
|
[ [ rest-slice ] dip ] [ rest-slice ] if
|
|
|
|
intersect-live-ranges
|
|
|
|
] if
|
|
|
|
]
|
|
|
|
} cond ;
|
|
|
|
|
|
|
|
: intersect-inactive ( new inactive -- n )
|
|
|
|
relevant-ranges intersect-live-ranges ;
|
|
|
|
|
|
|
|
: compute-free-pos ( new -- free-pos )
|
|
|
|
dup vreg>>
|
|
|
|
[ nip reg-class>> registers get at [ 1/0. ] H{ } map>assoc ]
|
|
|
|
[ inactive-intervals-for [ [ reg>> swap ] keep intersect-inactive ] with H{ } map>assoc ]
|
|
|
|
[ nip active-intervals-for [ reg>> 0 ] H{ } map>assoc ]
|
|
|
|
2tri 3array assoc-combine
|
|
|
|
>alist sort-values ;
|
|
|
|
|
2009-06-19 04:42:42 -04:00
|
|
|
: no-free-registers? ( result -- ? )
|
2009-06-17 16:27:20 -04:00
|
|
|
second 0 = ; inline
|
|
|
|
|
|
|
|
: register-available? ( new result -- ? )
|
|
|
|
[ end>> ] [ second ] bi* < ; inline
|
|
|
|
|
|
|
|
: register-available ( new result -- )
|
|
|
|
first >>reg add-active ;
|
|
|
|
|
|
|
|
: register-partially-available ( new result -- )
|
|
|
|
[ second split-before-use ] keep
|
|
|
|
'[ _ register-available ] [ add-unhandled ] bi* ;
|
|
|
|
|
2009-06-04 19:53:02 -04:00
|
|
|
: assign-register ( new -- )
|
|
|
|
dup coalesce? [ coalesce ] [
|
2009-06-17 16:27:20 -04:00
|
|
|
dup compute-free-pos last {
|
|
|
|
{ [ dup no-free-registers? ] [ drop assign-blocked-register ] }
|
|
|
|
{ [ 2dup register-available? ] [ register-available ] }
|
|
|
|
[ register-partially-available ]
|
|
|
|
} cond
|
2008-11-02 02:49:57 -05:00
|
|
|
] if ;
|
2008-09-10 23:11:03 -04:00
|
|
|
|
2008-09-15 02:54:48 -04:00
|
|
|
: handle-interval ( live-interval -- )
|
2009-06-04 19:53:02 -04:00
|
|
|
[
|
|
|
|
start>>
|
|
|
|
[ progress set ]
|
|
|
|
[ deactivate-intervals ]
|
|
|
|
[ activate-intervals ] tri
|
|
|
|
] [ assign-register ] bi ;
|
2008-09-15 02:54:48 -04:00
|
|
|
|
|
|
|
: (allocate-registers) ( -- )
|
|
|
|
unhandled-intervals get [ handle-interval ] slurp-heap ;
|
|
|
|
|
2009-06-04 19:53:02 -04:00
|
|
|
: finish-allocation ( -- )
|
|
|
|
active-intervals inactive-intervals
|
|
|
|
[ get values [ handled-intervals get push-all ] each ] bi@ ;
|
|
|
|
|
2008-09-15 05:22:12 -04:00
|
|
|
: allocate-registers ( live-intervals machine-registers -- live-intervals )
|
2008-09-17 20:31:35 -04:00
|
|
|
init-allocator
|
2009-06-04 19:53:02 -04:00
|
|
|
init-unhandled
|
|
|
|
(allocate-registers)
|
|
|
|
finish-allocation
|
|
|
|
handled-intervals get ;
|