compiler.cfg.coalescing: precompute live intervals, add support for instructions where output cannot equal an input, split critical edges
parent
e8cf50ac3e
commit
3cc71a1934
|
@ -7,10 +7,12 @@ compiler.cfg.def-use
|
||||||
compiler.cfg.utilities
|
compiler.cfg.utilities
|
||||||
compiler.cfg.dominance
|
compiler.cfg.dominance
|
||||||
compiler.cfg.instructions
|
compiler.cfg.instructions
|
||||||
|
compiler.cfg.critical-edges
|
||||||
compiler.cfg.coalescing.state
|
compiler.cfg.coalescing.state
|
||||||
compiler.cfg.coalescing.forest
|
compiler.cfg.coalescing.forest
|
||||||
compiler.cfg.coalescing.copies
|
compiler.cfg.coalescing.copies
|
||||||
compiler.cfg.coalescing.renaming
|
compiler.cfg.coalescing.renaming
|
||||||
|
compiler.cfg.coalescing.live-ranges
|
||||||
compiler.cfg.coalescing.process-blocks ;
|
compiler.cfg.coalescing.process-blocks ;
|
||||||
IN: compiler.cfg.coalescing
|
IN: compiler.cfg.coalescing
|
||||||
|
|
||||||
|
@ -49,9 +51,11 @@ SYMBOL: seen
|
||||||
|
|
||||||
: coalesce ( cfg -- cfg' )
|
: coalesce ( cfg -- cfg' )
|
||||||
init-coalescing
|
init-coalescing
|
||||||
|
dup split-critical-edges
|
||||||
dup compute-def-use
|
dup compute-def-use
|
||||||
dup compute-dominance
|
dup compute-dominance
|
||||||
dup compute-dfs
|
dup compute-dfs
|
||||||
|
dup compute-live-ranges
|
||||||
dup process-blocks
|
dup process-blocks
|
||||||
break-interferences
|
break-interferences
|
||||||
dup perform-renaming
|
dup perform-renaming
|
||||||
|
|
|
@ -7,7 +7,7 @@ IN: compiler.cfg.coalescing.copies
|
||||||
: compute-copies ( assoc -- assoc' )
|
: compute-copies ( assoc -- assoc' )
|
||||||
dup assoc-size <hashtable> [
|
dup assoc-size <hashtable> [
|
||||||
'[
|
'[
|
||||||
[ _ 2dup key? [ "OOPS" throw ] [ set-at ] if ] with each
|
[ 2dup eq? [ 2drop ] [ _ 2dup key? [ "OOPS" throw ] [ set-at ] if ] if ] with each
|
||||||
] assoc-each
|
] assoc-each
|
||||||
] keep ;
|
] keep ;
|
||||||
|
|
||||||
|
|
|
@ -2,48 +2,32 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors assocs combinators combinators.short-circuit
|
USING: accessors assocs combinators combinators.short-circuit
|
||||||
kernel math namespaces sequences locals compiler.cfg.def-use
|
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
|
IN: compiler.cfg.coalescing.interference
|
||||||
|
|
||||||
! Local interference testing. Requires live-out information
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
SYMBOLS: def-index kill-index ;
|
: kill-after-def? ( vreg1 vreg2 bb -- ? )
|
||||||
|
|
||||||
: compute-local-live-ranges ( bb -- )
|
|
||||||
H{ } clone def-index set
|
|
||||||
H{ } clone kill-index set
|
|
||||||
[
|
|
||||||
instructions>> [
|
|
||||||
[ 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 -- ? )
|
|
||||||
! If first register is killed after second one is defined, they interfere
|
! 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 -- ? )
|
: interferes-same-block? ( vreg1 vreg2 bb1 bb2 -- ? )
|
||||||
! If both are defined in the same basic block, they interfere if their
|
! If both are defined in the same basic block, they interfere if their
|
||||||
! local live ranges intersect.
|
! local live ranges intersect.
|
||||||
drop compute-local-live-ranges
|
drop
|
||||||
{ [ kill-after-def? ] [ swap kill-after-def? ] } 2|| ;
|
{ [ kill-after-def? ] [ swapd kill-after-def? ] } 3|| ;
|
||||||
|
|
||||||
: interferes-first-dominates? ( vreg1 vreg2 bb1 bb2 -- ? )
|
: interferes-first-dominates? ( vreg1 vreg2 bb1 bb2 -- ? )
|
||||||
! If vreg1 dominates vreg2, then they interfere if vreg2's definition
|
! If vreg1 dominates vreg2, then they interfere if vreg2's definition
|
||||||
! occurs before vreg1 is killed.
|
! occurs before vreg1 is killed.
|
||||||
nip compute-local-live-ranges
|
nip
|
||||||
kill-after-def? ;
|
kill-after-def? ;
|
||||||
|
|
||||||
: interferes-second-dominates? ( vreg1 vreg2 bb1 bb2 -- ? )
|
: interferes-second-dominates? ( vreg1 vreg2 bb1 bb2 -- ? )
|
||||||
! If vreg2 dominates vreg1, then they interfere if vreg1's definition
|
! If vreg2 dominates vreg1, then they interfere if vreg1's definition
|
||||||
! occurs before vreg2 is killed.
|
! occurs before vreg2 is killed.
|
||||||
drop compute-local-live-ranges
|
drop
|
||||||
swap kill-after-def? ;
|
swapd kill-after-def? ;
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
SYMBOLS: local-def-indices local-kill-indices ;
|
||||||
|
|
||||||
|
: record-defs ( n vregs -- )
|
||||||
|
local-def-indices get '[ _ set-at ] with each ;
|
||||||
|
|
||||||
|
: record-uses ( n vregs -- )
|
||||||
|
local-kill-indices get '[ _ set-at ] with each ;
|
||||||
|
|
||||||
|
: visit-insn ( insn n -- )
|
||||||
|
[ swap defs-vregs record-defs ]
|
||||||
|
[ swap uses-vregs record-uses ]
|
||||||
|
[ over def-is-use-insn? [ swap defs-vregs record-uses ] [ 2drop ] if ]
|
||||||
|
2tri ;
|
||||||
|
|
||||||
|
SYMBOLS: def-indices kill-indices ;
|
||||||
|
|
||||||
|
: compute-local-live-ranges ( bb -- )
|
||||||
|
H{ } clone local-def-indices set
|
||||||
|
H{ } clone local-kill-indices set
|
||||||
|
instructions>> [ 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 ;
|
|
@ -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 <simple-block> insert-basic-block ;
|
||||||
|
|
||||||
|
: split-critical-edges ( cfg -- )
|
||||||
|
[
|
||||||
|
dup successors>> [
|
||||||
|
2dup critical-edge?
|
||||||
|
[ split-critical-edge ] [ 2drop ] if
|
||||||
|
] with each
|
||||||
|
] each-basic-block ;
|
|
@ -251,3 +251,10 @@ UNION: kill-vreg-insn
|
||||||
##alien-invoke
|
##alien-invoke
|
||||||
##alien-indirect
|
##alien-indirect
|
||||||
##alien-callback ;
|
##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 ;
|
Loading…
Reference in New Issue