1 ! Copyright (C) 2004, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: 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 ;
14 : queue-compile ( word -- )
16 { [ dup compiled get key? ] [ drop ] }
17 { [ dup inlined-block? ] [ drop ] }
18 { [ dup primitive? ] [ drop ] }
19 [ dup compile-queue get set-at ]
22 : maybe-compile ( word -- )
23 dup compiled? [ drop ] [ queue-compile ] if ;
25 SYMBOL: compiling-word
27 SYMBOL: compiling-label
29 SYMBOL: compiling-loops
31 ! Label of current word, after prologue, makes recursion faster
32 SYMBOL: current-label-start
34 : compiled-stack-traces? ( -- ? ) 36 getenv ;
36 : begin-compiling ( word label -- )
37 H{ } clone compiling-loops set
40 compiled-stack-traces?
41 compiling-word get f ?
42 1vector literal-table set
43 f compiling-label get compiled get set-at ;
45 : save-machine-code ( literals relocation labels code -- )
46 4array compiling-label get compiled get set-at ;
48 : with-generator ( node word label quot -- )
55 GENERIC: generate-node ( node -- next )
57 : generate-nodes ( node -- )
58 [ node@ generate-node ] iterate-nodes end-basic-block ;
60 : init-generate-nodes ( -- )
64 current-label-start define-label
65 current-label-start resolve-label ;
67 : generate ( node word label -- )
70 [ generate-nodes ] with-node-iterator
73 : word-dataflow ( word -- effect dataflow )
75 dup "no-effect" word-prop [ no-effect ] when
76 dup "no-compile" word-prop [ no-effect ] when
77 dup specialized-def over dup 2array 1array infer-quot
81 : intrinsics ( #call -- quot )
82 node-param "intrinsics" word-prop ;
84 : if-intrinsics ( #call -- quot )
85 node-param "if-intrinsics" word-prop ;
88 M: node generate-node drop iterate-next ;
91 dup compiling-label get eq?
92 [ drop current-label-start get ] [ %epilogue-later ] if
95 : generate-call ( label -- next )
98 dup compiling-loops get at [
111 M: #label generate-node
112 dup node-param generate-call >r
113 dup node-child over #label-word rot node-param generate
117 : compiling-loop ( word -- )
118 <label> dup resolve-label swap compiling-loops get set-at ;
120 M: #loop generate-node
122 dup node-param compiling-loop
123 node-child generate-nodes
127 : end-false-branch ( label -- )
128 tail-call? [ %return drop ] [ %jump-label ] if ;
130 : generate-branch ( node -- )
131 [ copy-templates generate-nodes ] with-scope ;
133 : generate-if ( node label -- next )
135 >r >r node-children first2 swap generate-branch
136 r> r> end-false-branch resolve-label
139 ] keep resolve-label iterate-next ;
142 [ <label> dup %jump-f ]
143 H{ { +input+ { { f "flag" } } } }
148 : dispatch-branch ( node word -- label )
154 [ generate-nodes ] with-node-iterator
158 : dispatch-branches ( node -- )
160 compiling-word get dispatch-branch
164 : generate-dispatch ( node -- )
165 %dispatch dispatch-branches init-templates ;
167 M: #dispatch generate-node
168 #! The order here is important, dispatch-branches must
169 #! run after %dispatch, so that each branch gets the
170 #! correct register state
172 generate-dispatch iterate-next
174 compiling-word get gensym [
183 : define-intrinsics ( word intrinsics -- )
184 "intrinsics" set-word-prop ;
186 : define-intrinsic ( word quot assoc -- )
187 2array 1array define-intrinsics ;
189 : define-if>branch-intrinsics ( word intrinsics -- )
190 "if-intrinsics" set-word-prop ;
192 : if>boolean-intrinsic ( quot -- )
195 "false" get swap call
196 t "if-scratch" get load-literal
197 "end" get %jump-label
198 "false" resolve-label
199 f "if-scratch" get load-literal
201 "if-scratch" get phantom-push ; inline
203 : define-if>boolean-intrinsics ( word intrinsics -- )
205 >r [ if>boolean-intrinsic ] curry r>
206 { { f "if-scratch" } } +scratch+ associate assoc-union
207 ] assoc-map "intrinsics" set-word-prop ;
209 : define-if-intrinsics ( word intrinsics -- )
210 [ +input+ associate ] assoc-map
211 2dup define-if>branch-intrinsics
212 define-if>boolean-intrinsics ;
214 : define-if-intrinsic ( word quot inputs -- )
215 2array 1array define-if-intrinsics ;
217 : do-if-intrinsic ( pair -- next )
220 node> node-successor dup >node
223 : find-intrinsic ( #call -- pair/f )
224 intrinsics find-template ;
226 : find-if-intrinsic ( #call -- pair/f )
227 dup node-successor #if? [
228 if-intrinsics find-template
233 M: #call generate-node
234 dup node-input-classes set-operand-classes
235 dup find-if-intrinsic [
239 do-template iterate-next
241 node-param generate-call
246 M: #call-label generate-node node-param generate-call ;
249 M: #push generate-node
250 node-out-d [ value-literal <constant> phantom-push ] each
254 M: #shuffle generate-node
255 node-shuffle phantom-shuffle iterate-next ;
268 M: #return generate-node
270 node-param compiling-loops get key?
271 [ %return ] unless f ;