Merge branch 'master' of git://factorcode.org/git/factor
commit
b5ca026852
|
@ -26,7 +26,7 @@ M: word test-cfg
|
||||||
] map ;
|
] map ;
|
||||||
|
|
||||||
: insn. ( insn -- )
|
: insn. ( insn -- )
|
||||||
tuple>array [ pprint bl ] each nl ;
|
tuple>array but-last [ pprint bl ] each nl ;
|
||||||
|
|
||||||
: mr. ( mrs -- )
|
: mr. ( mrs -- )
|
||||||
[
|
[
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
! Copyright (C) 2009 Slava Pestov.
|
! Copyright (C) 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors kernel sequences
|
USING: accessors kernel sequences namespaces assocs fry
|
||||||
combinators.short-circuit
|
combinators.short-circuit
|
||||||
compiler.cfg.linear-scan.live-intervals
|
compiler.cfg.linear-scan.live-intervals
|
||||||
compiler.cfg.linear-scan.allocation.state ;
|
compiler.cfg.linear-scan.allocation.state ;
|
||||||
|
@ -20,9 +20,16 @@ IN: compiler.cfg.linear-scan.allocation.coalescing
|
||||||
[ avoids-inactive-intervals? ]
|
[ avoids-inactive-intervals? ]
|
||||||
} 1&& ;
|
} 1&& ;
|
||||||
|
|
||||||
|
: reuse-spill-slot ( old new -- )
|
||||||
|
[ vreg>> spill-slots get at ] dip '[ _ vreg>> spill-slots get set-at ] when* ;
|
||||||
|
|
||||||
|
: reuse-register ( old new -- )
|
||||||
|
reg>> >>reg drop ;
|
||||||
|
|
||||||
|
: (coalesce) ( old new -- )
|
||||||
|
[ add-active ] [ [ delete-active ] [ add-handled ] bi ] bi* ;
|
||||||
|
|
||||||
: coalesce ( live-interval -- )
|
: coalesce ( live-interval -- )
|
||||||
dup copy-from>> active-interval
|
dup copy-from>> active-interval
|
||||||
[ [ add-active ] [ [ delete-active ] [ add-handled ] bi ] bi* ]
|
[ reuse-spill-slot ] [ reuse-register ] [ (coalesce) ] 2tri ;
|
||||||
[ reg>> >>reg drop ]
|
|
||||||
2bi ;
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ ERROR: bad-live-ranges interval ;
|
||||||
] [ drop ] if ;
|
] [ drop ] if ;
|
||||||
|
|
||||||
: trim-before-ranges ( live-interval -- )
|
: trim-before-ranges ( live-interval -- )
|
||||||
[ ranges>> ] [ uses>> last ] bi
|
[ ranges>> ] [ uses>> last 1 + ] bi
|
||||||
[ '[ from>> _ <= ] filter-here ]
|
[ '[ from>> _ <= ] filter-here ]
|
||||||
[ swap last (>>to) ]
|
[ swap last (>>to) ]
|
||||||
2bi ;
|
2bi ;
|
||||||
|
@ -38,10 +38,10 @@ ERROR: bad-live-ranges interval ;
|
||||||
} 2cleave ;
|
} 2cleave ;
|
||||||
|
|
||||||
: assign-spill ( live-interval -- )
|
: assign-spill ( live-interval -- )
|
||||||
dup assign-spill-slot >>spill-to f >>split-next drop ;
|
dup vreg>> assign-spill-slot >>spill-to f >>split-next drop ;
|
||||||
|
|
||||||
: assign-reload ( live-interval -- )
|
: assign-reload ( live-interval -- )
|
||||||
dup assign-spill-slot >>reload-from drop ;
|
dup vreg>> assign-spill-slot >>reload-from drop ;
|
||||||
|
|
||||||
: split-and-spill ( live-interval n -- before after )
|
: split-and-spill ( live-interval n -- before after )
|
||||||
split-for-spill 2dup [ assign-spill ] [ assign-reload ] bi* ;
|
split-for-spill 2dup [ assign-spill ] [ assign-reload ] bi* ;
|
||||||
|
|
|
@ -126,18 +126,8 @@ SYMBOL: spill-counts
|
||||||
! Mapping from vregs to spill slots
|
! Mapping from vregs to spill slots
|
||||||
SYMBOL: spill-slots
|
SYMBOL: spill-slots
|
||||||
|
|
||||||
DEFER: assign-spill-slot
|
: assign-spill-slot ( vreg -- n )
|
||||||
|
spill-slots get [ reg-class>> next-spill-slot ] cache ;
|
||||||
: compute-spill-slot ( live-interval -- n )
|
|
||||||
dup copy-from>>
|
|
||||||
[ assign-spill-slot ]
|
|
||||||
[ vreg>> reg-class>> next-spill-slot ] ?if ;
|
|
||||||
|
|
||||||
: assign-spill-slot ( live-interval -- n )
|
|
||||||
dup vreg>> spill-slots get at [ ] [
|
|
||||||
[ compute-spill-slot dup ] keep
|
|
||||||
vreg>> spill-slots get set-at
|
|
||||||
] ?if ;
|
|
||||||
|
|
||||||
: init-allocator ( registers -- )
|
: init-allocator ( registers -- )
|
||||||
registers set
|
registers set
|
||||||
|
|
|
@ -107,7 +107,7 @@ SYMBOL: check-assignment?
|
||||||
ERROR: overlapping-registers intervals ;
|
ERROR: overlapping-registers intervals ;
|
||||||
|
|
||||||
: check-assignment ( intervals -- )
|
: check-assignment ( intervals -- )
|
||||||
dup [ copy-from>> ] map sift [ vreg>> ] map '[ vreg>> _ member? not ] filter
|
dup [ copy-from>> ] map sift '[ vreg>> _ member? not ] filter
|
||||||
dup [ reg>> ] map all-unique? [ drop ] [ overlapping-registers ] if ;
|
dup [ reg>> ] map all-unique? [ drop ] [ overlapping-registers ] if ;
|
||||||
|
|
||||||
: active-intervals ( n -- intervals )
|
: active-intervals ( n -- intervals )
|
||||||
|
@ -150,7 +150,7 @@ ERROR: bad-live-values live-values ;
|
||||||
|
|
||||||
: begin-block ( bb -- )
|
: begin-block ( bb -- )
|
||||||
dup basic-block set
|
dup basic-block set
|
||||||
dup block-from prepare-insn
|
dup block-from activate-new-intervals
|
||||||
[ [ live-in ] [ block-from ] bi compute-live-values ] keep
|
[ [ live-in ] [ block-from ] bi compute-live-values ] keep
|
||||||
register-live-ins get set-at ;
|
register-live-ins get set-at ;
|
||||||
|
|
||||||
|
|
|
@ -82,9 +82,9 @@ check-numbering? on
|
||||||
T{ live-interval
|
T{ live-interval
|
||||||
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
||||||
{ start 0 }
|
{ start 0 }
|
||||||
{ end 1 }
|
{ end 2 }
|
||||||
{ uses V{ 0 1 } }
|
{ uses V{ 0 1 } }
|
||||||
{ ranges V{ T{ live-range f 0 1 } } }
|
{ ranges V{ T{ live-range f 0 2 } } }
|
||||||
}
|
}
|
||||||
T{ live-interval
|
T{ live-interval
|
||||||
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
||||||
|
@ -107,9 +107,9 @@ check-numbering? on
|
||||||
T{ live-interval
|
T{ live-interval
|
||||||
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
||||||
{ start 0 }
|
{ start 0 }
|
||||||
{ end 0 }
|
{ end 1 }
|
||||||
{ uses V{ 0 } }
|
{ uses V{ 0 } }
|
||||||
{ ranges V{ T{ live-range f 0 0 } } }
|
{ ranges V{ T{ live-range f 0 1 } } }
|
||||||
}
|
}
|
||||||
T{ live-interval
|
T{ live-interval
|
||||||
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
||||||
|
@ -132,9 +132,9 @@ check-numbering? on
|
||||||
T{ live-interval
|
T{ live-interval
|
||||||
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
||||||
{ start 0 }
|
{ start 0 }
|
||||||
{ end 0 }
|
{ end 1 }
|
||||||
{ uses V{ 0 } }
|
{ uses V{ 0 } }
|
||||||
{ ranges V{ T{ live-range f 0 0 } } }
|
{ ranges V{ T{ live-range f 0 1 } } }
|
||||||
}
|
}
|
||||||
T{ live-interval
|
T{ live-interval
|
||||||
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
||||||
|
@ -1317,38 +1317,6 @@ USING: math.private ;
|
||||||
allocate-registers drop
|
allocate-registers drop
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
! Spill slot liveness was computed incorrectly, leading to a FEP
|
|
||||||
! early in bootstrap on x86-32
|
|
||||||
[ t ] [
|
|
||||||
[
|
|
||||||
H{ } clone live-ins set
|
|
||||||
H{ } clone live-outs set
|
|
||||||
H{ } clone phi-live-ins set
|
|
||||||
T{ basic-block
|
|
||||||
{ id 12345 }
|
|
||||||
{ instructions
|
|
||||||
V{
|
|
||||||
T{ ##gc f V int-regs 6 V int-regs 7 }
|
|
||||||
T{ ##peek f V int-regs 0 D 0 }
|
|
||||||
T{ ##peek f V int-regs 1 D 1 }
|
|
||||||
T{ ##peek f V int-regs 2 D 2 }
|
|
||||||
T{ ##peek f V int-regs 3 D 3 }
|
|
||||||
T{ ##peek f V int-regs 4 D 4 }
|
|
||||||
T{ ##peek f V int-regs 5 D 5 }
|
|
||||||
T{ ##replace f V int-regs 0 D 1 }
|
|
||||||
T{ ##replace f V int-regs 1 D 2 }
|
|
||||||
T{ ##replace f V int-regs 2 D 3 }
|
|
||||||
T{ ##replace f V int-regs 3 D 4 }
|
|
||||||
T{ ##replace f V int-regs 4 D 5 }
|
|
||||||
T{ ##replace f V int-regs 5 D 0 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} dup 1array { { int-regs V{ 0 1 2 3 } } } (linear-scan)
|
|
||||||
instructions>> first
|
|
||||||
live-values>> assoc-empty?
|
|
||||||
] with-scope
|
|
||||||
] unit-test
|
|
||||||
|
|
||||||
[ f ] [
|
[ f ] [
|
||||||
T{ live-range f 0 10 }
|
T{ live-range f 0 10 }
|
||||||
T{ live-range f 20 30 }
|
T{ live-range f 20 30 }
|
||||||
|
@ -2482,4 +2450,161 @@ V{
|
||||||
7 get 9 get 1vector >>successors drop
|
7 get 9 get 1vector >>successors drop
|
||||||
8 get 9 get 1vector >>successors drop
|
8 get 9 get 1vector >>successors drop
|
||||||
|
|
||||||
[ ] [ { 1 2 3 4 5 } test-linear-scan-on-cfg ] unit-test
|
[ ] [ { 1 2 3 4 5 } test-linear-scan-on-cfg ] unit-test
|
||||||
|
|
||||||
|
! Fencepost error in assignment pass
|
||||||
|
V{ T{ ##branch } } 0 test-bb
|
||||||
|
|
||||||
|
V{
|
||||||
|
T{ ##peek f V int-regs 0 D 0 }
|
||||||
|
T{ ##compare-imm-branch f V int-regs 0 5 cc= }
|
||||||
|
} 1 test-bb
|
||||||
|
|
||||||
|
V{ T{ ##branch } } 2 test-bb
|
||||||
|
|
||||||
|
V{
|
||||||
|
T{ ##peek f V int-regs 1 D 0 }
|
||||||
|
T{ ##peek f V int-regs 2 D 0 }
|
||||||
|
T{ ##replace f V int-regs 1 D 0 }
|
||||||
|
T{ ##replace f V int-regs 2 D 0 }
|
||||||
|
T{ ##branch }
|
||||||
|
} 3 test-bb
|
||||||
|
|
||||||
|
V{
|
||||||
|
T{ ##replace f V int-regs 0 D 0 }
|
||||||
|
T{ ##return }
|
||||||
|
} 4 test-bb
|
||||||
|
|
||||||
|
test-diamond
|
||||||
|
|
||||||
|
[ ] [ { 1 2 } test-linear-scan-on-cfg ] unit-test
|
||||||
|
|
||||||
|
[ 0 ] [ 1 get instructions>> [ _spill? ] count ] unit-test
|
||||||
|
|
||||||
|
[ 1 ] [ 2 get instructions>> [ _spill? ] count ] unit-test
|
||||||
|
|
||||||
|
[ 1 ] [ 3 get instructions>> [ _spill? ] count ] unit-test
|
||||||
|
|
||||||
|
[ 1 ] [ 4 get instructions>> [ _reload? ] count ] unit-test
|
||||||
|
|
||||||
|
! Another test case for fencepost error in assignment pass
|
||||||
|
V{ T{ ##branch } } 0 test-bb
|
||||||
|
|
||||||
|
V{
|
||||||
|
T{ ##peek f V int-regs 0 D 0 }
|
||||||
|
T{ ##compare-imm-branch f V int-regs 0 5 cc= }
|
||||||
|
} 1 test-bb
|
||||||
|
|
||||||
|
V{
|
||||||
|
T{ ##peek f V int-regs 1 D 0 }
|
||||||
|
T{ ##peek f V int-regs 2 D 0 }
|
||||||
|
T{ ##replace f V int-regs 1 D 0 }
|
||||||
|
T{ ##replace f V int-regs 2 D 0 }
|
||||||
|
T{ ##replace f V int-regs 0 D 0 }
|
||||||
|
T{ ##branch }
|
||||||
|
} 2 test-bb
|
||||||
|
|
||||||
|
V{
|
||||||
|
T{ ##branch }
|
||||||
|
} 3 test-bb
|
||||||
|
|
||||||
|
V{
|
||||||
|
T{ ##replace f V int-regs 0 D 0 }
|
||||||
|
T{ ##return }
|
||||||
|
} 4 test-bb
|
||||||
|
|
||||||
|
test-diamond
|
||||||
|
|
||||||
|
[ ] [ { 1 2 } test-linear-scan-on-cfg ] unit-test
|
||||||
|
|
||||||
|
[ 0 ] [ 1 get instructions>> [ _spill? ] count ] unit-test
|
||||||
|
|
||||||
|
[ 1 ] [ 2 get instructions>> [ _spill? ] count ] unit-test
|
||||||
|
|
||||||
|
[ 1 ] [ 2 get instructions>> [ _reload? ] count ] unit-test
|
||||||
|
|
||||||
|
[ 0 ] [ 3 get instructions>> [ _spill? ] count ] unit-test
|
||||||
|
|
||||||
|
[ 0 ] [ 4 get instructions>> [ _reload? ] count ] unit-test
|
||||||
|
|
||||||
|
! GC check tests
|
||||||
|
|
||||||
|
! Spill slot liveness was computed incorrectly, leading to a FEP
|
||||||
|
! early in bootstrap on x86-32
|
||||||
|
[ t ] [
|
||||||
|
[
|
||||||
|
H{ } clone live-ins set
|
||||||
|
H{ } clone live-outs set
|
||||||
|
H{ } clone phi-live-ins set
|
||||||
|
T{ basic-block
|
||||||
|
{ id 12345 }
|
||||||
|
{ instructions
|
||||||
|
V{
|
||||||
|
T{ ##gc f V int-regs 6 V int-regs 7 }
|
||||||
|
T{ ##peek f V int-regs 0 D 0 }
|
||||||
|
T{ ##peek f V int-regs 1 D 1 }
|
||||||
|
T{ ##peek f V int-regs 2 D 2 }
|
||||||
|
T{ ##peek f V int-regs 3 D 3 }
|
||||||
|
T{ ##peek f V int-regs 4 D 4 }
|
||||||
|
T{ ##peek f V int-regs 5 D 5 }
|
||||||
|
T{ ##replace f V int-regs 0 D 1 }
|
||||||
|
T{ ##replace f V int-regs 1 D 2 }
|
||||||
|
T{ ##replace f V int-regs 2 D 3 }
|
||||||
|
T{ ##replace f V int-regs 3 D 4 }
|
||||||
|
T{ ##replace f V int-regs 4 D 5 }
|
||||||
|
T{ ##replace f V int-regs 5 D 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} dup 1array { { int-regs V{ 0 1 2 3 } } } (linear-scan)
|
||||||
|
instructions>> first
|
||||||
|
live-values>> assoc-empty?
|
||||||
|
] with-scope
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
V{
|
||||||
|
T{ ##peek f V int-regs 0 D 0 }
|
||||||
|
T{ ##peek f V int-regs 1 D 1 }
|
||||||
|
T{ ##replace f V int-regs 1 D 1 }
|
||||||
|
T{ ##branch }
|
||||||
|
} 0 test-bb
|
||||||
|
|
||||||
|
V{
|
||||||
|
T{ ##gc f V int-regs 2 V int-regs 3 }
|
||||||
|
T{ ##branch }
|
||||||
|
} 1 test-bb
|
||||||
|
|
||||||
|
V{
|
||||||
|
T{ ##replace f V int-regs 0 D 0 }
|
||||||
|
T{ ##return }
|
||||||
|
} 2 test-bb
|
||||||
|
|
||||||
|
0 get 1 get 1vector >>successors drop
|
||||||
|
1 get 2 get 1vector >>successors drop
|
||||||
|
|
||||||
|
[ ] [ { 1 2 3 } test-linear-scan-on-cfg ] unit-test
|
||||||
|
|
||||||
|
[ H{ { V int-regs 0 3 } } ] [ 1 get instructions>> first live-values>> ] unit-test
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
V{
|
||||||
|
T{ ##peek f V int-regs 0 D 0 }
|
||||||
|
T{ ##peek f V int-regs 1 D 1 }
|
||||||
|
T{ ##compare-imm-branch f V int-regs 1 5 cc= }
|
||||||
|
} 0 test-bb
|
||||||
|
|
||||||
|
V{
|
||||||
|
T{ ##gc f V int-regs 2 V int-regs 3 }
|
||||||
|
T{ ##replace f V int-regs 0 D 0 }
|
||||||
|
T{ ##return }
|
||||||
|
} 1 test-bb
|
||||||
|
|
||||||
|
V{
|
||||||
|
T{ ##return }
|
||||||
|
} 2 test-bb
|
||||||
|
|
||||||
|
0 get 1 get 2 get V{ } 2sequence >>successors drop
|
||||||
|
|
||||||
|
[ ] [ { 1 2 3 } test-linear-scan-on-cfg ] unit-test
|
||||||
|
|
||||||
|
[ H{ { V int-regs 0 3 } } ] [ 1 get instructions>> first live-values>> ] unit-test
|
||||||
|
|
Loading…
Reference in New Issue