factor/unfinished/compiler/cfg/linear-scan/allocation/allocation.factor

91 lines
2.5 KiB
Factor
Raw Normal View History

2008-09-10 23:11:03 -04:00
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: namespaces sequences math math.order kernel assocs
accessors vectors fry
2008-09-11 03:05:22 -04:00
compiler.cfg.linear-scan.live-intervals
2008-09-10 23:11:03 -04:00
compiler.backend ;
2008-09-11 03:05:22 -04:00
IN: compiler.cfg.linear-scan.allocation
2008-09-10 23:11:03 -04:00
! Mapping from vregs to machine registers
SYMBOL: register-allocation
! Mapping from vregs to spill locations
SYMBOL: spill-locations
! Vector of active live intervals, in order of increasing end point
SYMBOL: active-intervals
: add-active ( live-interval -- )
active-intervals get push ;
: delete-active ( live-interval -- )
active-intervals get delete ;
! Mapping from register classes to sequences of machine registers
SYMBOL: free-registers
! Counter of spill locations
SYMBOL: spill-counter
: next-spill-location ( -- n )
spill-counter [ dup 1+ ] change ;
: assign-spill ( live-interval -- )
next-spill-location swap vreg>> spill-locations get set-at ;
: free-registers-for ( vreg -- seq )
reg-class>> free-registers get at ;
: free-register ( vreg -- )
#! Free machine register currently assigned to vreg.
[ register-allocation get at ] [ free-registers-for ] bi push ;
: expire-old-intervals ( live-interval -- )
active-intervals get
swap '[ end>> _ start>> < ] partition
active-intervals set
[ vreg>> free-register ] each ;
: interval-to-spill ( -- live-interval )
#! We spill the interval with the longest remaining range.
active-intervals get unclip-slice [
[ [ end>> ] bi@ > ] most
] reduce ;
: reuse-register ( live-interval to-spill -- )
vreg>> swap vreg>>
register-allocation get
tuck [ at ] [ set-at ] 2bi* ;
: spill-at-interval ( live-interval -- )
interval-to-spill
2dup [ end>> ] bi@ > [
[ reuse-register ]
[ nip assign-spill ]
[ [ add-active ] [ delete-active ] bi* ]
2tri
] [ drop assign-spill ] if ;
: init-allocator ( -- )
H{ } clone register-allocation set
H{ } clone spill-locations set
V{ } clone active-intervals set
machine-registers [ >vector ] assoc-map free-registers set
0 spill-counter set ;
: assign-register ( live-interval register -- )
swap vreg>> register-allocation get set-at ;
: allocate-register ( live-interval -- )
dup vreg>> free-registers-for [
spill-at-interval
] [
[ pop assign-register ]
[ drop add-active ]
2bi
] if-empty ;
: allocate-registers ( live-intervals -- )
init-allocator
[ [ expire-old-intervals ] [ allocate-register ] bi ] each ;