compiler.cfg.linear-scan.allocation.state: more docs and tests for vocab
parent
043b6d5377
commit
4cda101717
|
@ -1,16 +1,38 @@
|
||||||
USING: assocs compiler.cfg compiler.cfg.instructions
|
USING: assocs compiler.cfg compiler.cfg.instructions
|
||||||
compiler.cfg.linear-scan.allocation compiler.cfg.linear-scan.live-intervals
|
compiler.cfg.linear-scan.allocation
|
||||||
cpu.architecture heaps help.markup help.syntax math sequences vectors ;
|
compiler.cfg.linear-scan.allocation.spilling
|
||||||
|
compiler.cfg.linear-scan.live-intervals cpu.architecture heaps help.markup
|
||||||
|
help.syntax math sequences vectors ;
|
||||||
IN: compiler.cfg.linear-scan.allocation.state
|
IN: compiler.cfg.linear-scan.allocation.state
|
||||||
|
|
||||||
|
HELP: activate-intervals
|
||||||
|
{ $values { "n" integer } }
|
||||||
|
{ $description "Any inactive intervals which have ended are moved to handled. Any inactive intervals which do not cover the current position are moved to active." } ;
|
||||||
|
|
||||||
HELP: active-intervals
|
HELP: active-intervals
|
||||||
{ $var-description { $link assoc } " of active live intervals. The keys are register class symbols and the values vectors of " { $link live-interval-state } "." } ;
|
{ $var-description { $link assoc } " of active live intervals. The keys are register class symbols and the values vectors of " { $link live-interval-state } "." } ;
|
||||||
|
|
||||||
|
HELP: add-active
|
||||||
|
{ $values { "live-interval" live-interval-state } }
|
||||||
|
{ $description "Adds a live interval to the " { $link active-intervals } " assoc." } ;
|
||||||
|
|
||||||
|
HELP: align-spill-area
|
||||||
|
{ $values { "align" integer } }
|
||||||
|
{ $description "This word is used to ensure that the alignment of the spill area in the " { $link cfg } " is equal to the largest " { $link spill-slot } "." } ;
|
||||||
|
|
||||||
|
HELP: deactivate-intervals
|
||||||
|
{ $values { "n" integer } }
|
||||||
|
{ $description "Any active intervals which have ended are moved to handled. Any active intervals which cover the current position are moved to inactive." } ;
|
||||||
|
|
||||||
|
HELP: free-positions
|
||||||
|
{ $values { "new" live-interval-state } { "assoc" assoc } }
|
||||||
|
{ $description "A utility used by " { $link register-status } " and " { $link spill-status } " words." } ;
|
||||||
|
|
||||||
HELP: handled-intervals
|
HELP: handled-intervals
|
||||||
{ $var-description { $link vector } " of handled live intervals." } ;
|
{ $var-description { $link vector } " of handled live intervals." } ;
|
||||||
|
|
||||||
HELP: unhandled-min-heap
|
HELP: inactive-intervals
|
||||||
{ $var-description { $link min-heap } " of all live intervals and sync points which still needs processing. It is used by " { $link (allocate-registers) } ". The key of the heap is a pair of values, " { $slot "start" } " and " { $slot "end" } " for the " { $link live-interval-state } " tuple and " { $slot "n" } " and 1/0.0 for the " { $link sync-point } " tuple. That way smaller live intervals are always processed before larger ones and all live intervals before sync points." } ;
|
{ $var-description { $link vector } " of inactive live intervals." } ;
|
||||||
|
|
||||||
HELP: init-allocator
|
HELP: init-allocator
|
||||||
{ $values
|
{ $values
|
||||||
|
@ -25,9 +47,15 @@ HELP: next-spill-slot
|
||||||
{ $values { "size" "number of bytes required" } { "spill-slot" spill-slot } }
|
{ $values { "size" "number of bytes required" } { "spill-slot" spill-slot } }
|
||||||
{ $description "Creates a new " { $link spill-slot } " of the given size and also allocates space in the " { $link cfg } " in the 'cfg' dynamic variable for it." } ;
|
{ $description "Creates a new " { $link spill-slot } " of the given size and also allocates space in the " { $link cfg } " in the 'cfg' dynamic variable for it." } ;
|
||||||
|
|
||||||
|
HELP: progress
|
||||||
|
{ $var-description "Start index of current live interval. We ensure that all live intervals added to the unhandled set have a start index strictly greater than this one. This ensures that we can catch infinite loop situations. We also ensure that all live intervals added to the handled set have an end index strictly smaller than this one. This helps catch bugs." }
|
||||||
|
{ $see-also check-handled check-unhandled } ;
|
||||||
|
|
||||||
|
HELP: registers
|
||||||
|
{ $var-description "Mapping from register classes to sequences of machine registers." } ;
|
||||||
|
|
||||||
HELP: spill-slots
|
HELP: spill-slots
|
||||||
{ $var-description "Mapping from vregs to spill slots." } ;
|
{ $var-description "Mapping from vregs to spill slots." } ;
|
||||||
|
|
||||||
HELP: align-spill-area
|
HELP: unhandled-min-heap
|
||||||
{ $values { "align" integer } }
|
{ $var-description { $link min-heap } " of all live intervals and sync points which still needs processing. It is used by " { $link (allocate-registers) } ". The key of the heap is a pair of values, " { $slot "start" } " and " { $slot "end" } " for the " { $link live-interval-state } " tuple and " { $slot "n" } " and 1/0.0 for the " { $link sync-point } " tuple. That way smaller live intervals are always processed before larger ones and all live intervals before sync points." } ;
|
||||||
{ $description "This word is used to ensure that the alignment of the spill area in the " { $link cfg } " is equal to the largest " { $link spill-slot } "." } ;
|
|
||||||
|
|
|
@ -1,8 +1,52 @@
|
||||||
USING: combinators.extras compiler.cfg compiler.cfg.instructions
|
USING: combinators.extras compiler.cfg compiler.cfg.instructions
|
||||||
compiler.cfg.linear-scan.allocation.state
|
compiler.cfg.linear-scan.allocation.state
|
||||||
compiler.cfg.linear-scan.live-intervals heaps kernel namespaces tools.test ;
|
compiler.cfg.linear-scan.live-intervals cpu.architecture
|
||||||
|
cpu.x86.assembler.operands heaps kernel namespaces system tools.test ;
|
||||||
IN: compiler.cfg.linear-scan.allocation.state.tests
|
IN: compiler.cfg.linear-scan.allocation.state.tests
|
||||||
|
|
||||||
|
! add-active
|
||||||
|
{
|
||||||
|
{
|
||||||
|
{
|
||||||
|
int-regs
|
||||||
|
V{
|
||||||
|
T{ live-interval-state
|
||||||
|
{ vreg 123 }
|
||||||
|
{ reg-class int-regs }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{ float-regs V{ } }
|
||||||
|
}
|
||||||
|
} [
|
||||||
|
f f machine-registers init-allocator
|
||||||
|
T{ live-interval-state { reg-class int-regs } { vreg 123 } } add-active
|
||||||
|
active-intervals get
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
! free-positions
|
||||||
|
cpu x86.64? [
|
||||||
|
{
|
||||||
|
H{
|
||||||
|
{ RCX 1/0. }
|
||||||
|
{ RBX 1/0. }
|
||||||
|
{ RAX 1/0. }
|
||||||
|
{ R12 1/0. }
|
||||||
|
{ RDI 1/0. }
|
||||||
|
{ R10 1/0. }
|
||||||
|
{ RSI 1/0. }
|
||||||
|
{ R11 1/0. }
|
||||||
|
{ R8 1/0. }
|
||||||
|
{ R9 1/0. }
|
||||||
|
{ RDX 1/0. }
|
||||||
|
{ RBP 1/0. }
|
||||||
|
}
|
||||||
|
} [
|
||||||
|
f f machine-registers init-allocator
|
||||||
|
T{ live-interval-state { reg-class int-regs } } free-positions
|
||||||
|
] unit-test
|
||||||
|
] when
|
||||||
|
|
||||||
{
|
{
|
||||||
T{ spill-slot f 0 }
|
T{ spill-slot f 0 }
|
||||||
T{ spill-slot f 8 }
|
T{ spill-slot f 8 }
|
||||||
|
|
|
@ -8,12 +8,6 @@ math.order namespaces sequences ;
|
||||||
FROM: assocs => change-at ;
|
FROM: assocs => change-at ;
|
||||||
IN: compiler.cfg.linear-scan.allocation.state
|
IN: compiler.cfg.linear-scan.allocation.state
|
||||||
|
|
||||||
! Start index of current live interval. We ensure that all
|
|
||||||
! live intervals added to the unhandled set have a start index
|
|
||||||
! strictly greater than this one. This ensures that we can catch
|
|
||||||
! infinite loop situations. We also ensure that all live
|
|
||||||
! intervals added to the handled set have an end index strictly
|
|
||||||
! smaller than this one. This helps catch bugs.
|
|
||||||
SYMBOL: progress
|
SYMBOL: progress
|
||||||
|
|
||||||
: check-unhandled ( live-interval -- )
|
: check-unhandled ( live-interval -- )
|
||||||
|
@ -37,7 +31,6 @@ SYMBOL: unhandled-min-heap
|
||||||
[ [ live-interval-key ] zip-keyed ]
|
[ [ live-interval-key ] zip-keyed ]
|
||||||
[ [ sync-point-key ] zip-keyed ] bi* append >min-heap ;
|
[ [ sync-point-key ] zip-keyed ] bi* append >min-heap ;
|
||||||
|
|
||||||
! Mapping from register classes to sequences of machine registers
|
|
||||||
SYMBOL: registers
|
SYMBOL: registers
|
||||||
|
|
||||||
SYMBOL: active-intervals
|
SYMBOL: active-intervals
|
||||||
|
@ -54,7 +47,6 @@ SYMBOL: active-intervals
|
||||||
: assign-free-register ( new registers -- )
|
: assign-free-register ( new registers -- )
|
||||||
pop >>reg add-active ;
|
pop >>reg add-active ;
|
||||||
|
|
||||||
! Vector of inactive live intervals
|
|
||||||
SYMBOL: inactive-intervals
|
SYMBOL: inactive-intervals
|
||||||
|
|
||||||
: inactive-intervals-for ( live-interval -- seq )
|
: inactive-intervals-for ( live-interval -- seq )
|
||||||
|
@ -101,9 +93,6 @@ ERROR: register-already-used live-interval ;
|
||||||
[ get values ] dip '[ [ _ cond ] with filter! drop ] with each ; inline
|
[ get values ] dip '[ [ _ cond ] with filter! drop ] with each ; inline
|
||||||
|
|
||||||
: deactivate-intervals ( n -- )
|
: deactivate-intervals ( n -- )
|
||||||
! Any active intervals which have ended are moved to handled
|
|
||||||
! Any active intervals which cover the current position
|
|
||||||
! are moved to inactive
|
|
||||||
dup progress set
|
dup progress set
|
||||||
active-intervals {
|
active-intervals {
|
||||||
{ [ 2dup finished? ] [ finish ] }
|
{ [ 2dup finished? ] [ finish ] }
|
||||||
|
@ -112,9 +101,6 @@ ERROR: register-already-used live-interval ;
|
||||||
} process-intervals ;
|
} process-intervals ;
|
||||||
|
|
||||||
: activate-intervals ( n -- )
|
: activate-intervals ( n -- )
|
||||||
! Any inactive intervals which have ended are moved to handled
|
|
||||||
! Any inactive intervals which do not cover the current position
|
|
||||||
! are moved to active
|
|
||||||
inactive-intervals {
|
inactive-intervals {
|
||||||
{ [ 2dup finished? ] [ finish ] }
|
{ [ 2dup finished? ] [ finish ] }
|
||||||
{ [ 2dup covers? ] [ activate ] }
|
{ [ 2dup covers? ] [ activate ] }
|
||||||
|
@ -159,8 +145,6 @@ SYMBOL: spill-slots
|
||||||
H{ } clone spill-slots set
|
H{ } clone spill-slots set
|
||||||
-1 progress set ;
|
-1 progress set ;
|
||||||
|
|
||||||
|
|
||||||
! A utility used by register-status and spill-status words
|
|
||||||
: free-positions ( new -- assoc )
|
: free-positions ( new -- assoc )
|
||||||
reg-class>> registers get at
|
reg-class>> registers get at
|
||||||
[ 1/0. ] H{ } <linked-assoc> map>assoc ;
|
[ 1/0. ] H{ } <linked-assoc> map>assoc ;
|
||||||
|
|
Loading…
Reference in New Issue