1 ! Copyright (C) 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors assocs deques dlists kernel make sorting
4 namespaces sequences combinators combinators.short-circuit
5 fry math compiler.cfg.rpo compiler.cfg.utilities
6 compiler.cfg.loop-detection compiler.cfg.predecessors
8 FROM: namespaces => set ;
9 IN: compiler.cfg.linearization.order
11 ! This is RPO except loops are rotated. Based on SBCL's src/compiler/control.lisp
15 SYMBOLS: work-list loop-heads visited ;
17 : visited? ( bb -- ? ) visited get in? ;
19 : add-to-work-list ( bb -- )
20 dup visited? [ drop ] [
21 work-list get push-back
24 : init-linearization-order ( cfg -- )
26 HS{ } clone visited set
27 entry>> add-to-work-list ;
29 : (find-alternate-loop-head) ( bb -- bb' )
31 [ predecessor visited? not ]
32 [ predecessors>> length 1 = ]
33 [ predecessor successors>> length 1 = ]
34 [ [ number>> ] [ predecessor number>> ] bi > ]
35 } 1&& [ predecessor (find-alternate-loop-head) ] when ;
37 : find-back-edge ( bb -- pred )
38 [ predecessors>> ] keep '[ _ back-edge? ] find nip ;
40 : find-alternate-loop-head ( bb -- bb' )
41 dup find-back-edge dup visited? [ drop ] [
42 nip (find-alternate-loop-head)
45 : predecessors-ready? ( bb -- ? )
46 [ predecessors>> ] keep '[
48 [ 2drop t ] [ drop visited? ] if
51 : process-successor ( bb -- )
52 dup predecessors-ready? [
53 dup loop-entry? [ find-alternate-loop-head ] when
57 : sorted-successors ( bb -- seq )
58 successors>> <reversed> [ loop-nesting-at ] sort-with ;
60 : process-block ( bb -- )
61 dup visited? [ drop ] [
63 [ visited get adjoin ]
64 [ sorted-successors [ process-successor ] each ]
68 : (linearization-order) ( cfg -- bbs )
69 init-linearization-order
71 [ work-list get [ process-block ] slurp-deque ] { } make ;
75 : linearization-order ( cfg -- bbs )
76 needs-post-order needs-loops needs-predecessors
78 dup linear-order>> [ ] [
79 dup (linearization-order)
80 >>linear-order linear-order>>