1 ! Copyright (C) 2008, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: kernel math accessors sequences namespaces make
4 combinators assocs arrays locals layouts hashtables
7 compiler.cfg.comparisons
8 compiler.cfg.stack-frame
9 compiler.cfg.instructions
10 compiler.cfg.utilities
11 compiler.cfg.linearization.order ;
12 IN: compiler.cfg.linearization
18 : block-number ( bb -- n ) numbers get at ;
20 : number-blocks ( bbs -- ) [ 2array ] map-index >hashtable numbers set ;
22 ! Convert CFG IR to machine IR.
23 GENERIC: linearize-insn ( basic-block insn -- )
25 : linearize-basic-block ( bb -- )
26 [ block-number _label ]
27 [ dup instructions>> [ linearize-insn ] with each ]
30 M: insn linearize-insn , drop ;
32 : useless-branch? ( basic-block successor -- ? )
33 ! If our successor immediately follows us in linearization
34 ! order then we don't need to branch.
35 [ block-number ] bi@ 1 - = ; inline
37 : emit-branch ( bb successor -- )
38 2dup useless-branch? [ 2drop ] [ nip block-number _branch ] if ;
40 M: ##branch linearize-insn
41 drop dup successors>> first emit-branch ;
43 : successors ( bb -- first second ) successors>> first2 ; inline
45 : (binary-conditional) ( bb insn -- bb successor1 successor2 src1 src2 cc )
47 [ [ src1>> ] [ src2>> ] [ cc>> ] tri ] bi* ; inline
49 : binary-conditional ( bb insn -- bb successor label2 src1 src2 cc )
50 [ (binary-conditional) ]
51 [ drop dup successors>> second useless-branch? ] 2bi
52 [ [ swap block-number ] 3dip ] [ [ block-number ] 3dip negate-cc ] if ;
54 M: ##compare-branch linearize-insn
55 binary-conditional _compare-branch emit-branch ;
57 M: ##compare-imm-branch linearize-insn
58 binary-conditional _compare-imm-branch emit-branch ;
60 M: ##compare-float-ordered-branch linearize-insn
61 binary-conditional _compare-float-ordered-branch emit-branch ;
63 M: ##compare-float-unordered-branch linearize-insn
64 binary-conditional _compare-float-unordered-branch emit-branch ;
66 : overflow-conditional ( bb insn -- bb successor label2 dst src1 src2 )
67 [ dup successors block-number ]
68 [ [ dst>> ] [ src1>> ] [ src2>> ] tri ] bi* ; inline
70 M: ##fixnum-add linearize-insn
71 overflow-conditional _fixnum-add emit-branch ;
73 M: ##fixnum-sub linearize-insn
74 overflow-conditional _fixnum-sub emit-branch ;
76 M: ##fixnum-mul linearize-insn
77 overflow-conditional _fixnum-mul emit-branch ;
79 M: ##dispatch linearize-insn
81 [ [ src>> ] [ temp>> ] bi _dispatch ]
82 [ successors>> [ block-number _dispatch-label ] each ]
85 : gc-root-offsets ( registers -- alist )
86 ! Outputs a sequence of { offset register/spill-slot } pairs
87 [ length iota [ cell * ] map ] keep zip ;
89 M: ##gc linearize-insn
95 [ tagged-values>> gc-root-offsets ]
96 [ uninitialized-locs>> ]
100 : linearize-basic-blocks ( cfg -- insns )
105 [ [ linearize-basic-block ] each ] bi
106 ] [ spill-area-size>> _spill-area-size ] bi
111 : flatten-cfg ( cfg -- mr )
112 [ linearize-basic-blocks ] [ word>> ] [ label>> ] tri