Coalescing

db4
Slava Pestov 2008-11-02 01:49:57 -06:00
parent 46b1fd652b
commit 8df1aba71d
4 changed files with 91 additions and 6 deletions

View File

@ -5,7 +5,7 @@ classes.tuple accessors prettyprint prettyprint.config
compiler.tree.builder compiler.tree.optimizer
compiler.cfg.builder compiler.cfg.linearization
compiler.cfg.stack-frame compiler.cfg.linear-scan
compiler.cfg.optimizer ;
compiler.cfg.two-operand compiler.cfg.optimizer ;
IN: compiler.cfg.debugger
GENERIC: test-cfg ( quot -- cfgs )
@ -22,6 +22,7 @@ SYMBOL: allocate-registers?
test-cfg [
optimize-cfg
build-mr
convert-two-operand
allocate-registers? get
[ linear-scan build-stack-frame ] when
] map ;

View File

@ -56,6 +56,20 @@ SYMBOL: progress
[ [ start>> ] keep ] { } map>assoc
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
: find-use ( live-interval n quot -- i elt )
[ uses>> ] 2dip curry find ; inline
@ -67,7 +81,7 @@ SYMBOL: progress
: split-after ( live-interval i -- after )
[ clone dup uses>> ] dip
[ tail >>uses ] [ swap nth >>start ] 2bi
f >>reg ;
f >>reg f >>copy-from ;
: split-interval ( live-interval n -- before after )
[ drop ] [ [ > ] find-use drop ] 2bi
@ -128,8 +142,14 @@ SYMBOL: spill-counts
pop >>reg add-active ;
: assign-register ( new -- )
dup vreg>> free-registers-for
[ assign-blocked-register ] [ assign-free-register ] if-empty ;
dup coalesce? [
coalesce
] [
dup vreg>> free-registers-for
[ assign-blocked-register ]
[ assign-free-register ]
if-empty
] if ;
! Main loop
: reg-classes ( -- seq ) { int-regs double-float-regs } ; inline

View File

@ -303,3 +303,55 @@ USING: math.private compiler.cfg.debugger ;
allocate-registers
first split-before>> [ start>> ] [ end>> ] bi
] 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

View File

@ -8,7 +8,8 @@ IN: compiler.cfg.linear-scan.live-intervals
TUPLE: live-interval
vreg
reg spill-to reload-from split-before split-after
start end uses ;
start end uses
copy-from ;
: add-use ( n live-interval -- )
dup live-interval? [ "No def" throw ] unless
@ -37,12 +38,23 @@ SYMBOL: live-intervals
[ [ <live-interval> ] keep ] dip set-at
] if ;
: compute-live-intervals* ( insn n -- )
GENERIC# compute-live-intervals* 1 ( insn n -- )
M: insn compute-live-intervals*
live-intervals get
[ [ uses-vregs ] 2dip '[ _ swap _ at add-use ] each ]
[ [ defs-vregs ] 2dip '[ _ swap _ new-live-interval ] each ]
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 )
H{ } clone [
live-intervals set