Count integer and float spills separately, build stack frame after register allocation since spilling requires a stack frame

db4
Slava Pestov 2008-09-17 19:31:35 -05:00
parent 608ba27202
commit 0f2118cf38
10 changed files with 118 additions and 51 deletions

View File

@ -19,6 +19,10 @@ successors ;
V{ } clone >>instructions
V{ } clone >>successors ;
TUPLE: mr instructions word label ;
TUPLE: mr instructions word label frame-size spill-counts ;
C: <mr> mr
: <mr> ( instructions word label -- mr )
mr new
swap >>label
swap >>word
swap >>instructions ;

View File

@ -100,8 +100,8 @@ M: ##if-intrinsic defs-vregs intrinsic-defs-vregs ;
M: ##if-intrinsic uses-vregs intrinsic-uses-vregs ;
! Instructions used by machine IR only.
INSN: _prologue n ;
INSN: _epilogue n ;
INSN: _prologue ;
INSN: _epilogue ;
INSN: _label id ;
@ -117,5 +117,8 @@ M: _cond-branch uses-vregs src>> >vreg 1array ;
M: _if-intrinsic defs-vregs intrinsic-defs-vregs ;
M: _if-intrinsic uses-vregs intrinsic-uses-vregs ;
INSN: _spill src n ;
INSN: _reload dst n ;
INSN: _spill-integer src n ;
INSN: _reload-integer dst n ;
INSN: _spill-float src n ;
INSN: _reload-float dst n ;

View File

@ -2,6 +2,7 @@
! See http://factorcode.org/license.txt for BSD license.
USING: namespaces sequences math math.order kernel assocs
accessors vectors fry heaps
compiler.cfg.registers
compiler.cfg.linear-scan.live-intervals
compiler.backend ;
IN: compiler.cfg.linear-scan.allocation
@ -68,10 +69,10 @@ SYMBOL: progress
[ peek >>reg drop ] [ pop >>reg add-active ] if ;
! Spilling
SYMBOL: spill-counter
SYMBOL: spill-counts
: next-spill-location ( -- n )
spill-counter [ dup 1+ ] change ;
: next-spill-location ( reg-class -- n )
spill-counts get [ dup 1+ ] change-at ;
: interval-to-spill ( -- live-interval )
#! We spill the interval with the most distant use location.
@ -141,7 +142,7 @@ SYMBOL: spill-counter
V{ } clone active-intervals set
<min-heap> unhandled-intervals set
[ reverse >vector ] assoc-map free-registers set
0 spill-counter set
H{ { int-regs 0 } { double-float-regs 0 } } clone spill-counts set
-1 progress set ;
: handle-interval ( live-interval -- )
@ -152,8 +153,6 @@ SYMBOL: spill-counter
: allocate-registers ( live-intervals machine-registers -- live-intervals )
#! This modifies the input live-intervals.
[
init-allocator
dup init-unhandled
(allocate-registers)
] with-scope ;
init-allocator
dup init-unhandled
(allocate-registers) ;

View File

@ -1,7 +1,7 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors kernel math assocs namespaces sequences heaps
fry make
fry make combinators
compiler.cfg.registers
compiler.cfg.instructions
compiler.cfg.linear-scan.live-intervals ;
@ -34,7 +34,13 @@ SYMBOL: unhandled-intervals
[ add-unhandled ] each ;
: insert-spill ( live-interval -- )
[ reg>> ] [ spill-to>> ] bi dup [ _spill ] [ 2drop ] if ;
[ reg>> ] [ spill-to>> ] [ vreg>> reg-class>> ] tri
over [
{
{ int-regs [ _spill-integer ] }
{ double-float-regs [ _spill-float ] }
} case
] [ 3drop ] if ;
: expire-old-intervals ( n -- )
active-intervals get
@ -43,7 +49,13 @@ SYMBOL: unhandled-intervals
[ insert-spill ] each ;
: insert-reload ( live-interval -- )
[ reg>> ] [ reload-from>> ] bi dup [ _reload ] [ 2drop ] if ;
[ reg>> ] [ reload-from>> ] [ vreg>> reg-class>> ] tri
over [
{
{ int-regs [ _reload-integer ] }
{ double-float-regs [ _reload-float ] }
} case
] [ 3drop ] if ;
: activate-new-intervals ( n -- )
#! Any live intervals which start on the current instruction

View File

@ -1,6 +1,6 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: kernel accessors
USING: kernel accessors namespaces
compiler.backend
compiler.cfg
compiler.cfg.linear-scan.live-intervals
@ -24,7 +24,10 @@ IN: compiler.cfg.linear-scan
: linear-scan ( mr -- mr' )
[
dup compute-live-intervals
machine-registers allocate-registers
assign-registers
] change-instructions ;
[
dup compute-live-intervals
machine-registers allocate-registers
assign-registers
] change-instructions
spill-counts get >>spill-counts
] with-scope ;

View File

@ -43,7 +43,6 @@ SYMBOL: live-intervals
: compute-live-intervals ( instructions -- live-intervals )
H{ } clone [
live-intervals [
[ compute-live-intervals* ] each-index
] with-variable
live-intervals set
[ compute-live-intervals* ] each-index
] keep finalize-live-intervals ;

View File

@ -9,13 +9,6 @@ compiler.cfg.instructions.syntax ;
IN: compiler.cfg.linearization
! Convert CFG IR to machine IR.
SYMBOL: frame-size
: compute-frame-size ( rpo -- )
[ instructions>> [ ##frame-required? ] filter ] map concat
[ f ] [ [ n>> ] map supremum ] if-empty
frame-size set ;
GENERIC: linearize-insn ( basic-block insn -- )
: linearize-insns ( basic-block -- )
@ -23,14 +16,6 @@ GENERIC: linearize-insn ( basic-block insn -- )
M: insn linearize-insn , drop ;
M: ##frame-required linearize-insn 2drop ;
M: ##prologue linearize-insn
2drop frame-size get [ _prologue ] when* ;
M: ##epilogue linearize-insn
2drop frame-size get [ _epilogue ] when* ;
: useless-branch? ( basic-block successor -- ? )
#! If our successor immediately follows us in RPO, then we
#! don't need to branch.
@ -78,9 +63,6 @@ M: ##if-intrinsic linearize-insn
[ [ linearize-basic-block ] each ] { } make ;
: build-mr ( cfg -- mr )
[
entry>> reverse-post-order [
[ compute-frame-size ]
[ linearize-basic-blocks ] bi
] with-scope
] [ word>> ] [ label>> ] tri <mr> ;
[ entry>> reverse-post-order linearize-basic-blocks ]
[ word>> ] [ label>> ]
tri <mr> ;

View File

@ -0,0 +1,59 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: namespaces accessors math.order assocs kernel sequences
make compiler.cfg.instructions compiler.cfg.instructions.syntax
compiler.cfg.registers ;
IN: compiler.cfg.stack-frame
SYMBOL: frame-required?
SYMBOL: frame-size
SYMBOL: spill-counts
: init-stack-frame-builder ( -- )
frame-required? off
0 frame-size set ;
GENERIC: compute-frame-size* ( insn -- )
M: ##frame-required compute-frame-size*
frame-required? on
n>> frame-size [ max ] change ;
M: _spill-integer compute-frame-size*
drop frame-required? on ;
M: _spill-float compute-frame-size*
drop frame-required? on ;
M: insn compute-frame-size* drop ;
: compute-frame-size ( insns -- )
[ compute-frame-size* ] each ;
GENERIC: insert-pro/epilogues* ( insn -- )
M: ##frame-required insert-pro/epilogues* drop ;
M: ##prologue insert-pro/epilogues*
drop frame-required? get [ _prologue ] when ;
M: ##epilogue insert-pro/epilogues*
drop frame-required? get [ _epilogue ] when ;
M: insn insert-pro/epilogues* , ;
: insert-pro/epilogues ( insns -- insns )
[ [ insert-pro/epilogues* ] each ] { } make ;
: build-stack-frame ( mr -- mr )
[
init-stack-frame-builder
[
[ compute-frame-size ]
[ insert-pro/epilogues ]
bi
] change-instructions
frame-size get >>frame-size
] with-scope ;

View File

@ -71,10 +71,10 @@ M: _label generate-insn
id>> lookup-label , ;
M: _prologue generate-insn
n>> %prologue ;
drop %prologue ;
M: _epilogue generate-insn
n>> %epilogue ;
drop %epilogue ;
M: ##load-literal generate-insn
[ obj>> ] [ dst>> v>operand ] bi load-literal ;

View File

@ -7,7 +7,7 @@ stack-checker stack-checker.state stack-checker.inlining
compiler.errors compiler.units compiler.tree.builder
compiler.tree.optimizer compiler.cfg.builder
compiler.cfg.linearization compiler.cfg.linear-scan
compiler.codegen ;
compiler.cfg.stack-frame compiler.codegen ;
IN: compiler.new
SYMBOL: compile-queue
@ -79,7 +79,13 @@ SYMBOL: +failed+
bi ;
: backend ( nodes word -- )
build-cfg [ build-mr linear-scan generate save-asm ] each ;
build-cfg [
build-mr
linear-scan
build-stack-frame
generate
save-asm
] each ;
: (compile) ( word -- )
'[