Count integer and float spills separately, build stack frame after register allocation since spilling requires a stack frame
parent
608ba27202
commit
0f2118cf38
|
@ -19,6 +19,10 @@ successors ;
|
||||||
V{ } clone >>instructions
|
V{ } clone >>instructions
|
||||||
V{ } clone >>successors ;
|
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 ;
|
||||||
|
|
|
@ -100,8 +100,8 @@ M: ##if-intrinsic defs-vregs intrinsic-defs-vregs ;
|
||||||
M: ##if-intrinsic uses-vregs intrinsic-uses-vregs ;
|
M: ##if-intrinsic uses-vregs intrinsic-uses-vregs ;
|
||||||
|
|
||||||
! Instructions used by machine IR only.
|
! Instructions used by machine IR only.
|
||||||
INSN: _prologue n ;
|
INSN: _prologue ;
|
||||||
INSN: _epilogue n ;
|
INSN: _epilogue ;
|
||||||
|
|
||||||
INSN: _label id ;
|
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 defs-vregs intrinsic-defs-vregs ;
|
||||||
M: _if-intrinsic uses-vregs intrinsic-uses-vregs ;
|
M: _if-intrinsic uses-vregs intrinsic-uses-vregs ;
|
||||||
|
|
||||||
INSN: _spill src n ;
|
INSN: _spill-integer src n ;
|
||||||
INSN: _reload dst n ;
|
INSN: _reload-integer dst n ;
|
||||||
|
|
||||||
|
INSN: _spill-float src n ;
|
||||||
|
INSN: _reload-float dst n ;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: namespaces sequences math math.order kernel assocs
|
USING: namespaces sequences math math.order kernel assocs
|
||||||
accessors vectors fry heaps
|
accessors vectors fry heaps
|
||||||
|
compiler.cfg.registers
|
||||||
compiler.cfg.linear-scan.live-intervals
|
compiler.cfg.linear-scan.live-intervals
|
||||||
compiler.backend ;
|
compiler.backend ;
|
||||||
IN: compiler.cfg.linear-scan.allocation
|
IN: compiler.cfg.linear-scan.allocation
|
||||||
|
@ -68,10 +69,10 @@ SYMBOL: progress
|
||||||
[ peek >>reg drop ] [ pop >>reg add-active ] if ;
|
[ peek >>reg drop ] [ pop >>reg add-active ] if ;
|
||||||
|
|
||||||
! Spilling
|
! Spilling
|
||||||
SYMBOL: spill-counter
|
SYMBOL: spill-counts
|
||||||
|
|
||||||
: next-spill-location ( -- n )
|
: next-spill-location ( reg-class -- n )
|
||||||
spill-counter [ dup 1+ ] change ;
|
spill-counts get [ dup 1+ ] change-at ;
|
||||||
|
|
||||||
: interval-to-spill ( -- live-interval )
|
: interval-to-spill ( -- live-interval )
|
||||||
#! We spill the interval with the most distant use location.
|
#! We spill the interval with the most distant use location.
|
||||||
|
@ -141,7 +142,7 @@ SYMBOL: spill-counter
|
||||||
V{ } clone active-intervals set
|
V{ } clone active-intervals set
|
||||||
<min-heap> unhandled-intervals set
|
<min-heap> unhandled-intervals set
|
||||||
[ reverse >vector ] assoc-map free-registers 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 ;
|
-1 progress set ;
|
||||||
|
|
||||||
: handle-interval ( live-interval -- )
|
: handle-interval ( live-interval -- )
|
||||||
|
@ -152,8 +153,6 @@ SYMBOL: spill-counter
|
||||||
|
|
||||||
: allocate-registers ( live-intervals machine-registers -- live-intervals )
|
: allocate-registers ( live-intervals machine-registers -- live-intervals )
|
||||||
#! This modifies the input live-intervals.
|
#! This modifies the input live-intervals.
|
||||||
[
|
init-allocator
|
||||||
init-allocator
|
dup init-unhandled
|
||||||
dup init-unhandled
|
(allocate-registers) ;
|
||||||
(allocate-registers)
|
|
||||||
] with-scope ;
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
! Copyright (C) 2008 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors kernel math assocs namespaces sequences heaps
|
USING: accessors kernel math assocs namespaces sequences heaps
|
||||||
fry make
|
fry make combinators
|
||||||
compiler.cfg.registers
|
compiler.cfg.registers
|
||||||
compiler.cfg.instructions
|
compiler.cfg.instructions
|
||||||
compiler.cfg.linear-scan.live-intervals ;
|
compiler.cfg.linear-scan.live-intervals ;
|
||||||
|
@ -34,7 +34,13 @@ SYMBOL: unhandled-intervals
|
||||||
[ add-unhandled ] each ;
|
[ add-unhandled ] each ;
|
||||||
|
|
||||||
: insert-spill ( live-interval -- )
|
: 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 -- )
|
: expire-old-intervals ( n -- )
|
||||||
active-intervals get
|
active-intervals get
|
||||||
|
@ -43,7 +49,13 @@ SYMBOL: unhandled-intervals
|
||||||
[ insert-spill ] each ;
|
[ insert-spill ] each ;
|
||||||
|
|
||||||
: insert-reload ( live-interval -- )
|
: 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 -- )
|
: activate-new-intervals ( n -- )
|
||||||
#! Any live intervals which start on the current instruction
|
#! Any live intervals which start on the current instruction
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
! Copyright (C) 2008 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: kernel accessors
|
USING: kernel accessors namespaces
|
||||||
compiler.backend
|
compiler.backend
|
||||||
compiler.cfg
|
compiler.cfg
|
||||||
compiler.cfg.linear-scan.live-intervals
|
compiler.cfg.linear-scan.live-intervals
|
||||||
|
@ -24,7 +24,10 @@ IN: compiler.cfg.linear-scan
|
||||||
|
|
||||||
: linear-scan ( mr -- mr' )
|
: linear-scan ( mr -- mr' )
|
||||||
[
|
[
|
||||||
dup compute-live-intervals
|
[
|
||||||
machine-registers allocate-registers
|
dup compute-live-intervals
|
||||||
assign-registers
|
machine-registers allocate-registers
|
||||||
] change-instructions ;
|
assign-registers
|
||||||
|
] change-instructions
|
||||||
|
spill-counts get >>spill-counts
|
||||||
|
] with-scope ;
|
||||||
|
|
|
@ -43,7 +43,6 @@ SYMBOL: live-intervals
|
||||||
|
|
||||||
: compute-live-intervals ( instructions -- live-intervals )
|
: compute-live-intervals ( instructions -- live-intervals )
|
||||||
H{ } clone [
|
H{ } clone [
|
||||||
live-intervals [
|
live-intervals set
|
||||||
[ compute-live-intervals* ] each-index
|
[ compute-live-intervals* ] each-index
|
||||||
] with-variable
|
|
||||||
] keep finalize-live-intervals ;
|
] keep finalize-live-intervals ;
|
||||||
|
|
|
@ -9,13 +9,6 @@ compiler.cfg.instructions.syntax ;
|
||||||
IN: compiler.cfg.linearization
|
IN: compiler.cfg.linearization
|
||||||
|
|
||||||
! Convert CFG IR to machine IR.
|
! 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 -- )
|
GENERIC: linearize-insn ( basic-block insn -- )
|
||||||
|
|
||||||
: linearize-insns ( basic-block -- )
|
: linearize-insns ( basic-block -- )
|
||||||
|
@ -23,14 +16,6 @@ GENERIC: linearize-insn ( basic-block insn -- )
|
||||||
|
|
||||||
M: insn linearize-insn , drop ;
|
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 -- ? )
|
: useless-branch? ( basic-block successor -- ? )
|
||||||
#! If our successor immediately follows us in RPO, then we
|
#! If our successor immediately follows us in RPO, then we
|
||||||
#! don't need to branch.
|
#! don't need to branch.
|
||||||
|
@ -78,9 +63,6 @@ M: ##if-intrinsic linearize-insn
|
||||||
[ [ linearize-basic-block ] each ] { } make ;
|
[ [ linearize-basic-block ] each ] { } make ;
|
||||||
|
|
||||||
: build-mr ( cfg -- mr )
|
: build-mr ( cfg -- mr )
|
||||||
[
|
[ entry>> reverse-post-order linearize-basic-blocks ]
|
||||||
entry>> reverse-post-order [
|
[ word>> ] [ label>> ]
|
||||||
[ compute-frame-size ]
|
tri <mr> ;
|
||||||
[ linearize-basic-blocks ] bi
|
|
||||||
] with-scope
|
|
||||||
] [ word>> ] [ label>> ] tri <mr> ;
|
|
||||||
|
|
|
@ -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 ;
|
|
@ -71,10 +71,10 @@ M: _label generate-insn
|
||||||
id>> lookup-label , ;
|
id>> lookup-label , ;
|
||||||
|
|
||||||
M: _prologue generate-insn
|
M: _prologue generate-insn
|
||||||
n>> %prologue ;
|
drop %prologue ;
|
||||||
|
|
||||||
M: _epilogue generate-insn
|
M: _epilogue generate-insn
|
||||||
n>> %epilogue ;
|
drop %epilogue ;
|
||||||
|
|
||||||
M: ##load-literal generate-insn
|
M: ##load-literal generate-insn
|
||||||
[ obj>> ] [ dst>> v>operand ] bi load-literal ;
|
[ obj>> ] [ dst>> v>operand ] bi load-literal ;
|
||||||
|
|
|
@ -7,7 +7,7 @@ stack-checker stack-checker.state stack-checker.inlining
|
||||||
compiler.errors compiler.units compiler.tree.builder
|
compiler.errors compiler.units compiler.tree.builder
|
||||||
compiler.tree.optimizer compiler.cfg.builder
|
compiler.tree.optimizer compiler.cfg.builder
|
||||||
compiler.cfg.linearization compiler.cfg.linear-scan
|
compiler.cfg.linearization compiler.cfg.linear-scan
|
||||||
compiler.codegen ;
|
compiler.cfg.stack-frame compiler.codegen ;
|
||||||
IN: compiler.new
|
IN: compiler.new
|
||||||
|
|
||||||
SYMBOL: compile-queue
|
SYMBOL: compile-queue
|
||||||
|
@ -79,7 +79,13 @@ SYMBOL: +failed+
|
||||||
bi ;
|
bi ;
|
||||||
|
|
||||||
: backend ( nodes word -- )
|
: 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 -- )
|
: (compile) ( word -- )
|
||||||
'[
|
'[
|
||||||
|
|
Loading…
Reference in New Issue