From 8c781639ed478a63260ce93d745607baae9cef61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lindqvist?= Date: Tue, 15 Sep 2015 02:42:21 +0200 Subject: [PATCH] compiler.cfg.linear-scan.ranges: move more range-related features into this vocab --- .../allocation/spilling/spilling-docs.factor | 4 ++ .../allocation/spilling/spilling-tests.factor | 61 +++++++++++++++++++ .../allocation/spilling/spilling.factor | 13 +--- .../linear-scan/ranges/ranges-tests.factor | 44 +++++++++++++ .../cfg/linear-scan/ranges/ranges.factor | 16 +++-- 5 files changed, 124 insertions(+), 14 deletions(-) diff --git a/basis/compiler/cfg/linear-scan/allocation/spilling/spilling-docs.factor b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling-docs.factor index 93ffe0f37b..8defbc649d 100644 --- a/basis/compiler/cfg/linear-scan/allocation/spilling/spilling-docs.factor +++ b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling-docs.factor @@ -48,6 +48,10 @@ HELP: spill-partially-available } { $description "A register would be available for part of the new interval's lifetime if all active and inactive intervals using that register were split and spilled." } ; +HELP: trim-before-ranges +{ $values { "live-interval" live-interval } } +{ $description "Extends the last intervals range to one after the last use point and removes all intervals beyond that." } ; + ARTICLE: "compiler.cfg.linear-scan.allocation.spilling" "Spill slot assignment" "Words and dynamic variables for assigning spill slots to spilled registers during the " { $link linear-scan } " compiler pass." ; diff --git a/basis/compiler/cfg/linear-scan/allocation/spilling/spilling-tests.factor b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling-tests.factor index d04556abf6..d736d717c9 100644 --- a/basis/compiler/cfg/linear-scan/allocation/spilling/spilling-tests.factor +++ b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling-tests.factor @@ -49,3 +49,64 @@ IN: compiler.cfg.linear-scan.allocation.spilling.tests { double-rep } [ test-live-interval last-use-rep ] unit-test + +! trim-after-ranges +{ + T{ live-interval-state + { ranges + { + T{ live-range { from 25 } { to 30 } } + T{ live-range { from 40 } { to 50 } } + } + } + { uses { T{ vreg-use { n 25 } } } } + } +} [ + T{ live-interval-state + { ranges + { + T{ live-range { from 0 } { to 10 } } + T{ live-range { from 20 } { to 30 } } + T{ live-range { from 40 } { to 50 } } + } + } + { uses { T{ vreg-use { n 25 } } } } + } dup trim-after-ranges +] unit-test + +{ + T{ live-interval-state + { ranges { T{ live-range { from 10 } { to 23 } } } } + { uses { T{ vreg-use { n 10 } } } } + } +} [ + T{ live-interval-state + { ranges { T{ live-range { from 20 } { to 23 } } } } + { uses { T{ vreg-use { n 10 } } } } + } + dup trim-after-ranges +] unit-test + +! trim-before-ranges +{ + T{ live-interval-state + { ranges + { + T{ live-range { from 0 } { to 10 } } + T{ live-range { from 20 } { to 21 } } + } + } + { uses { T{ vreg-use { n 20 } } } } + } +} [ + T{ live-interval-state + { ranges + { + T{ live-range { from 0 } { to 10 } } + T{ live-range { from 20 } { to 30 } } + T{ live-range { from 40 } { to 50 } } + } + } + { uses { T{ vreg-use { n 20 } } } } + } dup trim-before-ranges +] unit-test diff --git a/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor index 54a9d6f028..fe1e775d16 100644 --- a/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor +++ b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor @@ -9,16 +9,10 @@ math namespaces sequences ; IN: compiler.cfg.linear-scan.allocation.spilling : trim-before-ranges ( live-interval -- ) - dup last-use n>> 1 + - [ '[ [ from>> _ >= ] trim-tail-slice ] change-ranges drop ] - [ swap ranges>> last to<< ] - 2bi ; + dup last-use n>> 1 + swap [ fix-upper-bound ] change-ranges drop ; : trim-after-ranges ( live-interval -- ) - dup first-use n>> - [ '[ [ to>> _ < ] trim-head-slice ] change-ranges drop ] - [ swap ranges>> first from<< ] - 2bi ; + dup first-use n>> swap [ fix-lower-bound ] change-ranges drop ; : last-use-rep ( live-interval -- rep/f ) last-use [ def-rep>> ] [ use-rep>> ] bi or ; inline @@ -34,8 +28,7 @@ ERROR: bad-live-ranges interval ; : check-ranges ( ranges -- ) check-allocation? get [ - ranges>> dup [ [ from>> ] [ to>> ] bi <= ] all? - [ drop ] [ bad-live-ranges ] if + dup ranges>> valid-ranges? [ drop ] [ bad-live-ranges ] if ] [ drop ] if ; : spill-before ( before -- before/f ) diff --git a/basis/compiler/cfg/linear-scan/ranges/ranges-tests.factor b/basis/compiler/cfg/linear-scan/ranges/ranges-tests.factor index 81710da12f..7284ccfec4 100644 --- a/basis/compiler/cfg/linear-scan/ranges/ranges-tests.factor +++ b/basis/compiler/cfg/linear-scan/ranges/ranges-tests.factor @@ -154,3 +154,47 @@ IN: compiler.cfg.linear-scan.ranges.tests [ { T{ live-range f 1 10 } } 0 split-ranges ] must-fail + +! valid-ranges? +{ t f f f } [ + { T{ live-range f 1 10 } T{ live-range f 15 20 } } valid-ranges? + { T{ live-range f 10 1 } T{ live-range f 15 20 } } valid-ranges? + { T{ live-range f 1 5 } T{ live-range f 3 10 } } valid-ranges? + { T{ live-range f 5 1 } } valid-ranges? +] unit-test + +! fix-lower-bound +{ + { + T{ live-range { from 25 } { to 30 } } + T{ live-range { from 40 } { to 50 } } + } + { T{ live-range { from 10 } { to 23 } } } +} [ + 25 { + T{ live-range { from 0 } { to 10 } } + T{ live-range { from 20 } { to 30 } } + T{ live-range { from 40 } { to 50 } } + } fix-lower-bound + 10 { T{ live-range { from 20 } { to 23 } } } fix-lower-bound +] unit-test + +! fix-upper-bound +{ + { + T{ live-range { from 0 } { to 10 } } + T{ live-range { from 20 } { to 20 } } + } +} [ + 20 { + T{ live-range { from 0 } { to 10 } } + T{ live-range { from 20 } { to 30 } } + T{ live-range { from 40 } { to 50 } } + } fix-upper-bound +] unit-test + +{ + { T{ live-range { from 0 } { to 20 } } } +} [ + 20 { T{ live-range { from 0 } { to 40 } } } fix-upper-bound +] unit-test diff --git a/basis/compiler/cfg/linear-scan/ranges/ranges.factor b/basis/compiler/cfg/linear-scan/ranges/ranges.factor index 0e349e8db7..f10f21d78f 100644 --- a/basis/compiler/cfg/linear-scan/ranges/ranges.factor +++ b/basis/compiler/cfg/linear-scan/ranges/ranges.factor @@ -1,5 +1,4 @@ -USING: accessors compiler.cfg.linear-scan.allocation.state fry kernel -math math.order namespaces sequences ; +USING: accessors arrays fry grouping kernel math math.order sequences ; IN: compiler.cfg.linear-scan.ranges ! Data definitions @@ -17,8 +16,7 @@ C: live-range [ from>> ] [ to>> ] bi between? ; : split-range ( live-range n -- before after ) - [ [ from>> ] dip ] - [ 1 + swap to>> ] 2bi ; + [ [ from>> ] dip ] [ 1 + swap to>> ] 2bi ; ! Range sequence utilities : extend-ranges? ( n ranges -- ? ) @@ -54,3 +52,13 @@ C: live-range [ over last ] dip 2dup split-last-range? [ split-last-range ] [ 2drop ] if ] bi ; + +: valid-ranges? ( ranges -- ? ) + [ [ [ from>> ] [ to>> ] bi <= ] all? ] + [ [ [ to>> ] [ from>> ] bi* <= ] monotonic? ] bi and ; + +: fix-lower-bound ( n ranges -- ranges' ) + over '[ to>> _ >= ] filter [ first from<< ] keep ; + +: fix-upper-bound ( n ranges -- ranges' ) + over '[ from>> _ <= ] filter [ last to<< ] keep ;