1 ! Copyright (C) 2004, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays assocs classes combinators cpu.architecture
4 effects generator.fixup generator.registers generic hashtables
5 inference inference.backend inference.dataflow io kernel
6 kernel.private layouts math namespaces optimizer
7 optimizer.specializers prettyprint quotations sequences system
8 threads words vectors sets dequeues ;
14 : queue-compile ( word -- )
16 { [ dup "forgotten" word-prop ] [ ] }
17 { [ dup compiled get key? ] [ ] }
18 { [ dup inlined-block? ] [ ] }
19 { [ dup primitive? ] [ ] }
20 [ dup compile-queue get push-front ]
23 : maybe-compile ( word -- )
24 dup compiled>> [ drop ] [ queue-compile ] if ;
26 SYMBOL: compiling-word
28 SYMBOL: compiling-label
30 SYMBOL: compiling-loops
32 ! Label of current word, after prologue, makes recursion faster
33 SYMBOL: current-label-start
35 : compiled-stack-traces? ( -- ? ) 59 getenv ;
37 : begin-compiling ( word label -- )
38 H{ } clone compiling-loops set
41 compiled-stack-traces?
42 compiling-word get f ?
43 1vector literal-table set
44 f compiling-label get compiled get set-at ;
46 : save-machine-code ( literals relocation labels code -- )
47 4array compiling-label get compiled get set-at ;
49 : with-generator ( node word label quot -- )
56 GENERIC: generate-node ( node -- next )
58 : generate-nodes ( node -- )
59 [ node@ generate-node ] iterate-nodes end-basic-block ;
61 : init-generate-nodes ( -- )
65 current-label-start define-label
66 current-label-start resolve-label ;
68 : generate ( node word label -- )
71 [ generate-nodes ] with-node-iterator
74 : word-dataflow ( word -- effect dataflow )
77 dup "cannot-infer" word-prop [ cannot-infer-effect ] when
78 dup "no-compile" word-prop [ cannot-infer-effect ] when
79 dup specialized-def over dup 2array 1array infer-quot
84 : intrinsics ( #call -- quot )
85 node-param "intrinsics" word-prop ;
87 : if-intrinsics ( #call -- quot )
88 node-param "if-intrinsics" word-prop ;
91 M: node generate-node drop iterate-next ;
94 dup compiling-label get eq?
95 [ drop current-label-start get ] [ %epilogue-later ] if
98 : generate-call ( label -- next )
101 dup compiling-loops get at [
114 M: #label generate-node
115 dup node-param generate-call >r
116 dup node-child over #label-word rot node-param generate
120 : compiling-loop ( word -- )
121 <label> dup resolve-label swap compiling-loops get set-at ;
123 M: #loop generate-node
125 dup node-param compiling-loop
126 node-child generate-nodes
130 : end-false-branch ( label -- )
131 tail-call? [ %return drop ] [ %jump-label ] if ;
133 : generate-branch ( node -- )
134 [ copy-templates generate-nodes ] with-scope ;
136 : generate-if ( node label -- next )
138 >r >r node-children first2 swap generate-branch
139 r> r> end-false-branch resolve-label
142 ] keep resolve-label iterate-next ;
145 [ <label> dup %jump-f ]
146 H{ { +input+ { { f "flag" } } } }
151 : dispatch-branch ( node word -- label )
157 [ generate-nodes ] with-node-iterator
161 : dispatch-branches ( node -- )
163 compiling-word get dispatch-branch
167 : generate-dispatch ( node -- )
168 %dispatch dispatch-branches init-templates ;
170 M: #dispatch generate-node
171 #! The order here is important, dispatch-branches must
172 #! run after %dispatch, so that each branch gets the
173 #! correct register state
175 generate-dispatch iterate-next
177 compiling-word get gensym [
186 : define-intrinsics ( word intrinsics -- )
187 "intrinsics" set-word-prop ;
189 : define-intrinsic ( word quot assoc -- )
190 2array 1array define-intrinsics ;
192 : define-if>branch-intrinsics ( word intrinsics -- )
193 "if-intrinsics" set-word-prop ;
195 : if>boolean-intrinsic ( quot -- )
198 "false" get swap call
199 t "if-scratch" get load-literal
200 "end" get %jump-label
201 "false" resolve-label
202 f "if-scratch" get load-literal
204 "if-scratch" get phantom-push ; inline
206 : define-if>boolean-intrinsics ( word intrinsics -- )
208 >r [ if>boolean-intrinsic ] curry r>
209 { { f "if-scratch" } } +scratch+ associate assoc-union
210 ] assoc-map "intrinsics" set-word-prop ;
212 : define-if-intrinsics ( word intrinsics -- )
213 [ +input+ associate ] assoc-map
214 2dup define-if>branch-intrinsics
215 define-if>boolean-intrinsics ;
217 : define-if-intrinsic ( word quot inputs -- )
218 2array 1array define-if-intrinsics ;
220 : do-if-intrinsic ( pair -- next )
223 node> node-successor dup >node
226 : find-intrinsic ( #call -- pair/f )
227 intrinsics find-template ;
229 : find-if-intrinsic ( #call -- pair/f )
230 dup node-successor #if? [
231 if-intrinsics find-template
236 M: #call generate-node
237 dup node-input-classes set-operand-classes
238 dup find-if-intrinsic [
242 do-template iterate-next
244 node-param generate-call
249 M: #call-label generate-node node-param generate-call ;
252 M: #push generate-node
253 node-out-d [ value-literal <constant> phantom-push ] each
257 M: #shuffle generate-node
258 node-shuffle phantom-shuffle iterate-next ;
271 M: #return generate-node
273 node-param compiling-loops get key?
274 [ %return ] unless f ;