Coalescing
parent
46b1fd652b
commit
8df1aba71d
basis/compiler/cfg
debugger
linear-scan
|
@ -5,7 +5,7 @@ classes.tuple accessors prettyprint prettyprint.config
|
||||||
compiler.tree.builder compiler.tree.optimizer
|
compiler.tree.builder compiler.tree.optimizer
|
||||||
compiler.cfg.builder compiler.cfg.linearization
|
compiler.cfg.builder compiler.cfg.linearization
|
||||||
compiler.cfg.stack-frame compiler.cfg.linear-scan
|
compiler.cfg.stack-frame compiler.cfg.linear-scan
|
||||||
compiler.cfg.optimizer ;
|
compiler.cfg.two-operand compiler.cfg.optimizer ;
|
||||||
IN: compiler.cfg.debugger
|
IN: compiler.cfg.debugger
|
||||||
|
|
||||||
GENERIC: test-cfg ( quot -- cfgs )
|
GENERIC: test-cfg ( quot -- cfgs )
|
||||||
|
@ -22,6 +22,7 @@ SYMBOL: allocate-registers?
|
||||||
test-cfg [
|
test-cfg [
|
||||||
optimize-cfg
|
optimize-cfg
|
||||||
build-mr
|
build-mr
|
||||||
|
convert-two-operand
|
||||||
allocate-registers? get
|
allocate-registers? get
|
||||||
[ linear-scan build-stack-frame ] when
|
[ linear-scan build-stack-frame ] when
|
||||||
] map ;
|
] map ;
|
||||||
|
|
|
@ -56,6 +56,20 @@ SYMBOL: progress
|
||||||
[ [ start>> ] keep ] { } map>assoc
|
[ [ start>> ] keep ] { } map>assoc
|
||||||
unhandled-intervals get heap-push-all ;
|
unhandled-intervals get heap-push-all ;
|
||||||
|
|
||||||
|
! Coalescing
|
||||||
|
: active-interval ( vreg -- live-interval )
|
||||||
|
dup active-intervals-for [ vreg>> = ] with find nip ;
|
||||||
|
|
||||||
|
: coalesce? ( live-interval -- ? )
|
||||||
|
[ start>> ] [ copy-from>> ] bi
|
||||||
|
dup [ active-interval end>> = ] [ 2drop f ] if ;
|
||||||
|
|
||||||
|
: coalesce ( live-interval -- )
|
||||||
|
dup copy-from>> active-interval
|
||||||
|
[ [ add-active ] [ delete-active ] bi* ]
|
||||||
|
[ reg>> >>reg drop ]
|
||||||
|
2bi ;
|
||||||
|
|
||||||
! Splitting
|
! Splitting
|
||||||
: find-use ( live-interval n quot -- i elt )
|
: find-use ( live-interval n quot -- i elt )
|
||||||
[ uses>> ] 2dip curry find ; inline
|
[ uses>> ] 2dip curry find ; inline
|
||||||
|
@ -67,7 +81,7 @@ SYMBOL: progress
|
||||||
: split-after ( live-interval i -- after )
|
: split-after ( live-interval i -- after )
|
||||||
[ clone dup uses>> ] dip
|
[ clone dup uses>> ] dip
|
||||||
[ tail >>uses ] [ swap nth >>start ] 2bi
|
[ tail >>uses ] [ swap nth >>start ] 2bi
|
||||||
f >>reg ;
|
f >>reg f >>copy-from ;
|
||||||
|
|
||||||
: split-interval ( live-interval n -- before after )
|
: split-interval ( live-interval n -- before after )
|
||||||
[ drop ] [ [ > ] find-use drop ] 2bi
|
[ drop ] [ [ > ] find-use drop ] 2bi
|
||||||
|
@ -128,8 +142,14 @@ SYMBOL: spill-counts
|
||||||
pop >>reg add-active ;
|
pop >>reg add-active ;
|
||||||
|
|
||||||
: assign-register ( new -- )
|
: assign-register ( new -- )
|
||||||
dup vreg>> free-registers-for
|
dup coalesce? [
|
||||||
[ assign-blocked-register ] [ assign-free-register ] if-empty ;
|
coalesce
|
||||||
|
] [
|
||||||
|
dup vreg>> free-registers-for
|
||||||
|
[ assign-blocked-register ]
|
||||||
|
[ assign-free-register ]
|
||||||
|
if-empty
|
||||||
|
] if ;
|
||||||
|
|
||||||
! Main loop
|
! Main loop
|
||||||
: reg-classes ( -- seq ) { int-regs double-float-regs } ; inline
|
: reg-classes ( -- seq ) { int-regs double-float-regs } ; inline
|
||||||
|
|
|
@ -303,3 +303,55 @@ USING: math.private compiler.cfg.debugger ;
|
||||||
allocate-registers
|
allocate-registers
|
||||||
first split-before>> [ start>> ] [ end>> ] bi
|
first split-before>> [ start>> ] [ end>> ] bi
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
! Coalescing interacted badly with splitting
|
||||||
|
[ ] [
|
||||||
|
{
|
||||||
|
T{ live-interval
|
||||||
|
{ vreg V int-regs 70 }
|
||||||
|
{ start 14 }
|
||||||
|
{ end 17 }
|
||||||
|
{ uses V{ 14 15 16 17 } }
|
||||||
|
{ copy-from V int-regs 67 }
|
||||||
|
}
|
||||||
|
T{ live-interval
|
||||||
|
{ vreg V int-regs 67 }
|
||||||
|
{ start 13 }
|
||||||
|
{ end 14 }
|
||||||
|
{ uses V{ 13 14 } }
|
||||||
|
}
|
||||||
|
T{ live-interval
|
||||||
|
{ vreg V int-regs 30 }
|
||||||
|
{ start 4 }
|
||||||
|
{ end 18 }
|
||||||
|
{ uses V{ 4 12 16 17 18 } }
|
||||||
|
}
|
||||||
|
T{ live-interval
|
||||||
|
{ vreg V int-regs 27 }
|
||||||
|
{ start 3 }
|
||||||
|
{ end 13 }
|
||||||
|
{ uses V{ 3 7 13 } }
|
||||||
|
}
|
||||||
|
T{ live-interval
|
||||||
|
{ vreg V int-regs 59 }
|
||||||
|
{ start 10 }
|
||||||
|
{ end 18 }
|
||||||
|
{ uses V{ 10 11 12 18 } }
|
||||||
|
{ copy-from V int-regs 56 }
|
||||||
|
}
|
||||||
|
T{ live-interval
|
||||||
|
{ vreg V int-regs 60 }
|
||||||
|
{ start 12 }
|
||||||
|
{ end 17 }
|
||||||
|
{ uses V{ 12 17 } }
|
||||||
|
}
|
||||||
|
T{ live-interval
|
||||||
|
{ vreg V int-regs 56 }
|
||||||
|
{ start 9 }
|
||||||
|
{ end 10 }
|
||||||
|
{ uses V{ 9 10 } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{ { int-regs { 0 1 2 3 } } }
|
||||||
|
allocate-registers
|
||||||
|
] unit-test
|
||||||
|
|
|
@ -8,7 +8,8 @@ IN: compiler.cfg.linear-scan.live-intervals
|
||||||
TUPLE: live-interval
|
TUPLE: live-interval
|
||||||
vreg
|
vreg
|
||||||
reg spill-to reload-from split-before split-after
|
reg spill-to reload-from split-before split-after
|
||||||
start end uses ;
|
start end uses
|
||||||
|
copy-from ;
|
||||||
|
|
||||||
: add-use ( n live-interval -- )
|
: add-use ( n live-interval -- )
|
||||||
dup live-interval? [ "No def" throw ] unless
|
dup live-interval? [ "No def" throw ] unless
|
||||||
|
@ -37,12 +38,23 @@ SYMBOL: live-intervals
|
||||||
[ [ <live-interval> ] keep ] dip set-at
|
[ [ <live-interval> ] keep ] dip set-at
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
: compute-live-intervals* ( insn n -- )
|
GENERIC# compute-live-intervals* 1 ( insn n -- )
|
||||||
|
|
||||||
|
M: insn compute-live-intervals*
|
||||||
live-intervals get
|
live-intervals get
|
||||||
[ [ uses-vregs ] 2dip '[ _ swap _ at add-use ] each ]
|
[ [ uses-vregs ] 2dip '[ _ swap _ at add-use ] each ]
|
||||||
[ [ defs-vregs ] 2dip '[ _ swap _ new-live-interval ] each ]
|
[ [ defs-vregs ] 2dip '[ _ swap _ new-live-interval ] each ]
|
||||||
3bi ;
|
3bi ;
|
||||||
|
|
||||||
|
: record-copy ( insn -- )
|
||||||
|
[ dst>> live-intervals get at ] [ src>> ] bi >>copy-from drop ;
|
||||||
|
|
||||||
|
M: ##copy compute-live-intervals*
|
||||||
|
[ call-next-method ] [ drop record-copy ] 2bi ;
|
||||||
|
|
||||||
|
M: ##copy-float compute-live-intervals*
|
||||||
|
[ call-next-method ] [ drop record-copy ] 2bi ;
|
||||||
|
|
||||||
: compute-live-intervals ( instructions -- live-intervals )
|
: compute-live-intervals ( instructions -- live-intervals )
|
||||||
H{ } clone [
|
H{ } clone [
|
||||||
live-intervals set
|
live-intervals set
|
||||||
|
|
Loading…
Reference in New Issue