]> gitweb.factorcode.org Git - factor.git/commitdiff
compiler.cfg.linear-scan: clean up clobber-insn handling
authorSlava Pestov <slava@factorcode.org>
Fri, 7 May 2010 22:22:35 +0000 (18:22 -0400)
committerSlava Pestov <slava@factorcode.org>
Fri, 7 May 2010 22:22:35 +0000 (18:22 -0400)
basis/compiler/cfg/linear-scan/allocation/allocation.factor
basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor
basis/compiler/cfg/linear-scan/allocation/splitting/splitting.factor
basis/compiler/cfg/linear-scan/assignment/assignment.factor
basis/compiler/cfg/linear-scan/linear-scan-tests.factor
basis/compiler/cfg/linear-scan/live-intervals/live-intervals.factor

index ed7690bd773170cf54dbf6557176af23feec3a7b..c1b3f04ff451fe6b81a78e7f31bb923159824c44 100644 (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 -- )
index 3ab400535980bfed73c9ff68fa6e0394e963b47b..be5ab9d48169da77bbe2ff97d12dca320206982a 100644 (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,
index d41a06806b33db11ccccb13f1ac5d140b87ebbe4..6346ea41f513047bdfd490a0b8912ef4b4cbfb38 100644 (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 ;
 
index 1682cf9eb630a7ee856c86005a657cdf78cee04b..1780a1c907793d46a857ab3e21c9f6107253d052 100644 (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 ;
index 9e6ec76d2ca7d1538dc4175f99d613e24dc74c5f..11e190d22663422c881b95319a4ac46c4607552d 100644 (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
index c4b255d12a9068eeb5cae00ec0255673312267aa..50efbd43e43cb1035bf124e2036a47b32a1a3779 100644 (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 ;
-
-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 ;
+    n live-interval (add-use) vreg rep-of >>def-rep drop ;
+
+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 ] [