2009-07-26 22:11:26 -04:00
|
|
|
! Copyright (C) 2009 Slava Pestov.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2009-08-02 11:26:52 -04:00
|
|
|
USING: accessors assocs combinators combinators.short-circuit fry
|
|
|
|
kernel math math.order sorting namespaces sequences locals
|
|
|
|
compiler.cfg.def-use compiler.cfg.dominance
|
|
|
|
compiler.cfg.ssa.interference.live-ranges ;
|
2009-08-02 09:15:36 -04:00
|
|
|
IN: compiler.cfg.ssa.interference
|
2009-07-26 22:11:26 -04:00
|
|
|
|
|
|
|
<PRIVATE
|
|
|
|
|
2009-08-02 09:11:30 -04:00
|
|
|
:: kill-after-def? ( vreg1 vreg2 bb -- ? )
|
2009-07-28 07:48:20 -04:00
|
|
|
! If first register is used after second one is defined, they interfere.
|
|
|
|
! If they are used in the same instruction, no interference. If the
|
|
|
|
! instruction is a def-is-use-insn, then there will be a use at +1
|
|
|
|
! (instructions are 2 apart) and so outputs will interfere with
|
|
|
|
! inputs.
|
2009-08-02 09:11:30 -04:00
|
|
|
vreg1 bb kill-index
|
|
|
|
vreg2 bb def-index > ;
|
2009-07-26 22:11:26 -04:00
|
|
|
|
2009-08-02 09:11:30 -04:00
|
|
|
:: interferes-same-block? ( vreg1 vreg2 bb1 bb2 -- ? )
|
2009-07-26 22:11:26 -04:00
|
|
|
! If both are defined in the same basic block, they interfere if their
|
|
|
|
! local live ranges intersect.
|
2009-08-02 09:11:30 -04:00
|
|
|
vreg1 bb1 def-index
|
|
|
|
vreg2 bb1 def-index <
|
|
|
|
[ vreg1 vreg2 ] [ vreg2 vreg1 ] if
|
|
|
|
bb1 kill-after-def? ;
|
2009-07-26 22:11:26 -04:00
|
|
|
|
2009-07-27 01:31:21 -04:00
|
|
|
: interferes-first-dominates? ( vreg1 vreg2 bb1 bb2 -- ? )
|
2009-07-26 22:11:26 -04:00
|
|
|
! If vreg1 dominates vreg2, then they interfere if vreg2's definition
|
|
|
|
! occurs before vreg1 is killed.
|
2009-07-27 23:29:17 -04:00
|
|
|
nip
|
2009-07-26 22:11:26 -04:00
|
|
|
kill-after-def? ;
|
|
|
|
|
2009-07-27 01:31:21 -04:00
|
|
|
: interferes-second-dominates? ( vreg1 vreg2 bb1 bb2 -- ? )
|
2009-07-26 22:11:26 -04:00
|
|
|
! If vreg2 dominates vreg1, then they interfere if vreg1's definition
|
|
|
|
! occurs before vreg2 is killed.
|
2009-07-27 23:29:17 -04:00
|
|
|
drop
|
|
|
|
swapd kill-after-def? ;
|
2009-07-26 22:11:26 -04:00
|
|
|
|
|
|
|
PRIVATE>
|
|
|
|
|
2009-07-27 01:31:21 -04:00
|
|
|
: interferes? ( vreg1 vreg2 -- ? )
|
|
|
|
2dup [ def-of ] bi@ {
|
|
|
|
{ [ 2dup eq? ] [ interferes-same-block? ] }
|
|
|
|
{ [ 2dup dominates? ] [ interferes-first-dominates? ] }
|
|
|
|
{ [ 2dup swap dominates? ] [ interferes-second-dominates? ] }
|
|
|
|
[ 2drop 2drop f ]
|
|
|
|
} cond ;
|
2009-08-02 11:26:52 -04:00
|
|
|
|
|
|
|
! Debug this stuff later
|
|
|
|
|
|
|
|
: quadratic-test? ( seq1 seq2 -- ? ) [ length ] bi@ + 10 < ;
|
|
|
|
|
|
|
|
: quadratic-test ( seq1 seq2 -- ? )
|
|
|
|
'[ _ [ interferes? ] with any? ] any? ;
|
|
|
|
|
|
|
|
: sort-vregs-by-bb ( vregs -- alist )
|
|
|
|
defs get
|
|
|
|
'[ dup _ at ] { } map>assoc
|
|
|
|
[ [ second pre-of ] compare ] sort ;
|
|
|
|
|
|
|
|
: ?last ( seq -- elt/f ) [ f ] [ last ] if-empty ; inline
|
|
|
|
|
|
|
|
: find-parent ( dom current -- parent )
|
|
|
|
over empty? [ 2drop f ] [
|
|
|
|
over last over dominates? [ drop last ] [
|
|
|
|
[ pop* ] dip find-parent
|
|
|
|
] if
|
|
|
|
] if ;
|
|
|
|
|
|
|
|
:: linear-test ( seq1 seq2 -- ? )
|
|
|
|
V{ } clone :> dom
|
|
|
|
seq1 seq2 append sort-vregs-by-bb [| pair |
|
|
|
|
pair first :> current
|
|
|
|
dom current find-parent
|
|
|
|
dup [ current interferes? ] when
|
|
|
|
[ t ] [ current dom push f ] if
|
|
|
|
] any? ;
|