2010-04-26 00:53:00 -04:00
|
|
|
! Copyright (C) 2008, 2010 Slava Pestov.
|
2008-09-10 23:11:03 -04:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2010-05-11 19:11:31 -04:00
|
|
|
USING: accessors assocs binary-search combinators
|
|
|
|
combinators.short-circuit heaps kernel namespaces
|
|
|
|
sequences fry locals math math.order arrays sorting
|
|
|
|
compiler.utilities
|
2009-06-23 22:32:51 -04:00
|
|
|
compiler.cfg.linear-scan.live-intervals
|
2009-06-11 18:55:14 -04:00
|
|
|
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-30 17:07:58 -04:00
|
|
|
: active-positions ( new assoc -- )
|
2010-04-28 03:35:46 -04:00
|
|
|
[ active-intervals-for ] dip
|
2009-06-30 17:07:58 -04:00
|
|
|
'[ [ 0 ] dip reg>> _ add-use-position ] each ;
|
|
|
|
|
|
|
|
: inactive-positions ( new assoc -- )
|
2010-04-28 03:35:46 -04:00
|
|
|
[ [ inactive-intervals-for ] keep ] dip
|
2009-06-30 17:07:58 -04:00
|
|
|
'[
|
2009-07-07 04:28:55 -04:00
|
|
|
[ _ relevant-ranges intersect-live-ranges 1/0. or ] [ reg>> ] bi
|
2009-06-30 17:07:58 -04:00
|
|
|
_ add-use-position
|
|
|
|
] each ;
|
2009-06-17 16:27:20 -04:00
|
|
|
|
2009-07-01 18:41:07 -04:00
|
|
|
: register-status ( new -- free-pos )
|
2009-06-30 17:07:58 -04:00
|
|
|
dup free-positions
|
|
|
|
[ inactive-positions ] [ active-positions ] [ nip ] 2tri
|
|
|
|
>alist alist-max ;
|
2009-06-17 16:27:20 -04:00
|
|
|
|
2009-06-19 04:42:42 -04:00
|
|
|
: no-free-registers? ( result -- ? )
|
2009-06-17 16:27:20 -04:00
|
|
|
second 0 = ; inline
|
|
|
|
|
2009-06-04 19:53:02 -04:00
|
|
|
: assign-register ( new -- )
|
2009-08-05 19:57:46 -04:00
|
|
|
dup register-status {
|
|
|
|
{ [ dup no-free-registers? ] [ drop assign-blocked-register ] }
|
|
|
|
{ [ 2dup register-available? ] [ register-available ] }
|
|
|
|
[ drop assign-blocked-register ]
|
|
|
|
} cond ;
|
2008-09-10 23:11:03 -04:00
|
|
|
|
2010-05-16 03:43:02 -04:00
|
|
|
: spill-at-sync-point? ( sync-point live-interval -- ? )
|
|
|
|
! If the live interval has a definition at a keep-dst?
|
|
|
|
! sync-point, don't spill.
|
|
|
|
{
|
|
|
|
[ drop keep-dst?>> not ]
|
|
|
|
[ [ n>> ] dip find-use dup [ def-rep>> ] when not ]
|
|
|
|
} 2|| ;
|
|
|
|
|
|
|
|
: spill-at-sync-point ( sync-point live-interval -- ? )
|
|
|
|
2dup spill-at-sync-point?
|
|
|
|
[ swap n>> spill f ] [ 2drop t ] if ;
|
|
|
|
|
2010-07-13 07:40:14 -04:00
|
|
|
: handle-interval ( live-interval -- )
|
|
|
|
[ start>> deactivate-intervals ]
|
|
|
|
[ start>> activate-intervals ]
|
|
|
|
[ assign-register ]
|
|
|
|
tri ;
|
2010-05-16 03:43:02 -04:00
|
|
|
|
2010-07-13 07:40:14 -04:00
|
|
|
: (handle-sync-point) ( sync-point -- )
|
2010-05-11 19:11:31 -04:00
|
|
|
active-intervals get values
|
|
|
|
[ [ spill-at-sync-point ] with filter! drop ] with each ;
|
2009-08-30 05:52:01 -04:00
|
|
|
|
2010-07-13 07:40:14 -04:00
|
|
|
: handle-sync-point ( sync-point -- )
|
|
|
|
[ n>> deactivate-intervals ]
|
|
|
|
[ (handle-sync-point) ]
|
|
|
|
[ n>> activate-intervals ]
|
|
|
|
tri ;
|
2009-08-30 05:52:01 -04:00
|
|
|
|
2010-07-13 07:40:14 -04:00
|
|
|
:: (allocate-registers-step) ( unhandled-intervals unhandled-sync-points -- )
|
2010-04-27 10:51:00 -04:00
|
|
|
{
|
2010-07-13 07:40:14 -04:00
|
|
|
{
|
|
|
|
[ unhandled-intervals heap-empty? ]
|
|
|
|
[ unhandled-sync-points heap-pop drop handle-sync-point ]
|
|
|
|
}
|
|
|
|
{
|
|
|
|
[ unhandled-sync-points heap-empty? ]
|
|
|
|
[ unhandled-intervals heap-pop drop handle-interval ]
|
|
|
|
}
|
|
|
|
[
|
|
|
|
unhandled-intervals heap-peek :> ( i ik )
|
|
|
|
unhandled-sync-points heap-peek :> ( s sk )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
[ ik sk < ]
|
|
|
|
[ unhandled-intervals heap-pop* i handle-interval ]
|
|
|
|
}
|
|
|
|
{
|
|
|
|
[ ik sk > ]
|
|
|
|
[ unhandled-sync-points heap-pop* s handle-sync-point ]
|
|
|
|
}
|
|
|
|
[
|
|
|
|
unhandled-intervals heap-pop*
|
|
|
|
i handle-interval
|
|
|
|
s (handle-sync-point)
|
|
|
|
]
|
|
|
|
} cond
|
|
|
|
]
|
2010-04-27 10:51:00 -04:00
|
|
|
} cond ;
|
2008-09-15 02:54:48 -04:00
|
|
|
|
2010-07-13 07:40:14 -04:00
|
|
|
: (allocate-registers) ( unhandled-intervals unhandled-sync-points -- )
|
|
|
|
2dup [ heap-empty? ] both? [ 2drop ] [
|
|
|
|
[ (allocate-registers-step) ]
|
|
|
|
[ (allocate-registers) ]
|
|
|
|
2bi
|
|
|
|
] if ;
|
2008-09-15 02:54:48 -04:00
|
|
|
|
2009-06-04 19:53:02 -04:00
|
|
|
: finish-allocation ( -- )
|
|
|
|
active-intervals inactive-intervals
|
|
|
|
[ get values [ handled-intervals get push-all ] each ] bi@ ;
|
|
|
|
|
2009-08-30 05:52:01 -04:00
|
|
|
: allocate-registers ( live-intervals sync-point machine-registers -- live-intervals )
|
2008-09-17 20:31:35 -04:00
|
|
|
init-allocator
|
2009-06-04 19:53:02 -04:00
|
|
|
init-unhandled
|
2010-07-13 07:40:14 -04:00
|
|
|
unhandled-intervals get unhandled-sync-points get (allocate-registers)
|
2009-06-04 19:53:02 -04:00
|
|
|
finish-allocation
|
|
|
|
handled-intervals get ;
|