diff --git a/basis/compiler/cfg/coalescing/coalescing.factor b/basis/compiler/cfg/coalescing/coalescing.factor index 28528068c2..a9637088a3 100644 --- a/basis/compiler/cfg/coalescing/coalescing.factor +++ b/basis/compiler/cfg/coalescing/coalescing.factor @@ -7,10 +7,12 @@ compiler.cfg.def-use compiler.cfg.utilities compiler.cfg.dominance compiler.cfg.instructions +compiler.cfg.critical-edges compiler.cfg.coalescing.state compiler.cfg.coalescing.forest compiler.cfg.coalescing.copies compiler.cfg.coalescing.renaming +compiler.cfg.coalescing.live-ranges compiler.cfg.coalescing.process-blocks ; IN: compiler.cfg.coalescing @@ -49,9 +51,11 @@ SYMBOL: seen : coalesce ( cfg -- cfg' ) init-coalescing + dup split-critical-edges dup compute-def-use dup compute-dominance dup compute-dfs + dup compute-live-ranges dup process-blocks break-interferences dup perform-renaming diff --git a/basis/compiler/cfg/coalescing/copies/copies.factor b/basis/compiler/cfg/coalescing/copies/copies.factor index ab1c514c96..5df2684f72 100644 --- a/basis/compiler/cfg/coalescing/copies/copies.factor +++ b/basis/compiler/cfg/coalescing/copies/copies.factor @@ -7,7 +7,7 @@ IN: compiler.cfg.coalescing.copies : compute-copies ( assoc -- assoc' ) dup assoc-size [ '[ - [ _ 2dup key? [ "OOPS" throw ] [ set-at ] if ] with each + [ 2dup eq? [ 2drop ] [ _ 2dup key? [ "OOPS" throw ] [ set-at ] if ] if ] with each ] assoc-each ] keep ; diff --git a/basis/compiler/cfg/coalescing/interference/interference.factor b/basis/compiler/cfg/coalescing/interference/interference.factor index 9fdf06bcb4..ff5e6319e6 100644 --- a/basis/compiler/cfg/coalescing/interference/interference.factor +++ b/basis/compiler/cfg/coalescing/interference/interference.factor @@ -2,48 +2,32 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors assocs combinators combinators.short-circuit kernel math namespaces sequences locals compiler.cfg.def-use -compiler.cfg.liveness compiler.cfg.dominance ; +compiler.cfg.dominance compiler.cfg.coalescing.live-ranges ; IN: compiler.cfg.coalescing.interference -! Local interference testing. Requires live-out information > [ - [ swap defs-vregs [ def-index get set-at ] with each ] - [ swap uses-vregs [ kill-index get set-at ] with each ] - 2bi - ] each-index - ] - [ live-out keys [ [ 1/0. ] dip kill-index get set-at ] each ] - bi ; - -: kill-after-def? ( vreg1 vreg2 -- ? ) +: kill-after-def? ( vreg1 vreg2 bb -- ? ) ! If first register is killed after second one is defined, they interfere - [ kill-index get at ] [ def-index get at ] bi* >= ; + [ kill-index ] [ def-index ] bi-curry bi* >= ; : interferes-same-block? ( vreg1 vreg2 bb1 bb2 -- ? ) ! If both are defined in the same basic block, they interfere if their ! local live ranges intersect. - drop compute-local-live-ranges - { [ kill-after-def? ] [ swap kill-after-def? ] } 2|| ; + drop + { [ kill-after-def? ] [ swapd kill-after-def? ] } 3|| ; : interferes-first-dominates? ( vreg1 vreg2 bb1 bb2 -- ? ) ! If vreg1 dominates vreg2, then they interfere if vreg2's definition ! occurs before vreg1 is killed. - nip compute-local-live-ranges + nip kill-after-def? ; : interferes-second-dominates? ( vreg1 vreg2 bb1 bb2 -- ? ) ! If vreg2 dominates vreg1, then they interfere if vreg1's definition ! occurs before vreg2 is killed. - drop compute-local-live-ranges - swap kill-after-def? ; + drop + swapd kill-after-def? ; PRIVATE> diff --git a/basis/compiler/cfg/coalescing/live-ranges/live-ranges.factor b/basis/compiler/cfg/coalescing/live-ranges/live-ranges.factor new file mode 100644 index 0000000000..f35a752ea6 --- /dev/null +++ b/basis/compiler/cfg/coalescing/live-ranges/live-ranges.factor @@ -0,0 +1,42 @@ +! Copyright (C) 2009 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: accessors assocs fry kernel namespaces sequences +compiler.cfg.def-use compiler.cfg.instructions +compiler.cfg.liveness compiler.cfg.rpo ; +IN: compiler.cfg.coalescing.live-ranges + +! Live ranges for interference testing + +> [ visit-insn ] each-index ; + +PRIVATE> + +: compute-live-ranges ( cfg -- ) + [ compute-local-live-ranges ] each-basic-block ; + +: def-index ( vreg bb -- n ) + def-indices get at at ; + +: kill-index ( vreg bb -- n ) + 2dup live-out key? [ 2drop 1/0. ] [ kill-indices get at at ] if ; diff --git a/basis/compiler/cfg/critical-edges/critical-edges.factor b/basis/compiler/cfg/critical-edges/critical-edges.factor new file mode 100644 index 0000000000..92b4f801d6 --- /dev/null +++ b/basis/compiler/cfg/critical-edges/critical-edges.factor @@ -0,0 +1,19 @@ +! Copyright (C) 2009 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel math accessors sequences +compiler.cfg compiler.cfg.rpo compiler.cfg.utilities ; +IN: compiler.cfg.critical-edges + +: critical-edge? ( from to -- ? ) + [ successors>> length 1 > ] [ predecessors>> length 1 > ] bi* and ; + +: split-critical-edge ( from to -- ) + f insert-basic-block ; + +: split-critical-edges ( cfg -- ) + [ + dup successors>> [ + 2dup critical-edge? + [ split-critical-edge ] [ 2drop ] if + ] with each + ] each-basic-block ; \ No newline at end of file diff --git a/basis/compiler/cfg/instructions/instructions.factor b/basis/compiler/cfg/instructions/instructions.factor index 07ebcc3ba9..066d20ddec 100644 --- a/basis/compiler/cfg/instructions/instructions.factor +++ b/basis/compiler/cfg/instructions/instructions.factor @@ -251,3 +251,10 @@ UNION: kill-vreg-insn ##alien-invoke ##alien-indirect ##alien-callback ; + +! Instructions that have complex expansions and require that the +! output registers are not equal to any of the input registers +UNION: def-is-use-insn + ##integer>bignum + ##bignum>integer + ##unbox-any-c-ptr ; \ No newline at end of file