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 compiled get key? ] [ drop ] }
17 { [ dup inlined-block? ] [ drop ] }
18 { [ dup primitive? ] [ drop ] }
19 [ compile-queue get push-front ]
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 )
76 dup "cannot-infer" word-prop [ cannot-infer-effect ] when
77 dup "no-compile" word-prop [ cannot-infer-effect ] when
78 dup specialized-def over dup 2array 1array infer-quot
83 : intrinsics ( #call -- quot )
84 node-param "intrinsics" word-prop ;
86 : if-intrinsics ( #call -- quot )
87 node-param "if-intrinsics" word-prop ;
90 M: node generate-node drop iterate-next ;
93 dup compiling-label get eq?
94 [ drop current-label-start get ] [ %epilogue-later ] if
97 : generate-call ( label -- next )
100 dup compiling-loops get at [
113 M: #label generate-node
114 dup node-param generate-call >r
115 dup node-child over #label-word rot node-param generate
119 : compiling-loop ( word -- )
120 <label> dup resolve-label swap compiling-loops get set-at ;
122 M: #loop generate-node
124 dup node-param compiling-loop
125 node-child generate-nodes
129 : end-false-branch ( label -- )
130 tail-call? [ %return drop ] [ %jump-label ] if ;
132 : generate-branch ( node -- )
133 [ copy-templates generate-nodes ] with-scope ;
135 : generate-if ( node label -- next )
137 >r >r node-children first2 swap generate-branch
138 r> r> end-false-branch resolve-label
141 ] keep resolve-label iterate-next ;
144 [ <label> dup %jump-f ]
145 H{ { +input+ { { f "flag" } } } }
150 : dispatch-branch ( node word -- label )
156 [ generate-nodes ] with-node-iterator
160 : dispatch-branches ( node -- )
162 compiling-word get dispatch-branch
166 : generate-dispatch ( node -- )
167 %dispatch dispatch-branches init-templates ;
169 M: #dispatch generate-node
170 #! The order here is important, dispatch-branches must
171 #! run after %dispatch, so that each branch gets the
172 #! correct register state
174 generate-dispatch iterate-next
176 compiling-word get gensym [
185 : define-intrinsics ( word intrinsics -- )
186 "intrinsics" set-word-prop ;
188 : define-intrinsic ( word quot assoc -- )
189 2array 1array define-intrinsics ;
191 : define-if>branch-intrinsics ( word intrinsics -- )
192 "if-intrinsics" set-word-prop ;
194 : if>boolean-intrinsic ( quot -- )
197 "false" get swap call
198 t "if-scratch" get load-literal
199 "end" get %jump-label
200 "false" resolve-label
201 f "if-scratch" get load-literal
203 "if-scratch" get phantom-push ; inline
205 : define-if>boolean-intrinsics ( word intrinsics -- )
207 >r [ if>boolean-intrinsic ] curry r>
208 { { f "if-scratch" } } +scratch+ associate assoc-union
209 ] assoc-map "intrinsics" set-word-prop ;
211 : define-if-intrinsics ( word intrinsics -- )
212 [ +input+ associate ] assoc-map
213 2dup define-if>branch-intrinsics
214 define-if>boolean-intrinsics ;
216 : define-if-intrinsic ( word quot inputs -- )
217 2array 1array define-if-intrinsics ;
219 : do-if-intrinsic ( pair -- next )
222 node> node-successor dup >node
225 : find-intrinsic ( #call -- pair/f )
226 intrinsics find-template ;
228 : find-if-intrinsic ( #call -- pair/f )
229 dup node-successor #if? [
230 if-intrinsics find-template
235 M: #call generate-node
236 dup node-input-classes set-operand-classes
237 dup find-if-intrinsic [
241 do-template iterate-next
243 node-param generate-call
248 M: #call-label generate-node node-param generate-call ;
251 M: #push generate-node
252 node-out-d [ value-literal <constant> phantom-push ] each
256 M: #shuffle generate-node
257 node-shuffle phantom-shuffle iterate-next ;
270 M: #return generate-node
272 node-param compiling-loops get key?
273 [ %return ] unless f ;