]> gitweb.factorcode.org Git - factor.git/commitdiff
compiler.cfg.linear-scan.ranges: new vocab to contain all the range
authorBjörn Lindqvist <bjourne@gmail.com>
Sun, 13 Sep 2015 16:02:01 +0000 (18:02 +0200)
committerBjörn Lindqvist <bjourne@gmail.com>
Tue, 22 Sep 2015 06:51:03 +0000 (08:51 +0200)
related stuff from live intervals

basis/compiler/cfg/linear-scan/allocation/allocation-tests.factor
basis/compiler/cfg/linear-scan/allocation/spilling/spilling-tests.factor
basis/compiler/cfg/linear-scan/allocation/splitting/splitting-tests.factor
basis/compiler/cfg/linear-scan/allocation/splitting/splitting.factor
basis/compiler/cfg/linear-scan/linear-scan-tests.factor
basis/compiler/cfg/linear-scan/live-intervals/live-intervals-docs.factor
basis/compiler/cfg/linear-scan/live-intervals/live-intervals-tests.factor
basis/compiler/cfg/linear-scan/live-intervals/live-intervals.factor
basis/compiler/cfg/linear-scan/ranges/ranges-docs.factor [new file with mode: 0644]
basis/compiler/cfg/linear-scan/ranges/ranges-tests.factor [new file with mode: 0644]
basis/compiler/cfg/linear-scan/ranges/ranges.factor [new file with mode: 0644]

index 08aaad1de66d1274081fe21904be3a3acd6f194d..cf63d4a857f8ddd8fbbef0851166cddb49ca9d07 100644 (file)
@@ -1,7 +1,8 @@
 USING: accessors compiler.cfg compiler.cfg.linear-scan.allocation
 compiler.cfg.linear-scan.allocation.state
-compiler.cfg.linear-scan.live-intervals cpu.architecture
-cpu.x86.assembler.operands heaps kernel namespaces system tools.test ;
+compiler.cfg.linear-scan.live-intervals compiler.cfg.linear-scan.ranges
+cpu.architecture cpu.x86.assembler.operands heaps kernel namespaces system
+tools.test ;
 IN: compiler.cfg.linear-scan.allocation.tests
 
 : interval-[30,46] ( -- live-interval )
index 98c7488347c61e1836424ce0d2b20b6f7de09907..d04556abf6633f9093612ea4151d0223059b0d0b 100644 (file)
@@ -1,8 +1,9 @@
 USING: assocs compiler.cfg compiler.cfg.instructions
 compiler.cfg.linear-scan.allocation.spilling
 compiler.cfg.linear-scan.allocation.state
-compiler.cfg.linear-scan.live-intervals compiler.cfg.registers cpu.architecture
-kernel namespaces sequences tools.test ;
+compiler.cfg.linear-scan.live-intervals compiler.cfg.linear-scan.ranges
+compiler.cfg.registers cpu.architecture kernel namespaces sequences
+tools.test ;
 IN: compiler.cfg.linear-scan.allocation.spilling.tests
 
 : test-live-interval ( -- live-interval )
index 9faec79d81ad176a0506bc09fecab008ff82675b..9d06ce4b52aa93f8a39fc335aa0ea5168fddebed 100644 (file)
@@ -1,5 +1,6 @@
 USING: compiler.cfg.instructions compiler.cfg.linear-scan.allocation.splitting
-compiler.cfg.linear-scan.live-intervals cpu.architecture sequences tools.test ;
+compiler.cfg.linear-scan.live-intervals compiler.cfg.linear-scan.ranges
+cpu.architecture sequences tools.test ;
 IN: compiler.cfg.linear-scan.allocation.splitting.tests
 
 : test-interval-easy ( -- interval )
index 6db04c7d84b783cbc632771015310e4abec7b229..a0380845512a78ccbe302a6d36bd123eb556fe20 100644 (file)
@@ -2,8 +2,9 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors binary-search combinators
 compiler.cfg.linear-scan.allocation.state
-compiler.cfg.linear-scan.live-intervals fry hints kernel locals
-math math.order namespaces sequences ;
+compiler.cfg.linear-scan.live-intervals
+compiler.cfg.linear-scan.ranges fry hints kernel locals math math.order
+namespaces sequences ;
 IN: compiler.cfg.linear-scan.allocation.splitting
 
 : split-range ( live-range n -- before after )
index e49e5e14350f08f4e6f8e5b18f51d0583e2014ec..6a228b286f469c8704ad87533c73fff4122d0c9f 100644 (file)
@@ -13,12 +13,13 @@ compiler.cfg.def-use
 compiler.cfg.comparisons
 compiler.cfg.ssa.destruction.leaders
 compiler.cfg.linear-scan
-compiler.cfg.linear-scan.numbering
-compiler.cfg.linear-scan.live-intervals
 compiler.cfg.linear-scan.allocation
 compiler.cfg.linear-scan.allocation.state
 compiler.cfg.linear-scan.allocation.splitting
 compiler.cfg.linear-scan.allocation.spilling
+compiler.cfg.linear-scan.live-intervals
+compiler.cfg.linear-scan.numbering
+compiler.cfg.linear-scan.ranges
 compiler.cfg.linear-scan.debugger
 compiler.cfg.utilities ;
 IN: compiler.cfg.linear-scan.tests
index e08971234e7648524105dbe5fbf9dee6366779ef..fec1b8f307dd31cbc480d27799b4e8393c923ce0 100644 (file)
@@ -1,6 +1,6 @@
 USING: compiler.cfg compiler.cfg.instructions
 compiler.cfg.linear-scan.allocation cpu.architecture help.markup help.syntax
-math sequences ;
+kernel math sequences ;
 IN: compiler.cfg.linear-scan.live-intervals
 
 HELP: <live-interval>
@@ -15,11 +15,20 @@ HELP: block-from
 { $values { "bb" basic-block } { "n" integer } }
 { $description "The instruction number immediately preceeding this block." } ;
 
+HELP: cfg>live-intervals
+{ $values { "cfg" cfg } { "live-intervals" sequence } }
+{ $description "The cfg is traversed in reverse linearization order." } ;
+
 HELP: cfg>sync-points
 { $values { "cfg" cfg } { "sync-points" sequence } }
 { $description "Creates a sequence of all sync points in the cfg." }
 { $see-also sync-point } ;
 
+HELP: compute-live-intervals
+{ $values { "cfg" cfg } { "intervals/sync-points" sequence } }
+{ $description "Computes the live intervals and sync points of a cfg." }
+{ $notes "The instructions must be numbered." } ;
+
 HELP: finish-live-intervals
 { $values { "live-intervals" sequence } }
 { $description "Since live intervals are computed in a backward order, we have to reverse some sequences, and compute the start and end." } ;
@@ -27,6 +36,10 @@ HELP: finish-live-intervals
 HELP: from
 { $var-description "An integer representing a sequence number one lower than all numbers in the currently processed block." } ;
 
+HELP: intervals-intersect?
+{ $values { "interval1" live-interval } { "interval2" live-interval } { "?" boolean } }
+{ $description "Checks if two live intervals intersect each other." } ;
+
 HELP: live-interval-state
 { $class-description "A class encoding the \"liveness\" of a virtual register. It has the following slots:"
   { $table
@@ -50,7 +63,7 @@ HELP: live-interval-state
         { "Inclusive ranges where the live interval is live. This is because the [start,end] interval can have gaps." }
     }
     {
-        { $slot "uses" } { "sequence of references to instructions that use the register in the live interval." }
+        { $slot "uses" } { "sequence of insn# numbers which reference insructions that use the register in the live interval." }
     }
     {
         { $slot "reg-class" }
@@ -62,13 +75,9 @@ HELP: live-interval-state
 }
 { $notes "The " { $slot "uses" } " and " { $slot "ranges" } " will never be empty because then the interval would be unused." } ;
 
-
 HELP: live-intervals
 { $var-description "Mapping from vreg to " { $link live-interval-state } "." } ;
 
-HELP: live-range
-{ $class-description "Represents a range in the " { $link cfg } " in which a vreg is live." } ;
-
 HELP: sync-point
 { $class-description "A location where all registers have to be spilled. For example when garbage collection is run or an alien ffi call is invoked. Figuring out where in the " { $link cfg } " the sync points are is done in the " { $link compute-live-intervals } " step. The tuple has the following slots:"
   { $table
@@ -84,12 +93,7 @@ ARTICLE: "compiler.cfg.linear-scan.live-intervals" "Live interval utilities"
 "This vocab contains words for managing live intervals."
 $nl
 "Liveness classes and constructors:"
-{ $subsections
-  <live-interval>
-  <live-range>
-  live-interval
-  live-range
-} ;
+{ $subsections <live-interval> live-interval } ;
 
 
 ABOUT: "compiler.cfg.linear-scan.live-intervals"
index 2ddaf6c07dba8fbc00ff7cc6c8c6fdf31b337182..fff12ed883977b7f4596d2cfae4871a8f724229a 100644 (file)
@@ -1,35 +1,14 @@
-USING: arrays compiler.cfg compiler.cfg.instructions
+USING: accessors arrays compiler.cfg compiler.cfg.instructions
 compiler.cfg.linear-scan.live-intervals
-compiler.cfg.linear-scan.numbering compiler.cfg.liveness
-compiler.cfg.registers compiler.cfg.ssa.destruction.leaders
-compiler.cfg.utilities cpu.architecture kernel namespaces sequences
-tools.test ;
+compiler.cfg.linear-scan.numbering compiler.cfg.linear-scan.ranges
+compiler.cfg.liveness compiler.cfg.registers
+compiler.cfg.ssa.destruction.leaders compiler.cfg.utilities cpu.architecture
+fry kernel namespaces sequences tools.test ;
 IN: compiler.cfg.linear-scan.live-intervals.tests
 
-! add-range
-{
-    T{ live-interval-state
-       { vreg 5 }
-       { ranges V{ T{ live-range { from 5 } { to 12 } } } }
-       { uses V{ } }
-       { reg-class int-rep }
-    }
-} [
-    5 int-rep <live-interval> dup
-    { { 5 10 } { 8 12 } } [ first2 rot add-range ] with each
-] unit-test
-
-{
-    T{ live-interval-state
-       { vreg 5 }
-       { ranges V{ T{ live-range { from 5 } { to 12 } } } }
-       { uses V{ } }
-       { reg-class int-rep }
-    }
-} [
-    5 int-rep <live-interval> dup
-    { { 10 12 } { 5 10 } } [ first2 rot add-range ] with each
-] unit-test
+: <live-interval-for-ranges> ( ranges -- live-interval )
+    10 int-rep <live-interval> [ '[ first2 _ ranges>> add-range ] each ] keep
+    dup compute-start/end ;
 
 ! cfg>sync-points
 {
@@ -39,6 +18,16 @@ IN: compiler.cfg.linear-scan.live-intervals.tests
     [ number-instructions ] [ cfg>sync-points ] bi
 ] unit-test
 
+! intervals-intersect?
+{ t f f } [
+    { { 4 20 } } <live-interval-for-ranges>
+    { { 8 12 } } <live-interval-for-ranges> intervals-intersect?
+    { { 9 20 } { 3 5 } } <live-interval-for-ranges>
+    { { 0 1 } { 7 8 } } <live-interval-for-ranges> intervals-intersect?
+    { { 3 5 } } <live-interval-for-ranges>
+    { { 7 8 } } <live-interval-for-ranges> intervals-intersect?
+] unit-test
+
 ! handle-live-out
 { } [
     H{ } clone live-outs set
index f7f54cde10b173574eb82dc87604b403312a70b4..c4297b6c1e73a0fb70e3da1297c845efe2e48339 100644 (file)
@@ -2,24 +2,21 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs binary-search combinators
 compiler.cfg.def-use compiler.cfg.instructions
-compiler.cfg.linearization compiler.cfg.liveness
-compiler.cfg.registers compiler.cfg.ssa.destruction.leaders cpu.architecture
-fry kernel locals math math.intervals math.order namespaces sequences ;
+compiler.cfg.linear-scan.ranges compiler.cfg.linearization
+compiler.cfg.liveness compiler.cfg.registers
+compiler.cfg.ssa.destruction.leaders cpu.architecture fry kernel locals math
+math.intervals math.order namespaces sequences ;
 IN: compiler.cfg.linear-scan.live-intervals
 
-TUPLE: live-range from to ;
-
-C: <live-range> live-range
-
 TUPLE: vreg-use n def-rep use-rep spill-slot? ;
 
 : <vreg-use> ( n -- vreg-use ) vreg-use new swap >>n ;
 
 TUPLE: live-interval-state
-vreg
-reg spill-to spill-rep reload-from reload-rep
-start end ranges uses
-reg-class ;
+    vreg
+    reg spill-to spill-rep reload-from reload-rep
+    start end ranges uses
+    reg-class ;
 
 : first-use ( live-interval -- use ) uses>> first ; inline
 
@@ -36,20 +33,8 @@ reg-class ;
     insn# uses last-use? [ insn# uses new-use ] unless*
     spill-slot? [ t >>spill-slot? ] when ;
 
-GENERIC: covers? ( insn# obj -- ? )
-
-M: f covers? 2drop f ;
-
-M: live-range covers? [ from>> ] [ to>> ] bi between? ;
-
-M: live-interval-state covers? ( insn# live-interval -- ? )
-    ranges>>
-    dup length 4 <= [
-        [ covers? ] with any?
-    ] [
-        [ drop ] [ [ from>> <=> ] with search nip ] 2bi
-        covers?
-    ] if ;
+: covers? ( n live-interval -- ? )
+    ranges>> ranges-cover? ;
 
 : (find-use) ( insn# live-interval -- vreg-use )
     uses>> [ n>> <=> ] with search nip ;
@@ -58,26 +43,6 @@ M: live-interval-state covers? ( insn# live-interval -- ? )
     insn# live-interval (find-use)
     dup [ dup n>> insn# = [ drop f ] unless ] when ;
 
-: add-new-range ( from to live-interval -- )
-    [ <live-range> ] dip ranges>> push ;
-
-: shorten-range ( n live-interval -- )
-    dup ranges>> empty?
-    [ dupd add-new-range ] [ ranges>> last from<< ] if ;
-
-: extend-range ( from to live-range -- )
-    ranges>> last
-    [ max ] change-to
-    [ min ] change-from
-    drop ;
-
-: extend-range? ( to live-interval -- ? )
-    ranges>> [ drop f ] [ last from>> >= ] if-empty ;
-
-: add-range ( from to live-interval -- )
-    2dup extend-range?
-    [ extend-range ] [ add-new-range ] if ;
-
 : <live-interval> ( vreg reg-class -- live-interval )
     \ live-interval-state new
         V{ } clone >>uses
@@ -104,19 +69,19 @@ M: insn compute-live-intervals* drop ;
 :: record-def ( vreg n spill-slot? -- )
     vreg live-interval :> live-interval
 
-    n live-interval shorten-range
+    n live-interval ranges>> shorten-ranges
     n live-interval spill-slot? (add-use) vreg rep-of >>def-rep drop ;
 
 :: record-use ( vreg n spill-slot? -- )
     vreg live-interval :> live-interval
 
-    from get n live-interval add-range
+    from get n live-interval ranges>> add-range
     n live-interval spill-slot? (add-use) vreg rep-of >>use-rep drop ;
 
 :: record-temp ( vreg n -- )
     vreg live-interval :> live-interval
 
-    n n live-interval add-range
+    n n live-interval ranges>> add-range
     n live-interval f (add-use) vreg rep-of >>def-rep drop ;
 
 M: vreg-insn compute-live-intervals* ( insn -- )
@@ -155,7 +120,7 @@ M: hairy-clobber-insn compute-live-intervals* ( insn -- )
 
 : handle-live-out ( bb -- )
     [ from get to get ] dip live-out keys
-    [ live-interval add-range ] 2with each ;
+    [ live-interval ranges>> add-range ] 2with each ;
 
 : compute-live-intervals-step ( bb -- )
     {
diff --git a/basis/compiler/cfg/linear-scan/ranges/ranges-docs.factor b/basis/compiler/cfg/linear-scan/ranges/ranges-docs.factor
new file mode 100644 (file)
index 0000000..7afe8c6
--- /dev/null
@@ -0,0 +1,12 @@
+USING: compiler.cfg help.syntax help.markup ;
+IN: compiler.cfg.linear-scan.ranges
+
+HELP: live-range
+{ $class-description "Represents a range in the " { $link cfg } " in which a vreg is live." } ;
+
+ARTICLE: "compiler.cfg.linear-scan.ranges" "Live ranges utilities"
+"Utilities for dealing with the live range part of live intervals. A sequence of " { $link live-range } " tuples encodes where in the cfg a virtual register is live."
+$nl
+"Constructors:" { $subsections <live-range> live-range } ;
+
+ABOUT: "compiler.cfg.linear-scan.ranges"
diff --git a/basis/compiler/cfg/linear-scan/ranges/ranges-tests.factor b/basis/compiler/cfg/linear-scan/ranges/ranges-tests.factor
new file mode 100644 (file)
index 0000000..158a79a
--- /dev/null
@@ -0,0 +1,42 @@
+USING: compiler.cfg.linear-scan.ranges fry kernel sequences tools.test ;
+IN: compiler.cfg.linear-scan.ranges.tests
+
+: combine-ranges ( seq -- ranges )
+    V{ } clone [ '[ first2 _ add-range ] each ] keep ;
+
+! extend-ranges?
+{ f } [
+    10 { } extend-ranges?
+] unit-test
+
+! add-range
+{
+    V{ T{ live-range { from 5 } { to 12 } } }
+    V{ T{ live-range { from 5 } { to 12 } } }
+} [
+    { { 5 10 } { 8 12 } } combine-ranges
+    { { 10 12 } { 5 10 } } combine-ranges
+] unit-test
+
+! ranges-cover?
+{
+    t f f t t
+} [
+    115 { { 90 120 } { 40 50 } } combine-ranges ranges-cover?
+    50 { { 60 70 } { 20 30 } } combine-ranges ranges-cover?
+    120 { { 130 140 } { 70 80 } { 50 60 } { 44 48 } { 40 42 } }
+    combine-ranges ranges-cover?
+    135 { { 130 140 } { 70 80 } { 50 60 } { 44 48 } }
+    combine-ranges ranges-cover?
+    135 { { 130 140 } { 70 80 } { 50 60 } { 44 48 } { 40 42 } } reverse
+    combine-ranges ranges-cover?
+] unit-test
+
+! shorten-ranges
+{
+    V{ T{ live-range { from 8 } { to 12 } } }
+    V{ T{ live-range { from 9 } { to 9 } } }
+} [
+    8 { { 4 12 } } combine-ranges [ shorten-ranges ] keep
+    9 { } combine-ranges [ shorten-ranges ] keep
+] unit-test
diff --git a/basis/compiler/cfg/linear-scan/ranges/ranges.factor b/basis/compiler/cfg/linear-scan/ranges/ranges.factor
new file mode 100644 (file)
index 0000000..be5b953
--- /dev/null
@@ -0,0 +1,30 @@
+USING: accessors kernel math math.order sequences ;
+IN: compiler.cfg.linear-scan.ranges
+
+! Data definitions
+TUPLE: live-range from to ;
+
+C: <live-range> live-range
+
+! Range utilities
+: range-covers? ( n range -- ? )
+    [ from>> ] [ to>> ] bi between? ;
+
+! Range sequence utilities
+: extend-ranges? ( n ranges -- ? )
+    [ drop f ] [ last from>> >= ] if-empty ;
+
+: extend-ranges ( from to ranges -- )
+    last [ max ] change-to [ min ] change-from drop ;
+
+: add-new-range ( from to ranges -- )
+    [ <live-range> ] dip push ;
+
+: add-range ( from to ranges -- )
+    2dup extend-ranges? [ extend-ranges ] [ add-new-range ] if ;
+
+: ranges-cover? ( n ranges -- ? )
+    [ range-covers? ] with any? ;
+
+: shorten-ranges ( n ranges -- )
+    dup empty? [ dupd add-new-range ] [ last from<< ] if ;