From 982e704626a9597f78277de134ea38281e71f9b0 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 7 May 2010 18:22:35 -0400 Subject: [PATCH] compiler.cfg.linear-scan: clean up clobber-insn handling --- .../linear-scan/allocation/allocation.factor | 7 +- .../allocation/spilling/spilling.factor | 22 ++- .../allocation/splitting/splitting.factor | 7 +- .../linear-scan/assignment/assignment.factor | 14 +- .../cfg/linear-scan/linear-scan-tests.factor | 143 +++++++++++++----- .../live-intervals/live-intervals.factor | 55 +++---- 6 files changed, 153 insertions(+), 95 deletions(-) diff --git a/basis/compiler/cfg/linear-scan/allocation/allocation.factor b/basis/compiler/cfg/linear-scan/allocation/allocation.factor index ed7690bd77..c1b3f04ff4 100644 --- a/basis/compiler/cfg/linear-scan/allocation/allocation.factor +++ b/basis/compiler/cfg/linear-scan/allocation/allocation.factor @@ -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 -- ) diff --git a/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor index 3ab4005359..be5ab9d481 100644 --- a/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor +++ b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor @@ -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, diff --git a/basis/compiler/cfg/linear-scan/allocation/splitting/splitting.factor b/basis/compiler/cfg/linear-scan/allocation/splitting/splitting.factor index d41a06806b..6346ea41f5 100644 --- a/basis/compiler/cfg/linear-scan/allocation/splitting/splitting.factor +++ b/basis/compiler/cfg/linear-scan/allocation/splitting/splitting.factor @@ -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 ; diff --git a/basis/compiler/cfg/linear-scan/assignment/assignment.factor b/basis/compiler/cfg/linear-scan/assignment/assignment.factor index 1682cf9eb6..1780a1c907 100644 --- a/basis/compiler/cfg/linear-scan/assignment/assignment.factor +++ b/basis/compiler/cfg/linear-scan/assignment/assignment.factor @@ -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 ; diff --git a/basis/compiler/cfg/linear-scan/linear-scan-tests.factor b/basis/compiler/cfg/linear-scan/linear-scan-tests.factor index 9e6ec76d2c..11e190d226 100644 --- a/basis/compiler/cfg/linear-scan/linear-scan-tests.factor +++ b/basis/compiler/cfg/linear-scan/linear-scan-tests.factor @@ -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 diff --git a/basis/compiler/cfg/linear-scan/live-intervals/live-intervals.factor b/basis/compiler/cfg/linear-scan/live-intervals/live-intervals.factor index c4b255d12a..50efbd43e4 100644 --- a/basis/compiler/cfg/linear-scan/live-intervals/live-intervals.factor +++ b/basis/compiler/cfg/linear-scan/live-intervals/live-intervals.factor @@ -16,15 +16,13 @@ TUPLE: live-range from to ; C: live-range -SYMBOLS: +def+ +use+ +memory+ ; +TUPLE: vreg-use n def-rep use-rep ; -TUPLE: vreg-use rep n type ; - -C: 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 ) + [ 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 - live-interval uses>> push - ] unless ; - : ( 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 ] [