2009-06-11 18:55:14 -04:00
|
|
|
! Copyright (C) 2009 Slava Pestov.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
|
|
USING: accessors arrays assocs combinators fry hints kernel locals
|
2009-07-07 04:28:55 -04:00
|
|
|
math sequences sets sorting splitting namespaces
|
|
|
|
combinators.short-circuit compiler.utilities
|
2009-06-11 18:55:14 -04:00
|
|
|
compiler.cfg.linear-scan.allocation.state
|
|
|
|
compiler.cfg.linear-scan.allocation.splitting
|
|
|
|
compiler.cfg.linear-scan.live-intervals ;
|
|
|
|
IN: compiler.cfg.linear-scan.allocation.spilling
|
|
|
|
|
2009-07-01 18:41:07 -04:00
|
|
|
ERROR: bad-live-ranges interval ;
|
|
|
|
|
|
|
|
: check-ranges ( live-interval -- )
|
|
|
|
check-allocation? get [
|
|
|
|
dup ranges>> [ [ from>> ] [ to>> ] bi <= ] all?
|
|
|
|
[ drop ] [ bad-live-ranges ] if
|
|
|
|
] [ drop ] if ;
|
|
|
|
|
2009-07-01 23:37:27 -04:00
|
|
|
: trim-before-ranges ( live-interval -- )
|
2009-07-01 18:41:07 -04:00
|
|
|
[ ranges>> ] [ uses>> last ] bi
|
|
|
|
[ '[ from>> _ <= ] filter-here ]
|
|
|
|
[ swap last (>>to) ]
|
|
|
|
2bi ;
|
|
|
|
|
2009-07-01 23:37:27 -04:00
|
|
|
: trim-after-ranges ( live-interval -- )
|
2009-07-01 18:41:07 -04:00
|
|
|
[ ranges>> ] [ uses>> first ] bi
|
|
|
|
[ '[ to>> _ >= ] filter-here ]
|
|
|
|
[ swap first (>>from) ]
|
|
|
|
2bi ;
|
|
|
|
|
2009-06-11 18:55:14 -04:00
|
|
|
: split-for-spill ( live-interval n -- before after )
|
|
|
|
split-interval
|
2009-07-01 18:41:07 -04:00
|
|
|
{
|
|
|
|
[ [ trim-before-ranges ] [ trim-after-ranges ] bi* ]
|
|
|
|
[ [ compute-start/end ] bi@ ]
|
|
|
|
[ [ check-ranges ] bi@ ]
|
|
|
|
[ ]
|
|
|
|
} 2cleave ;
|
|
|
|
|
2009-07-07 04:28:55 -04:00
|
|
|
: assign-spill ( live-interval -- )
|
2009-07-09 00:07:06 -04:00
|
|
|
dup vreg>> assign-spill-slot >>spill-to f >>split-next drop ;
|
2009-07-01 18:41:07 -04:00
|
|
|
|
2009-07-07 04:28:55 -04:00
|
|
|
: assign-reload ( live-interval -- )
|
|
|
|
dup vreg>> assign-spill-slot >>reload-from drop ;
|
2009-06-11 18:55:14 -04:00
|
|
|
|
2009-07-07 04:28:55 -04:00
|
|
|
: split-and-spill ( live-interval n -- before after )
|
2009-07-07 04:45:27 -04:00
|
|
|
split-for-spill 2dup [ assign-spill ] [ assign-reload ] bi* ;
|
2009-07-01 18:41:07 -04:00
|
|
|
|
2009-07-07 04:28:55 -04:00
|
|
|
: find-use-position ( live-interval new -- n )
|
|
|
|
[ uses>> ] [ start>> '[ _ >= ] ] bi* find nip 1/0. or ;
|
2009-07-01 18:41:07 -04:00
|
|
|
|
2009-07-07 04:28:55 -04:00
|
|
|
: find-use-positions ( live-intervals new assoc -- )
|
|
|
|
'[ [ _ find-use-position ] [ reg>> ] bi _ add-use-position ] each ;
|
2009-06-11 18:55:14 -04:00
|
|
|
|
2009-07-07 04:28:55 -04:00
|
|
|
: active-positions ( new assoc -- )
|
|
|
|
[ [ vreg>> active-intervals-for ] keep ] dip
|
|
|
|
find-use-positions ;
|
2009-07-01 18:41:07 -04:00
|
|
|
|
2009-07-07 04:28:55 -04:00
|
|
|
: inactive-positions ( new assoc -- )
|
|
|
|
[
|
|
|
|
[ vreg>> inactive-intervals-for ] keep
|
|
|
|
[ '[ _ intervals-intersect? ] filter ] keep
|
|
|
|
] dip
|
|
|
|
find-use-positions ;
|
2009-07-01 18:41:07 -04:00
|
|
|
|
2009-07-07 04:28:55 -04:00
|
|
|
: spill-status ( new -- use-pos )
|
|
|
|
H{ } clone
|
|
|
|
[ inactive-positions ] [ active-positions ] [ nip ] 2tri
|
|
|
|
>alist alist-max ;
|
2009-06-11 18:55:14 -04:00
|
|
|
|
2009-07-07 04:28:55 -04:00
|
|
|
: spill-new? ( new pair -- ? )
|
|
|
|
[ uses>> first ] [ second ] bi* > ;
|
2009-06-11 18:55:14 -04:00
|
|
|
|
2009-07-07 04:28:55 -04:00
|
|
|
: spill-new ( new pair -- )
|
2009-07-07 14:01:27 -04:00
|
|
|
drop
|
|
|
|
{
|
|
|
|
[ trim-after-ranges ]
|
|
|
|
[ compute-start/end ]
|
|
|
|
[ assign-reload ]
|
|
|
|
[ add-unhandled ]
|
|
|
|
} cleave ;
|
2009-07-07 04:28:55 -04:00
|
|
|
|
|
|
|
: split-intersecting? ( live-interval new reg -- ? )
|
|
|
|
{ [ [ drop reg>> ] dip = ] [ drop intervals-intersect? ] } 3&& ;
|
|
|
|
|
|
|
|
: split-live-out ( live-interval -- )
|
|
|
|
{
|
|
|
|
[ trim-before-ranges ]
|
|
|
|
[ compute-start/end ]
|
|
|
|
[ assign-spill ]
|
|
|
|
[ add-handled ]
|
|
|
|
} cleave ;
|
|
|
|
|
|
|
|
: split-live-in ( live-interval -- )
|
|
|
|
{
|
|
|
|
[ trim-after-ranges ]
|
|
|
|
[ compute-start/end ]
|
2009-07-07 04:45:27 -04:00
|
|
|
[ assign-reload ]
|
2009-07-07 14:01:27 -04:00
|
|
|
[ add-unhandled ]
|
2009-07-07 04:28:55 -04:00
|
|
|
} cleave ;
|
|
|
|
|
|
|
|
: (split-intersecting) ( live-interval new -- )
|
|
|
|
start>> {
|
|
|
|
{ [ 2dup [ uses>> last ] dip < ] [ drop split-live-out ] }
|
|
|
|
{ [ 2dup [ uses>> first ] dip > ] [ drop split-live-in ] }
|
|
|
|
[ split-and-spill [ add-handled ] [ add-unhandled ] bi* ]
|
2009-07-01 18:41:07 -04:00
|
|
|
} cond ;
|
2009-06-11 18:55:14 -04:00
|
|
|
|
2009-07-07 04:28:55 -04:00
|
|
|
: (split-intersecting-active) ( active new -- )
|
|
|
|
[ drop delete-active ]
|
|
|
|
[ (split-intersecting) ] 2bi ;
|
|
|
|
|
|
|
|
: split-intersecting-active ( new reg -- )
|
|
|
|
[ [ vreg>> active-intervals-for ] keep ] dip
|
|
|
|
[ '[ _ _ split-intersecting? ] filter ] 2keep drop
|
|
|
|
'[ _ (split-intersecting-active) ] each ;
|
|
|
|
|
|
|
|
: (split-intersecting-inactive) ( inactive new -- )
|
|
|
|
[ drop delete-inactive ]
|
|
|
|
[ (split-intersecting) ] 2bi ;
|
|
|
|
|
|
|
|
: split-intersecting-inactive ( new reg -- )
|
|
|
|
[ [ vreg>> inactive-intervals-for ] keep ] dip
|
|
|
|
[ '[ _ _ split-intersecting? ] filter ] 2keep drop
|
|
|
|
'[ _ (split-intersecting-inactive) ] each ;
|
|
|
|
|
|
|
|
: split-intersecting ( new reg -- )
|
|
|
|
[ split-intersecting-active ]
|
|
|
|
[ split-intersecting-inactive ]
|
|
|
|
2bi ;
|
|
|
|
|
|
|
|
: spill-available ( new pair -- )
|
|
|
|
[ first split-intersecting ] [ register-available ] 2bi ;
|
|
|
|
|
|
|
|
: spill-partially-available ( new pair -- )
|
|
|
|
[ second 1 - split-and-spill add-unhandled ] keep
|
|
|
|
spill-available ;
|
|
|
|
|
|
|
|
: assign-blocked-register ( new -- )
|
|
|
|
dup spill-status {
|
|
|
|
{ [ 2dup spill-new? ] [ spill-new ] }
|
|
|
|
{ [ 2dup register-available? ] [ spill-available ] }
|
|
|
|
[ spill-partially-available ]
|
|
|
|
} cond ;
|