diff --git a/basis/compiler/cfg/builder/builder-tests.factor b/basis/compiler/cfg/builder/builder-tests.factor index 792b5d0902..9ed7c592ce 100644 --- a/basis/compiler/cfg/builder/builder-tests.factor +++ b/basis/compiler/cfg/builder/builder-tests.factor @@ -5,7 +5,8 @@ compiler.cfg.optimizer compiler.cfg.predecessors compiler.cfg.checker compiler.cfg arrays locals byte-arrays kernel.private math slots.private vectors sbufs strings math.partial-dispatch hashtables assocs combinators.short-circuit -strings.private accessors compiler.cfg.instructions ; +strings.private accessors compiler.cfg.instructions +compiler.cfg.representations ; FROM: alien.c-types => int ; IN: compiler.cfg.builder.tests diff --git a/basis/compiler/cfg/cfg.factor b/basis/compiler/cfg/cfg.factor index 9568217e9c..1391c37077 100644 --- a/basis/compiler/cfg/cfg.factor +++ b/basis/compiler/cfg/cfg.factor @@ -21,7 +21,7 @@ number M: basic-block hashcode* nip id>> ; TUPLE: cfg { entry basic-block } word label -spill-area-size reps +spill-area-size post-order linear-order predecessors-valid? dominance-valid? loops-valid? ; diff --git a/basis/compiler/cfg/checker/checker.factor b/basis/compiler/cfg/checker/checker.factor index cb840a299d..b84742b8b0 100644 --- a/basis/compiler/cfg/checker/checker.factor +++ b/basis/compiler/cfg/checker/checker.factor @@ -3,7 +3,8 @@ USING: kernel combinators.short-circuit accessors math sequences sets assocs compiler.cfg.instructions compiler.cfg.rpo compiler.cfg.def-use compiler.cfg.linearization -compiler.cfg.utilities compiler.cfg.mr compiler.utilities ; +compiler.cfg.utilities compiler.cfg.finalization compiler.cfg.mr +compiler.utilities ; IN: compiler.cfg.checker ! Check invariants @@ -64,5 +65,5 @@ ERROR: undefined-values uses defs ; : check-cfg ( cfg -- ) [ [ check-basic-block ] each-basic-block ] - [ build-mr check-mr ] + [ finalize-cfg build-mr check-mr ] bi ; diff --git a/basis/compiler/cfg/debugger/debugger.factor b/basis/compiler/cfg/debugger/debugger.factor index d4e8c5401a..9aa81a1b0d 100644 --- a/basis/compiler/cfg/debugger/debugger.factor +++ b/basis/compiler/cfg/debugger/debugger.factor @@ -7,10 +7,10 @@ prettyprint.sections parser compiler.tree.builder compiler.tree.optimizer cpu.architecture compiler.cfg.builder compiler.cfg.linearization compiler.cfg.registers compiler.cfg.stack-frame compiler.cfg.linear-scan -compiler.cfg.optimizer compiler.cfg.instructions -compiler.cfg.utilities compiler.cfg.def-use compiler.cfg.rpo -compiler.cfg.mr compiler.cfg.representations.preferred -compiler.cfg ; +compiler.cfg.optimizer compiler.cfg.finalization +compiler.cfg.instructions compiler.cfg.utilities +compiler.cfg.def-use compiler.cfg.rpo compiler.cfg.mr +compiler.cfg.representations.preferred compiler.cfg ; IN: compiler.cfg.debugger GENERIC: test-cfg ( quot -- cfgs ) @@ -27,6 +27,7 @@ M: word test-cfg test-cfg [ [ optimize-cfg + finalize-cfg build-mr ] with-cfg ] map ; diff --git a/basis/compiler/cfg/finalization/authors.txt b/basis/compiler/cfg/finalization/authors.txt new file mode 100644 index 0000000000..1901f27a24 --- /dev/null +++ b/basis/compiler/cfg/finalization/authors.txt @@ -0,0 +1 @@ +Slava Pestov diff --git a/basis/compiler/cfg/finalization/finalization.factor b/basis/compiler/cfg/finalization/finalization.factor new file mode 100644 index 0000000000..93a9a07e3d --- /dev/null +++ b/basis/compiler/cfg/finalization/finalization.factor @@ -0,0 +1,14 @@ +! Copyright (C) 2010 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: compiler.cfg.empty-blocks compiler.cfg.gc-checks +compiler.cfg.linear-scan compiler.cfg.representations +compiler.cfg.save-contexts compiler.cfg.ssa.destruction ; +IN: compiler.cfg.finalization + +: finalize-cfg ( cfg -- cfg' ) + select-representations + insert-gc-checks + insert-save-contexts + destruct-ssa + delete-empty-blocks + linear-scan ; diff --git a/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor index fdba952d4a..19b0f6c5b9 100644 --- a/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor +++ b/basis/compiler/cfg/linear-scan/allocation/spilling/spilling.factor @@ -29,7 +29,8 @@ ERROR: bad-live-ranges interval ; 2bi ; : assign-spill ( live-interval -- ) - dup vreg>> vreg-spill-slot >>spill-to drop ; + dup [ vreg>> ] [ last-use rep>> ] bi + assign-spill-slot >>spill-to drop ; : spill-before ( before -- before/f ) ! If the interval does not have any usages before the spill location, @@ -46,7 +47,8 @@ ERROR: bad-live-ranges interval ; ] if ; : assign-reload ( live-interval -- ) - dup vreg>> vreg-spill-slot >>reload-from drop ; + dup [ vreg>> ] [ first-use rep>> ] bi + assign-spill-slot >>reload-from drop ; : 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/state/state.factor b/basis/compiler/cfg/linear-scan/allocation/state/state.factor index 06365b0ed2..7626ac9554 100644 --- a/basis/compiler/cfg/linear-scan/allocation/state/state.factor +++ b/basis/compiler/cfg/linear-scan/allocation/state/state.factor @@ -1,9 +1,10 @@ ! Copyright (C) 2009 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors assocs combinators cpu.architecture fry heaps -kernel math math.order namespaces sequences vectors +USING: arrays accessors assocs combinators cpu.architecture fry +heaps kernel math math.order namespaces sequences vectors linked-assocs compiler.cfg compiler.cfg.registers -compiler.cfg.instructions compiler.cfg.linear-scan.live-intervals ; +compiler.cfg.instructions +compiler.cfg.linear-scan.live-intervals ; IN: compiler.cfg.linear-scan.allocation.state ! Start index of current live interval. We ensure that all @@ -127,8 +128,11 @@ SYMBOL: unhandled-sync-points ! Mapping from vregs to spill slots SYMBOL: spill-slots -: vreg-spill-slot ( vreg -- spill-slot ) - spill-slots get [ rep-of next-spill-slot ] cache ; +: assign-spill-slot ( coalesced-vreg rep -- spill-slot ) + spill-slots get [ nip next-spill-slot ] 2cache ; + +: lookup-spill-slot ( coalesced-vreg rep -- spill-slot ) + 2array spill-slots get ?at [ ] [ bad-vreg ] if ; : init-allocator ( registers -- ) registers set diff --git a/basis/compiler/cfg/linear-scan/assignment/assignment.factor b/basis/compiler/cfg/linear-scan/assignment/assignment.factor index 7c0f38a44e..5f1a50f178 100644 --- a/basis/compiler/cfg/linear-scan/assignment/assignment.factor +++ b/basis/compiler/cfg/linear-scan/assignment/assignment.factor @@ -31,10 +31,12 @@ SYMBOL: pending-interval-assoc ERROR: bad-vreg vreg ; -: (vreg>reg) ( vreg pending -- reg ) +:: (vreg>reg) ( vreg pending -- reg ) ! If a live vreg is not in the pending set, then it must ! have been spilled. - ?at [ spill-slots get ?at [ ] [ bad-vreg ] if ] unless ; + vreg pending at* [ + drop vreg vreg rep-of lookup-spill-slot + ] unless ; : vreg>reg ( vreg -- reg ) pending-interval-assoc get (vreg>reg) ; @@ -68,10 +70,8 @@ SYMBOL: register-live-outs H{ } clone register-live-outs set init-unhandled ; -: spill-rep ( live-interval -- rep ) vreg>> rep-of ; - : insert-spill ( live-interval -- ) - [ reg>> ] [ spill-rep ] [ spill-to>> ] tri ##spill ; + [ reg>> ] [ first-use rep>> ] [ spill-to>> ] tri ##spill ; : handle-spill ( live-interval -- ) dup spill-to>> [ insert-spill ] [ drop ] if ; @@ -90,10 +90,8 @@ SYMBOL: register-live-outs : expire-old-intervals ( n -- ) pending-interval-heap get (expire-old-intervals) ; -: reload-rep ( live-interval -- rep ) vreg>> rep-of ; - : insert-reload ( live-interval -- ) - [ reg>> ] [ reload-rep ] [ reload-from>> ] tri ##reload ; + [ reg>> ] [ first-use rep>> ] [ reload-from>> ] tri ##reload ; : insert-reload? ( live-interval -- ? ) ! Don't insert a reload if the register will be written to diff --git a/basis/compiler/cfg/linear-scan/linear-scan-tests.factor b/basis/compiler/cfg/linear-scan/linear-scan-tests.factor index a0f6b9f5c5..6d479c9daa 100644 --- a/basis/compiler/cfg/linear-scan/linear-scan-tests.factor +++ b/basis/compiler/cfg/linear-scan/linear-scan-tests.factor @@ -92,7 +92,7 @@ H{ { reg-class float-regs } { start 0 } { end 2 } - { uses V{ T{ vreg-use f 0 } T{ vreg-use f 1 } } } + { uses V{ T{ vreg-use f float-rep 0 } T{ vreg-use f float-rep 1 } } } { ranges V{ T{ live-range f 0 2 } } } { spill-to T{ spill-slot f 0 } } } @@ -101,7 +101,7 @@ H{ { reg-class float-regs } { start 5 } { end 5 } - { uses V{ T{ vreg-use f 5 } } } + { uses V{ T{ vreg-use f float-rep 5 } } } { ranges V{ T{ live-range f 5 5 } } } { reload-from T{ spill-slot f 0 } } } @@ -111,7 +111,7 @@ H{ { reg-class float-regs } { start 0 } { end 5 } - { uses V{ T{ vreg-use f 0 } T{ vreg-use f 1 } T{ vreg-use f 5 } } } + { uses V{ T{ vreg-use f float-rep 0 } T{ vreg-use f float-rep 1 } T{ vreg-use f float-rep 5 } } } { ranges V{ T{ live-range f 0 5 } } } } 2 split-for-spill ] unit-test @@ -122,7 +122,7 @@ H{ { reg-class float-regs } { start 0 } { end 1 } - { uses V{ T{ vreg-use f 0 } } } + { uses V{ T{ vreg-use f float-rep 0 } } } { ranges V{ T{ live-range f 0 1 } } } { spill-to T{ spill-slot f 4 } } } @@ -131,7 +131,7 @@ H{ { reg-class float-regs } { start 1 } { end 5 } - { uses V{ T{ vreg-use f 1 } T{ vreg-use f 5 } } } + { uses V{ T{ vreg-use f float-rep 1 } T{ vreg-use f float-rep 5 } } } { ranges V{ T{ live-range f 1 5 } } } { reload-from T{ spill-slot f 4 } } } @@ -141,7 +141,7 @@ H{ { reg-class float-regs } { start 0 } { end 5 } - { uses V{ T{ vreg-use f 0 } T{ vreg-use f 1 } T{ vreg-use f 5 } } } + { uses V{ T{ vreg-use f float-rep 0 } T{ vreg-use f float-rep 1 } T{ vreg-use f float-rep 5 } } } { ranges V{ T{ live-range f 0 5 } } } } 0 split-for-spill ] unit-test @@ -152,7 +152,7 @@ H{ { reg-class float-regs } { start 0 } { end 1 } - { uses V{ T{ vreg-use f 0 } } } + { uses V{ T{ vreg-use f float-rep 0 } } } { ranges V{ T{ live-range f 0 1 } } } { spill-to T{ spill-slot f 8 } } } @@ -161,7 +161,7 @@ H{ { reg-class float-regs } { start 20 } { end 30 } - { uses V{ T{ vreg-use f 20 } T{ vreg-use f 30 } } } + { uses V{ T{ vreg-use f float-rep 20 } T{ vreg-use f float-rep 30 } } } { ranges V{ T{ live-range f 20 30 } } } { reload-from T{ spill-slot f 8 } } } @@ -171,7 +171,7 @@ H{ { reg-class float-regs } { start 0 } { end 30 } - { uses V{ T{ vreg-use f 0 } T{ vreg-use f 20 } T{ vreg-use f 30 } } } + { uses V{ T{ vreg-use f float-rep 0 } T{ vreg-use f float-rep 20 } T{ vreg-use f float-rep 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 @@ -197,7 +197,7 @@ H{ { reg 1 } { start 1 } { end 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 } } } + { 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 } } } } T{ live-interval { vreg 2 } @@ -205,7 +205,7 @@ H{ { reg 2 } { start 3 } { end 8 } - { uses V{ T{ vreg-use f 3 } T{ vreg-use f 4 } T{ vreg-use f 8 } } } + { uses V{ T{ vreg-use f int-rep 3 } T{ vreg-use f int-rep 4 } T{ vreg-use f int-rep 8 } } } } T{ live-interval { vreg 3 } @@ -213,7 +213,7 @@ H{ { reg 3 } { start 3 } { end 10 } - { uses V{ T{ vreg-use f 3 } T{ vreg-use f 10 } } } + { uses V{ T{ vreg-use f int-rep 3 } T{ vreg-use f int-rep 10 } } } } } } @@ -224,7 +224,7 @@ H{ { reg-class int-regs } { start 5 } { end 5 } - { uses V{ T{ vreg-use f 5 } } } + { uses V{ T{ vreg-use f int-rep 5 } } } } spill-status ] unit-test @@ -244,7 +244,7 @@ H{ { reg 1 } { start 1 } { end 15 } - { uses V{ T{ vreg-use f 1 } } } + { uses V{ T{ vreg-use f int-rep 1 } } } } T{ live-interval { vreg 2 } @@ -252,7 +252,7 @@ H{ { reg 2 } { start 3 } { end 8 } - { uses V{ T{ vreg-use f 3 } T{ vreg-use f 8 } } } + { uses V{ T{ vreg-use f int-rep 3 } T{ vreg-use f int-rep 8 } } } } } } @@ -263,7 +263,7 @@ H{ { reg-class int-regs } { start 5 } { end 5 } - { uses V{ T{ vreg-use f 5 } } } + { uses V{ T{ vreg-use f int-rep 5 } } } } spill-status ] unit-test @@ -277,7 +277,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set { reg-class int-regs } { start 0 } { end 100 } - { uses V{ T{ vreg-use f 0 } T{ vreg-use f 100 } } } + { uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 100 } } } { ranges V{ T{ live-range f 0 100 } } } } } @@ -292,7 +292,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set { reg-class int-regs } { start 0 } { end 10 } - { uses V{ T{ vreg-use f 0 } T{ vreg-use f 10 } } } + { uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 10 } } } { ranges V{ T{ live-range f 0 10 } } } } T{ live-interval @@ -300,7 +300,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set { reg-class int-regs } { start 11 } { end 20 } - { uses V{ T{ vreg-use f 11 } T{ vreg-use f 20 } } } + { uses V{ T{ vreg-use f int-rep 11 } T{ vreg-use f int-rep 20 } } } { ranges V{ T{ live-range f 11 20 } } } } } @@ -315,7 +315,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set { reg-class int-regs } { start 0 } { end 100 } - { uses V{ T{ vreg-use f 0 } T{ vreg-use f 100 } } } + { uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 100 } } } { ranges V{ T{ live-range f 0 100 } } } } T{ live-interval @@ -323,7 +323,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set { reg-class int-regs } { start 30 } { end 60 } - { uses V{ T{ vreg-use f 30 } T{ vreg-use f 60 } } } + { uses V{ T{ vreg-use f int-rep 30 } T{ vreg-use f int-rep 60 } } } { ranges V{ T{ live-range f 30 60 } } } } } @@ -338,7 +338,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set { reg-class int-regs } { start 0 } { end 100 } - { uses V{ T{ vreg-use f 0 } T{ vreg-use f 100 } } } + { uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 100 } } } { ranges V{ T{ live-range f 0 100 } } } } T{ live-interval @@ -346,7 +346,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set { reg-class int-regs } { start 30 } { end 200 } - { uses V{ T{ vreg-use f 30 } T{ vreg-use f 200 } } } + { uses V{ T{ vreg-use f int-rep 30 } T{ vreg-use f int-rep 200 } } } { ranges V{ T{ live-range f 30 200 } } } } } @@ -361,7 +361,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set { reg-class int-regs } { start 0 } { end 100 } - { uses V{ T{ vreg-use f 0 } T{ vreg-use f 100 } } } + { uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 100 } } } { ranges V{ T{ live-range f 0 100 } } } } T{ live-interval @@ -369,7 +369,7 @@ H{ { 1 int-rep } { 2 int-rep } } representations set { reg-class int-regs } { start 30 } { end 100 } - { uses V{ T{ vreg-use f 30 } T{ vreg-use f 100 } } } + { uses V{ T{ vreg-use f int-rep 30 } T{ vreg-use f int-rep 100 } } } { ranges V{ T{ live-range f 30 100 } } } } } @@ -393,7 +393,7 @@ H{ { reg-class int-regs } { start 0 } { end 20 } - { uses V{ T{ vreg-use f 0 } T{ vreg-use f 10 } T{ vreg-use f 20 } } } + { uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 10 } T{ vreg-use f int-rep 20 } } } { ranges V{ T{ live-range f 0 2 } T{ live-range f 10 20 } } } } T{ live-interval @@ -401,7 +401,7 @@ H{ { reg-class int-regs } { start 0 } { end 20 } - { uses V{ T{ vreg-use f 0 } T{ vreg-use f 10 } T{ vreg-use f 20 } } } + { uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 10 } T{ vreg-use f int-rep 20 } } } { ranges V{ T{ live-range f 0 2 } T{ live-range f 10 20 } } } } T{ live-interval @@ -409,7 +409,7 @@ H{ { reg-class int-regs } { start 4 } { end 8 } - { uses V{ T{ vreg-use f 6 } } } + { uses V{ T{ vreg-use f int-rep 6 } } } { ranges V{ T{ live-range f 4 8 } } } } T{ live-interval @@ -417,7 +417,7 @@ H{ { reg-class int-regs } { start 4 } { end 8 } - { uses V{ T{ vreg-use f 8 } } } + { uses V{ T{ vreg-use f int-rep 8 } } } { ranges V{ T{ live-range f 4 8 } } } } @@ -427,7 +427,7 @@ H{ { reg-class int-regs } { start 4 } { end 8 } - { uses V{ T{ vreg-use f 8 } } } + { uses V{ T{ vreg-use f int-rep 8 } } } { ranges V{ T{ live-range f 4 8 } } } } } @@ -444,7 +444,7 @@ H{ { reg-class int-regs } { start 0 } { end 10 } - { uses V{ T{ vreg-use f 0 } T{ vreg-use f 6 } T{ vreg-use f 10 } } } + { uses V{ T{ vreg-use f int-rep 0 } T{ vreg-use f int-rep 6 } T{ vreg-use f int-rep 10 } } } { ranges V{ T{ live-range f 0 10 } } } } @@ -454,7 +454,7 @@ H{ { reg-class int-regs } { start 2 } { end 8 } - { uses V{ T{ vreg-use f 8 } } } + { uses V{ T{ vreg-use f int-rep 8 } } } { ranges V{ T{ live-range f 2 8 } } } } } @@ -596,7 +596,7 @@ H{ { start 8 } { end 10 } { ranges V{ T{ live-range f 8 10 } } } - { uses V{ T{ vreg-use f 8 } T{ vreg-use f 10 } } } + { uses V{ T{ vreg-use f int-rep 8 } T{ vreg-use f int-rep 10 } } } } register-status ] unit-test @@ -783,6 +783,7 @@ V{ T{ ##copy { dst 689607 } { src 689604 } + { rep int-rep } } T{ ##copy { dst 689608 } 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 62b23ddde9..596ac610f0 100644 --- a/basis/compiler/cfg/linear-scan/live-intervals/live-intervals.factor +++ b/basis/compiler/cfg/linear-scan/live-intervals/live-intervals.factor @@ -1,9 +1,12 @@ ! 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 -compiler.cfg.def-use compiler.cfg.liveness compiler.cfg.linearization.order -compiler.cfg cpu.architecture ; +USING: namespaces kernel assocs accessors locals sequences math +math.order fry combinators binary-search +compiler.cfg.instructions compiler.cfg.registers +compiler.cfg.def-use compiler.cfg.liveness +compiler.cfg.linearization.order +compiler.cfg +cpu.architecture ; IN: compiler.cfg.linear-scan.live-intervals TUPLE: live-range from to ; @@ -12,7 +15,7 @@ C: live-range SYMBOLS: +def+ +use+ +memory+ ; -TUPLE: vreg-use n type ; +TUPLE: vreg-use rep n type ; C: vreg-use @@ -61,62 +64,75 @@ M: live-interval covers? ( insn# live-interval -- ? ) 2dup extend-range? [ extend-range ] [ add-new-range ] if ; -: add-use ( insn live-interval type -- ) - dup +memory+ eq? [ 3drop ] [ - swap [ [ insn#>> ] dip ] dip - uses>> push - ] if ; +:: add-use ( rep n type live-interval -- ) + type +memory+ eq? [ + rep n type + live-interval uses>> push + ] unless ; -: ( vreg -- live-interval ) +: ( vreg reg-class -- live-interval ) \ live-interval new V{ } clone >>uses V{ } clone >>ranges - over rep-of reg-class-of >>reg-class + swap >>reg-class swap >>vreg ; : block-from ( bb -- n ) instructions>> first insn#>> 1 - ; : block-to ( bb -- n ) instructions>> last insn#>> ; +SYMBOLS: from to ; + ! Mapping from vreg to live-interval SYMBOL: live-intervals : live-interval ( vreg -- live-interval ) - live-intervals get [ ] cache ; + live-intervals get [ dup rep-of reg-class-of ] cache ; GENERIC: compute-live-intervals* ( insn -- ) M: insn compute-live-intervals* drop ; -: handle-output ( insn vreg type -- ) - [ live-interval ] dip - [ drop [ insn#>> ] dip shorten-range ] [ add-use ] 3bi ; +:: handle-output ( vreg n type -- ) + vreg rep-of :> rep + vreg live-interval :> live-interval -: handle-input ( insn vreg type -- ) - [ live-interval ] dip - [ drop [ [ basic-block get block-from ] dip insn#>> ] dip add-range ] - [ add-use ] - 3bi ; + n live-interval shorten-range + rep n type live-interval add-use ; -: handle-temp ( insn vreg -- ) - live-interval - [ [ insn#>> dup ] dip add-range ] [ +def+ add-use ] 2bi ; +:: handle-input ( vreg n type -- ) + vreg rep-of :> rep + vreg live-interval :> live-interval -M: vreg-insn compute-live-intervals* - [ dup defs-vreg [ +def+ handle-output ] with when* ] - [ dup uses-vregs [ +use+ handle-input ] with each ] - [ dup temp-vregs [ handle-temp ] with each ] - tri ; + from get n live-interval add-range + rep n type live-interval add-use ; -M: clobber-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 ; +:: handle-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+ handle-output ] when* + insn uses-vregs [ n +use+ handle-input ] each + insn temp-vregs [ n handle-temp ] each ; + +M:: clobber-insn compute-live-intervals* ( insn -- ) + insn insn#>> :> n + + insn defs-vreg [ n +use+ handle-output ] when* + insn uses-vregs [ n +memory+ handle-input ] each + insn temp-vregs [ n handle-temp ] each ; : handle-live-out ( bb -- ) - [ block-from ] [ block-to ] [ live-out keys ] tri - [ live-interval add-range ] with with each ; + live-out dup assoc-empty? [ drop ] [ + [ from get to get ] dip keys + [ live-interval add-range ] with with each + ] if ; ! A location where all registers have to be spilled TUPLE: sync-point n ; @@ -134,15 +150,18 @@ M: clobber-insn compute-sync-points* M: insn compute-sync-points* drop ; : compute-live-intervals-step ( bb -- ) - [ basic-block set ] - [ handle-live-out ] - [ - instructions>> [ - [ compute-live-intervals* ] - [ compute-sync-points* ] - bi - ] each - ] tri ; + { + [ block-from from set ] + [ block-to to set ] + [ handle-live-out ] + [ + instructions>> [ + [ compute-live-intervals* ] + [ compute-sync-points* ] + bi + ] each + ] + } cleave ; : init-live-intervals ( -- ) H{ } clone live-intervals set diff --git a/basis/compiler/cfg/mr/mr.factor b/basis/compiler/cfg/mr/mr.factor index 140fba8d4e..5b9e9ee2c3 100644 --- a/basis/compiler/cfg/mr/mr.factor +++ b/basis/compiler/cfg/mr/mr.factor @@ -1,11 +1,8 @@ -! Copyright (C) 2009 Slava Pestov. +! Copyright (C) 2009, 2010 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel namespaces accessors compiler.cfg -compiler.cfg.linearization compiler.cfg.linear-scan -compiler.cfg.build-stack-frame ; +USING: compiler.cfg.linearization compiler.cfg.build-stack-frame ; IN: compiler.cfg.mr : build-mr ( cfg -- mr ) - linear-scan flatten-cfg build-stack-frame ; \ No newline at end of file diff --git a/basis/compiler/cfg/optimizer/optimizer.factor b/basis/compiler/cfg/optimizer/optimizer.factor index e6cd65f4b5..ca1886bcd6 100644 --- a/basis/compiler/cfg/optimizer/optimizer.factor +++ b/basis/compiler/cfg/optimizer/optimizer.factor @@ -1,7 +1,6 @@ ! Copyright (C) 2008, 2010 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel sequences accessors combinators namespaces -compiler.cfg.tco +USING: compiler.cfg.tco compiler.cfg.useless-conditionals compiler.cfg.branch-splitting compiler.cfg.block-joining @@ -19,13 +18,6 @@ compiler.cfg.empty-blocks compiler.cfg.checker ; IN: compiler.cfg.optimizer -SYMBOL: check-optimizer? - -: ?check ( cfg -- cfg' ) - check-optimizer? get [ - dup check-cfg - ] when ; - : optimize-cfg ( cfg -- cfg' ) optimize-tail-calls delete-useless-conditionals @@ -36,10 +28,4 @@ SYMBOL: check-optimizer? value-numbering copy-propagation eliminate-dead-code - eliminate-write-barriers - select-representations - insert-gc-checks - insert-save-contexts - destruct-ssa - delete-empty-blocks - ?check ; + eliminate-write-barriers ; diff --git a/basis/compiler/cfg/representations/representations.factor b/basis/compiler/cfg/representations/representations.factor index 100da7a53f..2160ad26e6 100644 --- a/basis/compiler/cfg/representations/representations.factor +++ b/basis/compiler/cfg/representations/representations.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2009, 2010 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. -USING: accessors combinators namespaces +USING: combinators compiler.cfg compiler.cfg.registers compiler.cfg.predecessors @@ -26,5 +26,4 @@ IN: compiler.cfg.representations [ compute-representations ] [ insert-conversions ] [ ] - } cleave - representations get cfg get (>>reps) ; + } cleave ; diff --git a/basis/compiler/cfg/ssa/destruction/destruction.factor b/basis/compiler/cfg/ssa/destruction/destruction.factor index 83413067b7..03252dce0d 100644 --- a/basis/compiler/cfg/ssa/destruction/destruction.factor +++ b/basis/compiler/cfg/ssa/destruction/destruction.factor @@ -23,6 +23,11 @@ SYMBOL: leader-map : leader ( vreg -- vreg' ) leader-map get compress-path ; +! Maps basic blocks to ##phi instruction outputs +SYMBOL: phi-sets + +: phi-set ( bb -- vregs ) phi-sets get at ; + ! Maps leaders to equivalence class elements. SYMBOL: class-element-map @@ -102,16 +107,25 @@ M: ##copy rename-insn [ call-next-method drop ] [ [ dst>> ] [ src>> ] bi eq? not ] bi ; -M: ##phi rename-insn drop f ; +SYMBOL: current-phi-set + +M: ##phi rename-insn dst>> current-phi-set get push f ; M: ##call-gc rename-insn [ renamings get '[ _ at ] map members ] change-gc-roots drop t ; M: insn rename-insn drop t ; +: renaming-in-block ( bb -- ) + V{ } clone current-phi-set set + [ [ current-phi-set ] dip phi-sets get set-at ] + [ instructions>> [ rename-insn ] filter! drop ] + bi ; + : perform-renaming ( cfg -- ) + H{ } clone phi-sets set leader-map get keys [ dup leader ] H{ } map>assoc renamings set - [ instructions>> [ rename-insn ] filter! drop ] each-basic-block ; + [ renaming-in-block ] each-basic-block ; : destruct-ssa ( cfg -- cfg' ) needs-dominance diff --git a/basis/compiler/compiler.factor b/basis/compiler/compiler.factor index 71fdd6cbaf..9bc473e330 100644 --- a/basis/compiler/compiler.factor +++ b/basis/compiler/compiler.factor @@ -16,6 +16,7 @@ compiler.tree.optimizer compiler.cfg compiler.cfg.builder compiler.cfg.optimizer +compiler.cfg.finalization compiler.cfg.mr compiler.codegen ; @@ -125,7 +126,7 @@ M: word combinator? inline? ; : backend ( tree word -- ) build-cfg [ - [ optimize-cfg build-mr ] with-cfg + [ optimize-cfg finalize-cfg build-mr ] with-cfg [ generate ] [ label>> ] bi compiled get set-at ] each ; diff --git a/basis/compiler/tests/low-level-ir.factor b/basis/compiler/tests/low-level-ir.factor index 57612e730e..5cba592163 100644 --- a/basis/compiler/tests/low-level-ir.factor +++ b/basis/compiler/tests/low-level-ir.factor @@ -1,20 +1,20 @@ USING: accessors assocs compiler compiler.cfg compiler.cfg.debugger compiler.cfg.instructions compiler.cfg.mr -compiler.cfg.registers compiler.codegen compiler.units -cpu.architecture hashtables kernel namespaces sequences -tools.test vectors words layouts literals math arrays +compiler.cfg.registers compiler.cfg.linear-scan compiler.codegen +compiler.units cpu.architecture hashtables kernel namespaces +sequences tools.test vectors words layouts literals math arrays alien.c-types alien.syntax math.private ; IN: compiler.tests.low-level-ir : compile-cfg ( cfg -- word ) gensym - [ build-mr generate ] dip + [ linear-scan build-mr generate ] dip [ associate >alist t t modify-code-heap ] keep ; : compile-test-cfg ( -- word ) cfg new 0 get >>entry dup cfg set - dup fake-representations representations get >>reps + dup fake-representations compile-cfg ; : compile-test-bb ( insns -- result )