compiler.cfg.linear-scan: clean up clobber-insn handling

db4
Slava Pestov 2010-05-07 18:22:35 -04:00
parent d215d691b5
commit 982e704626
6 changed files with 153 additions and 95 deletions

View File

@ -35,10 +35,9 @@ IN: compiler.cfg.linear-scan.allocation
} cond ;
: spill-at-sync-point ( live-interval n -- ? )
! If the live interval has a usage at 'n', don't spill it,
! since this means its being defined by the sync point
! instruction. Output t if this is the case.
2dup [ uses>> ] dip '[ n>> _ = ] any?
! If the live interval has a definition at 'n', don't spill
2dup [ uses>> ] dip
'[ [ def-rep>> ] [ n>> _ = ] bi and ] any?
[ 2drop t ] [ spill f ] if ;
: handle-sync-point ( n -- )

View File

@ -28,14 +28,20 @@ ERROR: bad-live-ranges interval ;
[ swap first from<< ]
2bi ;
: last-use-rep ( live-interval -- rep/f )
last-use [ def-rep>> ] [ use-rep>> ] bi or ; inline
: assign-spill ( live-interval -- )
dup [ vreg>> ] [ last-use rep>> ] bi
assign-spill-slot >>spill-to drop ;
dup last-use-rep dup [
>>spill-rep
dup [ vreg>> ] [ spill-rep>> ] bi
assign-spill-slot >>spill-to drop
] [ 2drop ] if ;
: spill-before ( before -- before/f )
! If the interval does not have any usages before the spill location,
! then it is the second child of an interval that was split. We reload
! the value and let the resolve pass insert a split later.
! the value and let the resolve pass insert a spill later.
dup uses>> empty? [ drop f ] [
{
[ ]
@ -46,9 +52,15 @@ ERROR: bad-live-ranges interval ;
} cleave
] if ;
: first-use-rep ( live-interval -- rep/f )
first-use use-rep>> ; inline
: assign-reload ( live-interval -- )
dup [ vreg>> ] [ first-use rep>> ] bi
assign-spill-slot >>reload-from drop ;
dup first-use-rep dup [
>>reload-rep
dup [ vreg>> ] [ reload-rep>> ] bi
assign-spill-slot >>reload-from drop
] [ 2drop ] if ;
: spill-after ( after -- after/f )
! If the interval has no more usages after the spill location,

View File

@ -1,6 +1,7 @@
! Copyright (C) 2009, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays assocs combinators fry hints kernel locals
USING: accessors arrays assocs combinators
combinators.short-circuit fry hints kernel locals
math sequences sets sorting splitting namespaces
compiler.cfg.linear-scan.allocation.state
compiler.cfg.linear-scan.live-intervals ;
@ -25,7 +26,9 @@ IN: compiler.cfg.linear-scan.allocation.splitting
] bi ;
: split-uses ( uses n -- before after )
'[ n>> _ <= ] partition ;
[ '[ n>> _ < ] filter ]
[ '[ n>> _ > ] filter ]
2bi ;
ERROR: splitting-too-early ;

View File

@ -93,7 +93,7 @@ SYMBOL: machine-live-outs
init-unhandled ;
: insert-spill ( live-interval -- )
[ reg>> ] [ last-use rep>> ] [ spill-to>> ] tri ##spill ;
[ reg>> ] [ spill-rep>> ] [ spill-to>> ] tri ##spill ;
: handle-spill ( live-interval -- )
dup spill-to>> [ insert-spill ] [ drop ] if ;
@ -113,18 +113,10 @@ SYMBOL: machine-live-outs
pending-interval-heap get (expire-old-intervals) ;
: insert-reload ( live-interval -- )
[ reg>> ] [ first-use rep>> ] [ reload-from>> ] tri ##reload ;
: insert-reload? ( live-interval -- ? )
! Don't insert a reload if the register will be written to
! before being read again.
{
[ reload-from>> ]
[ first-use type>> +use+ eq? ]
} 1&& ;
[ reg>> ] [ reload-rep>> ] [ reload-from>> ] tri ##reload ;
: handle-reload ( live-interval -- )
dup insert-reload? [ insert-reload ] [ drop ] if ;
dup reload-from>> [ insert-reload ] [ drop ] if ;
: activate-interval ( live-interval -- )
[ add-pending ] [ handle-reload ] bi ;

View File

@ -91,18 +91,20 @@ H{
{ reg-class float-regs }
{ start 0 }
{ end 2 }
{ uses V{ T{ vreg-use f float-rep 0 } T{ vreg-use f float-rep 1 } } }
{ uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 1 f float-rep } } }
{ ranges V{ T{ live-range f 0 2 } } }
{ spill-to T{ spill-slot f 0 } }
{ spill-rep float-rep }
}
T{ live-interval
{ vreg 1 }
{ reg-class float-regs }
{ start 5 }
{ end 5 }
{ uses V{ T{ vreg-use f float-rep 5 } } }
{ uses V{ T{ vreg-use f 5 f float-rep } } }
{ ranges V{ T{ live-range f 5 5 } } }
{ reload-from T{ spill-slot f 0 } }
{ reload-rep float-rep }
}
] [
T{ live-interval
@ -110,29 +112,22 @@ H{
{ reg-class float-regs }
{ start 0 }
{ end 5 }
{ uses V{ T{ vreg-use f float-rep 0 } T{ vreg-use f float-rep 1 } T{ vreg-use f float-rep 5 } } }
{ uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 1 f float-rep } T{ vreg-use f 5 f float-rep } } }
{ ranges V{ T{ live-range f 0 5 } } }
} 2 split-for-spill
] unit-test
[
T{ live-interval
{ vreg 2 }
{ reg-class float-regs }
{ start 0 }
{ end 1 }
{ uses V{ T{ vreg-use f float-rep 0 } } }
{ ranges V{ T{ live-range f 0 1 } } }
{ spill-to T{ spill-slot f 4 } }
}
f
T{ live-interval
{ vreg 2 }
{ reg-class float-regs }
{ start 1 }
{ end 5 }
{ uses V{ T{ vreg-use f float-rep 1 } T{ vreg-use f float-rep 5 } } }
{ uses V{ T{ vreg-use f 1 f float-rep } T{ vreg-use f 5 f float-rep } } }
{ ranges V{ T{ live-range f 1 5 } } }
{ reload-from T{ spill-slot f 4 } }
{ reload-rep float-rep }
}
] [
T{ live-interval
@ -140,7 +135,7 @@ H{
{ reg-class float-regs }
{ start 0 }
{ end 5 }
{ uses V{ T{ vreg-use f float-rep 0 } T{ vreg-use f float-rep 1 } T{ vreg-use f float-rep 5 } } }
{ uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 1 f float-rep } T{ vreg-use f 5 f float-rep } } }
{ ranges V{ T{ live-range f 0 5 } } }
} 0 split-for-spill
] unit-test
@ -151,18 +146,20 @@ H{
{ reg-class float-regs }
{ start 0 }
{ end 1 }
{ uses V{ T{ vreg-use f float-rep 0 } } }
{ uses V{ T{ vreg-use f 0 float-rep f } } }
{ ranges V{ T{ live-range f 0 1 } } }
{ spill-to T{ spill-slot f 8 } }
{ spill-rep float-rep }
}
T{ live-interval
{ vreg 3 }
{ reg-class float-regs }
{ start 20 }
{ end 30 }
{ uses V{ T{ vreg-use f float-rep 20 } T{ vreg-use f float-rep 30 } } }
{ uses V{ T{ vreg-use f 20 f float-rep } T{ vreg-use f 30 f float-rep } } }
{ ranges V{ T{ live-range f 20 30 } } }
{ reload-from T{ spill-slot f 8 } }
{ reload-rep float-rep }
}
] [
T{ live-interval
@ -170,11 +167,75 @@ H{
{ reg-class float-regs }
{ start 0 }
{ end 30 }
{ uses V{ T{ vreg-use f float-rep 0 } T{ vreg-use f float-rep 20 } T{ vreg-use f float-rep 30 } } }
{ uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 20 f float-rep } T{ vreg-use f 30 f float-rep } } }
{ ranges V{ T{ live-range f 0 8 } T{ live-range f 10 18 } T{ live-range f 20 30 } } }
} 10 split-for-spill
] unit-test
! Don't insert reload if first usage is a def
[
T{ live-interval
{ vreg 4 }
{ reg-class float-regs }
{ start 0 }
{ end 1 }
{ uses V{ T{ vreg-use f 0 float-rep f } } }
{ ranges V{ T{ live-range f 0 1 } } }
{ spill-to T{ spill-slot f 12 } }
{ spill-rep float-rep }
}
T{ live-interval
{ vreg 4 }
{ reg-class float-regs }
{ start 20 }
{ end 30 }
{ uses V{ T{ vreg-use f 20 float-rep f } T{ vreg-use f 30 f float-rep } } }
{ ranges V{ T{ live-range f 20 30 } } }
}
] [
T{ live-interval
{ vreg 4 }
{ reg-class float-regs }
{ start 0 }
{ end 30 }
{ uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 20 float-rep f } T{ vreg-use f 30 f float-rep } } }
{ ranges V{ T{ live-range f 0 8 } T{ live-range f 10 18 } T{ live-range f 20 30 } } }
} 10 split-for-spill
] unit-test
! Multiple representations
[
T{ live-interval
{ vreg 5 }
{ reg-class float-regs }
{ start 0 }
{ end 11 }
{ uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 10 double-rep float-rep } } }
{ ranges V{ T{ live-range f 0 11 } } }
{ spill-to T{ spill-slot f 16 } }
{ spill-rep double-rep }
}
T{ live-interval
{ vreg 5 }
{ reg-class float-regs }
{ start 20 }
{ end 20 }
{ uses V{ T{ vreg-use f 20 f double-rep } } }
{ ranges V{ T{ live-range f 20 20 } } }
{ reload-from T{ spill-slot f 16 } }
{ reload-rep double-rep }
}
] [
T{ live-interval
{ vreg 5 }
{ reg-class float-regs }
{ start 0 }
{ end 20 }
{ uses V{ T{ vreg-use f 0 float-rep f } T{ vreg-use f 10 double-rep float-rep } T{ vreg-use f 20 f double-rep } } }
{ ranges V{ T{ live-range f 0 20 } } }
} 15 split-for-spill
] unit-test
H{
{ 1 int-rep }
{ 2 int-rep }
@ -196,7 +257,7 @@ H{
{ reg 1 }
{ start 1 }
{ end 15 }
{ uses V{ T{ vreg-use f int-rep 1 } T{ vreg-use f int-rep 3 } T{ vreg-use f int-rep 7 } T{ vreg-use f int-rep 10 } T{ vreg-use f int-rep 15 } } }
{ uses V{ T{ vreg-use f 1 int-rep f } T{ vreg-use f 3 f int-rep } T{ vreg-use f 7 f int-rep } T{ vreg-use f 10 f int-rep } T{ vreg-use f 15 f int-rep } } }
}
T{ live-interval
{ vreg 2 }
@ -204,7 +265,7 @@ H{
{ reg 2 }
{ start 3 }
{ end 8 }
{ uses V{ T{ vreg-use f int-rep 3 } T{ vreg-use f int-rep 4 } T{ vreg-use f int-rep 8 } } }
{ uses V{ T{ vreg-use f 3 int-rep f } T{ vreg-use f 4 f int-rep } T{ vreg-use f 8 f int-rep } } }
}
T{ live-interval
{ vreg 3 }
@ -212,7 +273,7 @@ H{
{ reg 3 }
{ start 3 }
{ end 10 }
{ uses V{ T{ vreg-use f int-rep 3 } T{ vreg-use f int-rep 10 } } }
{ uses V{ T{ vreg-use f 3 int-rep f } T{ vreg-use f 10 f int-rep } } }
}
}
}
@ -223,7 +284,7 @@ H{
{ reg-class int-regs }
{ start 5 }
{ end 5 }
{ uses V{ T{ vreg-use f int-rep 5 } } }
{ uses V{ T{ vreg-use f 5 int-rep f } } }
}
spill-status
] unit-test
@ -243,7 +304,7 @@ H{
{ reg 1 }
{ start 1 }
{ end 15 }
{ uses V{ T{ vreg-use f int-rep 1 } } }
{ uses V{ T{ vreg-use f 1 int-rep f } } }
}
T{ live-interval
{ vreg 2 }
@ -251,7 +312,7 @@ H{
{ reg 2 }
{ start 3 }
{ end 8 }
{ uses V{ T{ vreg-use f int-rep 3 } T{ vreg-use f int-rep 8 } } }
{ uses V{ T{ vreg-use f 3 int-rep f } T{ vreg-use f 8 f int-rep } } }
}
}
}
@ -262,7 +323,7 @@ H{
{ reg-class int-regs }
{ start 5 }
{ end 5 }
{ uses V{ T{ vreg-use f int-rep 5 } } }
{ uses V{ T{ vreg-use f 5 int-rep f } } }
}
spill-status
] unit-test
@ -276,7 +337,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set
{ reg-class int-regs }
{ start 0 }
{ end 100 }
{ uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 100 } } }
{ uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 100 f int-rep } } }
{ ranges V{ T{ live-range f 0 100 } } }
}
}
@ -291,7 +352,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set
{ reg-class int-regs }
{ start 0 }
{ end 10 }
{ uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 10 } } }
{ uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 10 f int-rep } } }
{ ranges V{ T{ live-range f 0 10 } } }
}
T{ live-interval
@ -299,7 +360,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set
{ reg-class int-regs }
{ start 11 }
{ end 20 }
{ uses V{ T{ vreg-use f int-rep 11 } T{ vreg-use f int-rep 20 } } }
{ uses V{ T{ vreg-use f 11 int-rep f } T{ vreg-use f 20 f int-rep } } }
{ ranges V{ T{ live-range f 11 20 } } }
}
}
@ -314,7 +375,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set
{ reg-class int-regs }
{ start 0 }
{ end 100 }
{ uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 100 } } }
{ uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 100 f int-rep } } }
{ ranges V{ T{ live-range f 0 100 } } }
}
T{ live-interval
@ -322,7 +383,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set
{ reg-class int-regs }
{ start 30 }
{ end 60 }
{ uses V{ T{ vreg-use f int-rep 30 } T{ vreg-use f int-rep 60 } } }
{ uses V{ T{ vreg-use f 30 int-rep f } T{ vreg-use f 60 f int-rep } } }
{ ranges V{ T{ live-range f 30 60 } } }
}
}
@ -337,7 +398,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set
{ reg-class int-regs }
{ start 0 }
{ end 100 }
{ uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 100 } } }
{ uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 100 f int-rep } } }
{ ranges V{ T{ live-range f 0 100 } } }
}
T{ live-interval
@ -345,7 +406,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set
{ reg-class int-regs }
{ start 30 }
{ end 200 }
{ uses V{ T{ vreg-use f int-rep 30 } T{ vreg-use f int-rep 200 } } }
{ uses V{ T{ vreg-use f 30 int-rep f } T{ vreg-use f 200 f int-rep } } }
{ ranges V{ T{ live-range f 30 200 } } }
}
}
@ -360,7 +421,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set
{ reg-class int-regs }
{ start 0 }
{ end 100 }
{ uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 100 } } }
{ uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 100 f int-rep } } }
{ ranges V{ T{ live-range f 0 100 } } }
}
T{ live-interval
@ -368,7 +429,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set
{ reg-class int-regs }
{ start 30 }
{ end 100 }
{ uses V{ T{ vreg-use f int-rep 30 } T{ vreg-use f int-rep 100 } } }
{ uses V{ T{ vreg-use f 30 int-rep f } T{ vreg-use f 100 f int-rep } } }
{ ranges V{ T{ live-range f 30 100 } } }
}
}
@ -392,7 +453,7 @@ H{
{ reg-class int-regs }
{ start 0 }
{ end 20 }
{ uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 10 } T{ vreg-use f int-rep 20 } } }
{ uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 10 f int-rep } T{ vreg-use f 20 f int-rep } } }
{ ranges V{ T{ live-range f 0 2 } T{ live-range f 10 20 } } }
}
T{ live-interval
@ -400,7 +461,7 @@ H{
{ reg-class int-regs }
{ start 0 }
{ end 20 }
{ uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 10 } T{ vreg-use f int-rep 20 } } }
{ uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 10 f int-rep } T{ vreg-use f 20 f int-rep } } }
{ ranges V{ T{ live-range f 0 2 } T{ live-range f 10 20 } } }
}
T{ live-interval
@ -408,7 +469,7 @@ H{
{ reg-class int-regs }
{ start 4 }
{ end 8 }
{ uses V{ T{ vreg-use f int-rep 6 } } }
{ uses V{ T{ vreg-use f 6 int-rep f } } }
{ ranges V{ T{ live-range f 4 8 } } }
}
T{ live-interval
@ -416,7 +477,7 @@ H{
{ reg-class int-regs }
{ start 4 }
{ end 8 }
{ uses V{ T{ vreg-use f int-rep 8 } } }
{ uses V{ T{ vreg-use f 8 int-rep f } } }
{ ranges V{ T{ live-range f 4 8 } } }
}
@ -426,7 +487,7 @@ H{
{ reg-class int-regs }
{ start 4 }
{ end 8 }
{ uses V{ T{ vreg-use f int-rep 8 } } }
{ uses V{ T{ vreg-use f 8 int-rep f } } }
{ ranges V{ T{ live-range f 4 8 } } }
}
}
@ -443,7 +504,7 @@ H{
{ reg-class int-regs }
{ start 0 }
{ end 10 }
{ uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 6 } T{ vreg-use f int-rep 10 } } }
{ uses V{ T{ vreg-use f 0 int-rep f } T{ vreg-use f 6 f int-rep } T{ vreg-use f 10 f int-rep } } }
{ ranges V{ T{ live-range f 0 10 } } }
}
@ -453,7 +514,7 @@ H{
{ reg-class int-regs }
{ start 2 }
{ end 8 }
{ uses V{ T{ vreg-use f int-rep 8 } } }
{ uses V{ T{ vreg-use f 8 int-rep f } } }
{ ranges V{ T{ live-range f 2 8 } } }
}
}
@ -595,7 +656,7 @@ H{
{ start 8 }
{ end 10 }
{ ranges V{ T{ live-range f 8 10 } } }
{ uses V{ T{ vreg-use f int-rep 8 } T{ vreg-use f int-rep 10 } } }
{ uses V{ T{ vreg-use f 8 int-rep f } T{ vreg-use f 10 f int-rep } } }
}
register-status
] unit-test

View File

@ -16,15 +16,13 @@ TUPLE: live-range from to ;
C: <live-range> live-range
SYMBOLS: +def+ +use+ +memory+ ;
TUPLE: vreg-use n def-rep use-rep ;
TUPLE: vreg-use rep n type ;
C: <vreg-use> vreg-use
: <vreg-use> ( n -- vreg-use ) vreg-use new swap >>n ;
TUPLE: live-interval
vreg
reg spill-to reload-from
reg spill-to spill-rep reload-from reload-rep
start end ranges uses
reg-class ;
@ -32,6 +30,15 @@ reg-class ;
: last-use ( live-interval -- use ) uses>> last ; inline
: new-use ( insn# uses -- use )
[ <vreg-use> dup ] dip push ;
: last-use? ( insn# uses -- use/f )
[ drop f ] [ last [ n>> = ] keep and ] if-empty ;
: (add-use) ( insn# live-interval -- use )
uses>> 2dup last-use? dup [ 2nip ] [ drop new-use ] if ;
GENERIC: covers? ( insn# obj -- ? )
M: f covers? 2drop f ;
@ -67,12 +74,6 @@ M: live-interval covers? ( insn# live-interval -- ? )
2dup extend-range?
[ extend-range ] [ add-new-range ] if ;
:: add-use ( rep n type live-interval -- )
type +memory+ eq? [
rep n type <vreg-use>
live-interval uses>> push
] unless ;
: <live-interval> ( vreg reg-class -- live-interval )
\ live-interval new
V{ } clone >>uses
@ -97,40 +98,30 @@ GENERIC: compute-live-intervals* ( insn -- )
M: insn compute-live-intervals* drop ;
:: record-def ( vreg n type -- )
vreg rep-of :> rep
:: record-def ( vreg n -- )
vreg live-interval :> live-interval
n live-interval shorten-range
rep n type live-interval add-use ;
n live-interval (add-use) vreg rep-of >>def-rep drop ;
:: record-use ( vreg n type -- )
vreg rep-of :> rep
:: record-use ( vreg n -- )
vreg live-interval :> live-interval
from get n live-interval add-range
rep n type live-interval add-use ;
n live-interval (add-use) vreg rep-of >>use-rep drop ;
:: record-temp ( vreg n -- )
vreg rep-of :> rep
vreg live-interval :> live-interval
n n live-interval add-range
rep n +def+ live-interval add-use ;
n live-interval (add-use) vreg rep-of >>def-rep drop ;
M:: vreg-insn compute-live-intervals* ( insn -- )
insn insn#>> :> n
insn defs-vreg [ n +def+ record-def ] when*
insn uses-vregs [ n +use+ record-use ] each
insn temp-vregs [ n record-temp ] each ;
M:: clobber-insn compute-live-intervals* ( insn -- )
insn insn#>> :> n
insn defs-vreg [ n +use+ record-def ] when*
insn uses-vregs [ n +memory+ record-use ] each
insn temp-vregs [ n record-temp ] each ;
M: vreg-insn compute-live-intervals* ( insn -- )
dup insn#>>
[ [ defs-vreg ] dip '[ _ record-def ] when* ]
[ [ uses-vregs ] dip '[ _ record-use ] each ]
[ [ temp-vregs ] dip '[ _ record-temp ] each ]
2tri ;
: handle-live-out ( bb -- )
live-out dup assoc-empty? [ drop ] [