compiler.cfg.linear-scan: Get cycle breaking in resolve pass to work by allocating a spare spill slot for this purpose

db4
Slava Pestov 2009-07-05 21:32:23 -05:00
parent f14a61fac2
commit a452f32e3a
4 changed files with 158 additions and 20 deletions

View File

@ -261,4 +261,3 @@ INSN: _reload dst class n ;
INSN: _copy dst src class ;
INSN: _spill-counts counts ;
SYMBOL: spill-temp

View File

@ -206,6 +206,56 @@ check-assignment? on
} 5 split-before-use [ f >>split-next ] bi@
] unit-test
[
T{ live-interval
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
{ start 0 }
{ end 4 }
{ uses V{ 0 1 4 } }
{ ranges V{ T{ live-range f 0 4 } } }
}
T{ live-interval
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
{ start 5 }
{ end 10 }
{ uses V{ 5 10 } }
{ ranges V{ T{ live-range f 5 10 } } }
}
] [
T{ live-interval
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
{ start 0 }
{ end 10 }
{ uses V{ 0 1 10 } }
{ ranges V{ T{ live-range f 0 10 } } }
} 5 split-before-use [ f >>split-next ] bi@
] unit-test
[
T{ live-interval
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
{ start 0 }
{ end 4 }
{ uses V{ 0 1 4 } }
{ ranges V{ T{ live-range f 0 4 } } }
}
T{ live-interval
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
{ start 5 }
{ end 10 }
{ uses V{ 5 10 } }
{ ranges V{ T{ live-range f 5 10 } } }
}
] [
T{ live-interval
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
{ start 0 }
{ end 10 }
{ uses V{ 0 1 4 5 10 } }
{ ranges V{ T{ live-range f 0 10 } } }
} 5 split-before-use [ f >>split-next ] bi@
] unit-test
[
T{ live-interval
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
@ -1858,6 +1908,8 @@ test-diamond
[ _spill ] [ 3 get instructions>> second class ] unit-test
[ f ] [ 3 get instructions>> [ _reload? ] any? ] unit-test
[ _reload ] [ 4 get instructions>> first class ] unit-test
! Resolve pass
@ -1975,4 +2027,77 @@ V{
[ V{ 3 2 1 } ] [ 9 get instructions>> [ _reload? ] filter [ n>> ] map ] unit-test
! Resolve pass should insert this
[ _reload ] [ 5 get instructions>> first class ] unit-test
[ _reload ] [ 5 get instructions>> first class ] unit-test
! Some random bug
V{
T{ ##peek f V int-regs 1 D 1 }
T{ ##peek f V int-regs 2 D 2 }
T{ ##replace f V int-regs 1 D 1 }
T{ ##replace f V int-regs 2 D 2 }
T{ ##peek f V int-regs 3 D 0 }
T{ ##peek f V int-regs 0 D 0 }
T{ ##branch }
} 0 test-bb
V{ T{ ##branch } } 1 test-bb
V{
T{ ##peek f V int-regs 1 D 1 }
T{ ##peek f V int-regs 2 D 2 }
T{ ##replace f V int-regs 3 D 3 }
T{ ##replace f V int-regs 1 D 1 }
T{ ##replace f V int-regs 2 D 2 }
T{ ##replace f V int-regs 0 D 3 }
T{ ##branch }
} 2 test-bb
V{ T{ ##branch } } 3 test-bb
V{
T{ ##return }
} 4 test-bb
test-diamond
[ ] [ { 1 2 } test-linear-scan-on-cfg ] unit-test
! Spilling an interval immediately after its activated;
! and the interval does not have a use at the activation point
V{
T{ ##peek f V int-regs 1 D 1 }
T{ ##peek f V int-regs 2 D 2 }
T{ ##replace f V int-regs 1 D 1 }
T{ ##replace f V int-regs 2 D 2 }
T{ ##peek f V int-regs 0 D 0 }
T{ ##branch }
} 0 test-bb
V{ T{ ##branch } } 1 test-bb
V{
T{ ##peek f V int-regs 1 D 1 }
T{ ##branch }
} 2 test-bb
V{
T{ ##replace f V int-regs 1 D 1 }
T{ ##peek f V int-regs 2 D 2 }
T{ ##replace f V int-regs 2 D 2 }
T{ ##branch }
} 3 test-bb
V{ T{ ##branch } } 4 test-bb
V{
T{ ##replace f V int-regs 0 D 0 }
T{ ##return }
} 5 test-bb
1 get 1vector 0 get (>>successors)
2 get 4 get V{ } 2sequence 1 get (>>successors)
5 get 1vector 4 get (>>successors)
3 get 1vector 2 get (>>successors)
5 get 1vector 3 get (>>successors)
[ ] [ { 1 2 } test-linear-scan-on-cfg ] unit-test

View File

@ -3,6 +3,7 @@ compiler.cfg.debugger compiler.cfg.instructions
compiler.cfg.linear-scan.debugger
compiler.cfg.linear-scan.live-intervals
compiler.cfg.linear-scan.numbering
compiler.cfg.linear-scan.allocation.state
compiler.cfg.linear-scan.resolve compiler.cfg.predecessors
compiler.cfg.registers compiler.cfg.rpo cpu.architecture kernel
namespaces tools.test vectors ;
@ -12,15 +13,18 @@ IN: compiler.cfg.linear-scan.resolve.tests
{ 3 4 } V{ 1 2 } clone [ { 5 6 } 3append-here ] keep >array
] unit-test
H{ { int-regs 10 } { float-regs 20 } } clone spill-counts set
H{ } clone spill-temps set
[
{
T{ _copy { dst 5 } { src 4 } { class int-regs } }
T{ _spill { src 1 } { class int-regs } { n spill-temp } }
T{ _spill { src 1 } { class int-regs } { n 10 } }
T{ _copy { dst 1 } { src 0 } { class int-regs } }
T{ _reload { dst 0 } { class int-regs } { n spill-temp } }
T{ _spill { src 1 } { class float-regs } { n spill-temp } }
T{ _reload { dst 0 } { class int-regs } { n 10 } }
T{ _spill { src 1 } { class float-regs } { n 20 } }
T{ _copy { dst 1 } { src 0 } { class float-regs } }
T{ _reload { dst 0 } { class float-regs } { n spill-temp } }
T{ _reload { dst 0 } { class float-regs } { n 20 } }
}
] [
{
@ -34,10 +38,10 @@ IN: compiler.cfg.linear-scan.resolve.tests
[
{
T{ _spill { src 2 } { class int-regs } { n spill-temp } }
T{ _spill { src 2 } { class int-regs } { n 10 } }
T{ _copy { dst 2 } { src 1 } { class int-regs } }
T{ _copy { dst 1 } { src 0 } { class int-regs } }
T{ _reload { dst 0 } { class int-regs } { n spill-temp } }
T{ _reload { dst 0 } { class int-regs } { n 10 } }
}
] [
{
@ -49,10 +53,10 @@ IN: compiler.cfg.linear-scan.resolve.tests
[
{
T{ _spill { src 0 } { class int-regs } { n spill-temp } }
T{ _spill { src 0 } { class int-regs } { n 10 } }
T{ _copy { dst 0 } { src 2 } { class int-regs } }
T{ _copy { dst 2 } { src 1 } { class int-regs } }
T{ _reload { dst 1 } { class int-regs } { n spill-temp } }
T{ _reload { dst 1 } { class int-regs } { n 10 } }
}
] [
{
@ -113,10 +117,10 @@ IN: compiler.cfg.linear-scan.resolve.tests
{
T{ _copy { dst 1 } { src 0 } { class int-regs } }
T{ _copy { dst 2 } { src 0 } { class int-regs } }
T{ _spill { src 4 } { class int-regs } { n spill-temp } }
T{ _spill { src 4 } { class int-regs } { n 10 } }
T{ _copy { dst 4 } { src 0 } { class int-regs } }
T{ _copy { dst 0 } { src 3 } { class int-regs } }
T{ _reload { dst 3 } { class int-regs } { n spill-temp } }
T{ _reload { dst 3 } { class int-regs } { n 10 } }
}
] [
{
@ -133,10 +137,10 @@ IN: compiler.cfg.linear-scan.resolve.tests
T{ _copy { dst 2 } { src 0 } { class int-regs } }
T{ _copy { dst 9 } { src 1 } { class int-regs } }
T{ _copy { dst 1 } { src 0 } { class int-regs } }
T{ _spill { src 4 } { class int-regs } { n spill-temp } }
T{ _spill { src 4 } { class int-regs } { n 10 } }
T{ _copy { dst 4 } { src 0 } { class int-regs } }
T{ _copy { dst 0 } { src 3 } { class int-regs } }
T{ _reload { dst 3 } { class int-regs } { n spill-temp } }
T{ _reload { dst 3 } { class int-regs } { n 10 } }
}
] [
{

View File

@ -3,10 +3,15 @@
USING: accessors arrays assocs classes.parser classes.tuple
combinators combinators.short-circuit fry hashtables kernel locals
make math math.order namespaces sequences sets words parser
compiler.cfg.instructions compiler.cfg.linear-scan.assignment
compiler.cfg.liveness ;
compiler.cfg.instructions compiler.cfg.linear-scan.allocation.state
compiler.cfg.linear-scan.assignment compiler.cfg.liveness ;
IN: compiler.cfg.linear-scan.resolve
SYMBOL: spill-temps
: spill-temp ( reg-class -- n )
spill-temps get [ next-spill-slot ] cache ;
<<
TUPLE: operation from to reg-class ;
@ -116,11 +121,15 @@ ERROR: resolve-error ;
: break-cycle-n ( operations -- operations' )
split-cycle [
[ from>> spill-temp <spill-slot> ]
[ reg-class>> ] bi \ register->memory boa
[ from>> ]
[ reg-class>> spill-temp <spill-slot> ]
[ reg-class>> ]
tri \ register->memory boa
] [
[ to>> spill-temp <spill-slot> swap ]
[ reg-class>> ] bi \ memory->register boa
[ reg-class>> spill-temp <spill-slot> ]
[ to>> ]
[ reg-class>> ]
tri \ memory->register boa
] bi [ 1array ] bi@ surround ;
: break-cycle ( operations -- operations' )
@ -197,4 +206,5 @@ ERROR: resolve-error ;
dup successors>> [ resolve-edge-data-flow ] with each ;
: resolve-data-flow ( rpo -- )
H{ } clone spill-temps set
[ resolve-block-data-flow ] each ;