diff --git a/basis/compiler/cfg/linear-scan/allocation/allocation.factor b/basis/compiler/cfg/linear-scan/allocation/allocation.factor index 8951d7a1f1..ae6c375016 100644 --- a/basis/compiler/cfg/linear-scan/allocation/allocation.factor +++ b/basis/compiler/cfg/linear-scan/allocation/allocation.factor @@ -1,4 +1,4 @@ -! Copyright (C) 2008, 2009 Slava Pestov. +! Copyright (C) 2008, 2010 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: accessors assocs heaps kernel namespaces sequences fry math math.order combinators arrays sorting compiler.utilities locals @@ -38,7 +38,8 @@ IN: compiler.cfg.linear-scan.allocation ! 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 swap member? [ 2drop t ] [ spill f ] if ; + 2dup [ uses>> ] dip '[ n>> _ = ] any? + [ 2drop t ] [ spill f ] if ; : handle-sync-point ( n -- ) [ active-intervals get values ] dip diff --git a/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor index 845cb14d5c..a914aab4bf 100644 --- a/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor +++ b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor @@ -1,4 +1,4 @@ -! Copyright (C) 2009 Slava Pestov. +! Copyright (C) 2009, 2010 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays assocs combinators fry hints kernel locals math sequences sets sorting splitting namespaces linked-assocs @@ -17,13 +17,13 @@ ERROR: bad-live-ranges interval ; ] [ drop ] if ; : trim-before-ranges ( live-interval -- ) - [ ranges>> ] [ uses>> last 1 + ] bi + [ ranges>> ] [ uses>> last n>> 1 + ] bi [ '[ from>> _ <= ] filter! drop ] [ swap last (>>to) ] 2bi ; : trim-after-ranges ( live-interval -- ) - [ ranges>> ] [ uses>> first ] bi + [ ranges>> ] [ uses>> first n>> ] bi [ '[ to>> _ >= ] filter! drop ] [ swap first (>>from) ] 2bi ; @@ -66,7 +66,8 @@ ERROR: bad-live-ranges interval ; split-interval [ spill-before ] [ spill-after ] bi* ; : find-use-position ( live-interval new -- n ) - [ uses>> ] [ start>> '[ _ >= ] ] bi* find nip 1/0. or ; + [ uses>> ] [ start>> '[ n>> _ >= ] ] bi* find nip + [ n>> ] [ 1/0. ] if* ; : find-use-positions ( live-intervals new assoc -- ) '[ [ _ find-use-position ] [ reg>> ] bi _ add-use-position ] each ; @@ -88,7 +89,7 @@ ERROR: bad-live-ranges interval ; >alist alist-max ; : spill-new? ( new pair -- ? ) - [ uses>> first ] [ second ] bi* > ; + [ uses>> first n>> ] [ second ] bi* > ; : spill-new ( new pair -- ) drop spill-after add-unhandled ; diff --git a/basis/compiler/cfg/linear-scan/allocation/splitting/splitting.factor b/basis/compiler/cfg/linear-scan/allocation/splitting/splitting.factor index 1a2b0f2f2b..b3cba3d90d 100644 --- a/basis/compiler/cfg/linear-scan/allocation/splitting/splitting.factor +++ b/basis/compiler/cfg/linear-scan/allocation/splitting/splitting.factor @@ -1,4 +1,4 @@ -! Copyright (C) 2009 Slava Pestov. +! Copyright (C) 2009, 2010 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays assocs combinators fry hints kernel locals math sequences sets sorting splitting namespaces @@ -25,7 +25,7 @@ IN: compiler.cfg.linear-scan.allocation.splitting ] bi ; : split-uses ( uses n -- before after ) - '[ _ <= ] partition ; + '[ n>> _ <= ] partition ; 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 c79aa36af1..535f4515eb 100644 --- a/basis/compiler/cfg/linear-scan/assignment/assignment.factor +++ b/basis/compiler/cfg/linear-scan/assignment/assignment.factor @@ -1,7 +1,7 @@ -! Copyright (C) 2008, 2009 Slava Pestov. +! Copyright (C) 2008, 2010 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: accessors kernel math assocs namespaces sequences heaps -fry make combinators sets locals arrays +fry make combinators combinators.short-circuit sets locals arrays cpu.architecture layouts compiler.cfg compiler.cfg.def-use @@ -91,8 +91,16 @@ SYMBOL: register-live-outs : insert-reload ( live-interval -- ) [ reg>> ] [ vreg>> rep-of ] [ 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>> ] + [ uses>> first type>> +use+ eq? ] + } 1&& ; + : handle-reload ( live-interval -- ) - dup reload-from>> [ insert-reload ] [ drop ] if ; + dup insert-reload? [ 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 b3fca6bab7..570c7f9aa7 100644 --- a/basis/compiler/cfg/linear-scan/linear-scan-tests.factor +++ b/basis/compiler/cfg/linear-scan/linear-scan-tests.factor @@ -91,7 +91,7 @@ H{ { vreg 1 } { start 0 } { end 2 } - { uses V{ 0 1 } } + { uses V{ T{ vreg-use f 0 } T{ vreg-use f 1 } } } { ranges V{ T{ live-range f 0 2 } } } { spill-to T{ spill-slot f 0 } } } @@ -99,7 +99,7 @@ H{ { vreg 1 } { start 5 } { end 5 } - { uses V{ 5 } } + { uses V{ T{ vreg-use f 5 } } } { ranges V{ T{ live-range f 5 5 } } } { reload-from T{ spill-slot f 0 } } } @@ -108,7 +108,7 @@ H{ { vreg 1 } { start 0 } { end 5 } - { uses V{ 0 1 5 } } + { uses V{ T{ vreg-use f 0 } T{ vreg-use f 1 } T{ vreg-use f 5 } } } { ranges V{ T{ live-range f 0 5 } } } } 2 split-for-spill ] unit-test @@ -118,7 +118,7 @@ H{ { vreg 2 } { start 0 } { end 1 } - { uses V{ 0 } } + { uses V{ T{ vreg-use f 0 } } } { ranges V{ T{ live-range f 0 1 } } } { spill-to T{ spill-slot f 4 } } } @@ -126,7 +126,7 @@ H{ { vreg 2 } { start 1 } { end 5 } - { uses V{ 1 5 } } + { uses V{ T{ vreg-use f 1 } T{ vreg-use f 5 } } } { ranges V{ T{ live-range f 1 5 } } } { reload-from T{ spill-slot f 4 } } } @@ -135,7 +135,7 @@ H{ { vreg 2 } { start 0 } { end 5 } - { uses V{ 0 1 5 } } + { uses V{ T{ vreg-use f 0 } T{ vreg-use f 1 } T{ vreg-use f 5 } } } { ranges V{ T{ live-range f 0 5 } } } } 0 split-for-spill ] unit-test @@ -145,7 +145,7 @@ H{ { vreg 3 } { start 0 } { end 1 } - { uses V{ 0 } } + { uses V{ T{ vreg-use f 0 } } } { ranges V{ T{ live-range f 0 1 } } } { spill-to T{ spill-slot f 8 } } } @@ -153,7 +153,7 @@ H{ { vreg 3 } { start 20 } { end 30 } - { uses V{ 20 30 } } + { uses V{ T{ vreg-use f 20 } T{ vreg-use f 30 } } } { ranges V{ T{ live-range f 20 30 } } } { reload-from T{ spill-slot f 8 } } } @@ -162,7 +162,7 @@ H{ { vreg 3 } { start 0 } { end 30 } - { uses V{ 0 20 30 } } + { uses V{ T{ vreg-use f 0 } T{ vreg-use f 20 } T{ vreg-use f 30 } } } { 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 @@ -187,21 +187,21 @@ H{ { reg 1 } { start 1 } { end 15 } - { uses V{ 1 3 7 10 15 } } + { uses V{ T{ vreg-use f 1 } T{ vreg-use f 3 } T{ vreg-use f 7 } T{ vreg-use f 10 } T{ vreg-use f 15 } } } } T{ live-interval { vreg 2 } { reg 2 } { start 3 } { end 8 } - { uses V{ 3 4 8 } } + { uses V{ T{ vreg-use f 3 } T{ vreg-use f 4 } T{ vreg-use f 8 } } } } T{ live-interval { vreg 3 } { reg 3 } { start 3 } { end 10 } - { uses V{ 3 10 } } + { uses V{ T{ vreg-use f 3 } T{ vreg-use f 10 } } } } } } @@ -211,7 +211,7 @@ H{ { vreg 1 } { start 5 } { end 5 } - { uses V{ 5 } } + { uses V{ T{ vreg-use f 5 } } } } spill-status ] unit-test @@ -230,14 +230,14 @@ H{ { reg 1 } { start 1 } { end 15 } - { uses V{ 1 } } + { uses V{ T{ vreg-use f 1 } } } } T{ live-interval { vreg 2 } { reg 2 } { start 3 } { end 8 } - { uses V{ 3 8 } } + { uses V{ T{ vreg-use f 3 } T{ vreg-use f 8 } } } } } } @@ -247,7 +247,7 @@ H{ { vreg 3 } { start 5 } { end 5 } - { uses V{ 5 } } + { uses V{ T{ vreg-use f 5 } } } } spill-status ] unit-test @@ -260,7 +260,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set { vreg 1 } { start 0 } { end 100 } - { uses V{ 0 100 } } + { uses V{ T{ vreg-use f 0 } T{ vreg-use f 100 } } } { ranges V{ T{ live-range f 0 100 } } } } } @@ -274,14 +274,14 @@ H{ { 1 int-rep } { 2 int-rep } } representations set { vreg 1 } { start 0 } { end 10 } - { uses V{ 0 10 } } + { uses V{ T{ vreg-use f 0 } T{ vreg-use f 10 } } } { ranges V{ T{ live-range f 0 10 } } } } T{ live-interval { vreg 2 } { start 11 } { end 20 } - { uses V{ 11 20 } } + { uses V{ T{ vreg-use f 11 } T{ vreg-use f 20 } } } { ranges V{ T{ live-range f 11 20 } } } } } @@ -295,14 +295,14 @@ H{ { 1 int-rep } { 2 int-rep } } representations set { vreg 1 } { start 0 } { end 100 } - { uses V{ 0 100 } } + { uses V{ T{ vreg-use f 0 } T{ vreg-use f 100 } } } { ranges V{ T{ live-range f 0 100 } } } } T{ live-interval { vreg 2 } { start 30 } { end 60 } - { uses V{ 30 60 } } + { uses V{ T{ vreg-use f 30 } T{ vreg-use f 60 } } } { ranges V{ T{ live-range f 30 60 } } } } } @@ -316,14 +316,14 @@ H{ { 1 int-rep } { 2 int-rep } } representations set { vreg 1 } { start 0 } { end 100 } - { uses V{ 0 100 } } + { uses V{ T{ vreg-use f 0 } T{ vreg-use f 100 } } } { ranges V{ T{ live-range f 0 100 } } } } T{ live-interval { vreg 2 } { start 30 } { end 200 } - { uses V{ 30 200 } } + { uses V{ T{ vreg-use f 30 } T{ vreg-use f 200 } } } { ranges V{ T{ live-range f 30 200 } } } } } @@ -337,14 +337,14 @@ H{ { 1 int-rep } { 2 int-rep } } representations set { vreg 1 } { start 0 } { end 100 } - { uses V{ 0 100 } } + { uses V{ T{ vreg-use f 0 } T{ vreg-use f 100 } } } { ranges V{ T{ live-range f 0 100 } } } } T{ live-interval { vreg 2 } { start 30 } { end 100 } - { uses V{ 30 100 } } + { uses V{ T{ vreg-use f 30 } T{ vreg-use f 100 } } } { ranges V{ T{ live-range f 30 100 } } } } } @@ -367,28 +367,28 @@ H{ { vreg 1 } { start 0 } { end 20 } - { uses V{ 0 10 20 } } + { uses V{ T{ vreg-use f 0 } T{ vreg-use f 10 } T{ vreg-use f 20 } } } { ranges V{ T{ live-range f 0 2 } T{ live-range f 10 20 } } } } T{ live-interval { vreg 2 } { start 0 } { end 20 } - { uses V{ 0 10 20 } } + { uses V{ T{ vreg-use f 0 } T{ vreg-use f 10 } T{ vreg-use f 20 } } } { ranges V{ T{ live-range f 0 2 } T{ live-range f 10 20 } } } } T{ live-interval { vreg 3 } { start 4 } { end 8 } - { uses V{ 6 } } + { uses V{ T{ vreg-use f 6 } } } { ranges V{ T{ live-range f 4 8 } } } } T{ live-interval { vreg 4 } { start 4 } { end 8 } - { uses V{ 8 } } + { uses V{ T{ vreg-use f 8 } } } { ranges V{ T{ live-range f 4 8 } } } } @@ -397,7 +397,7 @@ H{ { vreg 5 } { start 4 } { end 8 } - { uses V{ 8 } } + { uses V{ T{ vreg-use f 8 } } } { ranges V{ T{ live-range f 4 8 } } } } } @@ -413,7 +413,7 @@ H{ { vreg 1 } { start 0 } { end 10 } - { uses V{ 0 6 10 } } + { uses V{ T{ vreg-use f 0 } T{ vreg-use f 6 } T{ vreg-use f 10 } } } { ranges V{ T{ live-range f 0 10 } } } } @@ -422,7 +422,7 @@ H{ { vreg 5 } { start 2 } { end 8 } - { uses V{ 8 } } + { uses V{ T{ vreg-use f 8 } } } { ranges V{ T{ live-range f 2 8 } } } } } @@ -558,7 +558,7 @@ H{ { start 8 } { end 10 } { ranges V{ T{ live-range f 8 10 } } } - { uses V{ 8 10 } } + { uses V{ T{ vreg-use f 8 } T{ vreg-use f 10 } } } } 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 00d6f73517..221832e41a 100644 --- a/basis/compiler/cfg/linear-scan/live-intervals/live-intervals.factor +++ b/basis/compiler/cfg/linear-scan/live-intervals/live-intervals.factor @@ -1,4 +1,4 @@ -! Copyright (C) 2008, 2009 Slava Pestov. +! Copyright (C) 2008, 2010 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: namespaces kernel assocs accessors sequences math math.order fry combinators binary-search compiler.cfg.instructions compiler.cfg.registers @@ -10,6 +10,12 @@ TUPLE: live-range from to ; C: live-range +SYMBOLS: +def+ +use+ +memory+ ; + +TUPLE: vreg-use n type ; + +C: vreg-use + TUPLE: live-interval vreg reg spill-to reload-from @@ -50,18 +56,11 @@ M: live-interval covers? ( insn# live-interval -- ? ) 2dup extend-range? [ extend-range ] [ add-new-range ] if ; -GENERIC: operands-in-registers? ( insn -- ? ) - -M: vreg-insn operands-in-registers? drop t ; - -M: partial-sync-insn operands-in-registers? drop f ; - -: add-def ( insn live-interval -- ) - [ insn#>> ] [ uses>> ] bi* push ; - -: add-use ( insn live-interval -- ) - ! Every use is a potential def, no SSA here baby! - over operands-in-registers? [ add-def ] [ 2drop ] if ; +: add-use ( insn live-interval type -- ) + dup +memory+ eq? [ 3drop ] [ + swap [ [ insn#>> ] dip ] dip + uses>> push + ] if ; : ( vreg -- live-interval ) \ live-interval new @@ -73,9 +72,6 @@ M: partial-sync-insn operands-in-registers? drop f ; : block-to ( bb -- n ) instructions>> last insn#>> ; -M: live-interval hashcode* - nip [ start>> ] [ end>> 1000 * ] bi + ; - ! Mapping from vreg to live-interval SYMBOL: live-intervals @@ -86,21 +82,29 @@ GENERIC: compute-live-intervals* ( insn -- ) M: insn compute-live-intervals* drop ; -: handle-output ( insn vreg -- ) - live-interval - [ [ insn#>> ] dip shorten-range ] [ add-def ] 2bi ; +: handle-output ( insn vreg type -- ) + [ live-interval ] dip + [ drop [ insn#>> ] dip shorten-range ] [ add-use ] 3bi ; -: handle-input ( insn vreg -- ) - live-interval - [ [ [ basic-block get block-from ] dip insn#>> ] dip add-range ] [ add-use ] 2bi ; +: handle-input ( insn vreg type -- ) + [ live-interval ] dip + [ drop [ [ basic-block get block-from ] dip insn#>> ] dip add-range ] + [ add-use ] + 3bi ; : handle-temp ( insn vreg -- ) live-interval - [ [ insn#>> dup ] dip add-range ] [ add-use ] 2bi ; + [ [ insn#>> dup ] dip add-range ] [ +def+ add-use ] 2bi ; M: vreg-insn compute-live-intervals* - [ dup defs-vreg [ handle-output ] with when* ] - [ dup uses-vregs [ handle-input ] with each ] + [ dup defs-vreg [ +def+ handle-output ] with when* ] + [ dup uses-vregs [ +use+ handle-input ] with each ] + [ dup temp-vregs [ handle-temp ] with each ] + tri ; + +M: partial-sync-insn compute-live-intervals* + [ dup defs-vreg [ +use+ handle-output ] with when* ] + [ dup uses-vregs [ +memory+ handle-input ] with each ] [ dup temp-vregs [ handle-temp ] with each ] tri ;