1 ! Copyright (C) 2008, 2010 Slava Pestov, Daniel Ehrenberg.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: alien.c-types kernel sequences words fry generic accessors
4 classes.tuple classes classes.algebra definitions
5 stack-checker.dependencies quotations classes.tuple.private math
6 math.partial-dispatch math.private math.intervals new-sets.private
7 math.floats.private math.integers.private layouts math.order
8 vectors hashtables combinators effects generalizations assocs
9 new-sets combinators.short-circuit sequences.private locals growable
10 stack-checker namespaces compiler.tree.propagation.info ;
12 FROM: new-sets => set ;
13 IN: compiler.tree.propagation.transforms
16 ! If first input has a known type and second input is an
17 ! object, we convert this to [ swap equal? ].
18 in-d>> first2 value-info class>> object class= [
19 value-info class>> \ equal? method-for-class
22 ] "custom-inlining" set-word-prop
24 : rem-custom-inlining ( #call -- quot/f )
25 second value-info literal>> dup integer?
26 [ power-of-2? [ 1 - bitand ] f ? ] [ drop f ] if ;
35 in-d>> dup first value-info interval>> [0,inf] interval-subset?
36 [ rem-custom-inlining ] [ drop f ] if
37 ] "custom-inlining" set-word-prop
41 in-d>> rem-custom-inlining
42 ] "custom-inlining" set-word-prop
44 : positive-fixnum? ( obj -- ? )
45 { [ fixnum? ] [ 0 >= ] } 1&& ;
47 : simplify-bitand? ( value1 value2 -- ? )
48 [ literal>> positive-fixnum? ]
49 [ class>> fixnum swap class<= ]
52 : all-ones? ( n -- ? ) dup 1 + bitand zero? ; inline
54 : redundant-bitand? ( value1 value2 -- ? )
55 [ interval>> ] [ literal>> ] bi* {
58 [ 0 swap [a,b] interval-subset? ]
61 : zero-bitand? ( value1 value2 -- ? )
62 [ interval>> ] [ literal>> ] bi* {
64 [ nip bitnot all-ones? ]
65 [ 0 swap bitnot [a,b] interval-subset? ]
69 bitand-integer-integer
75 in-d>> first2 [ value-info ] bi@ {
81 [ 2dup swap zero-bitand? ]
85 [ 2dup redundant-bitand? ]
89 [ 2dup swap redundant-bitand? ]
93 [ 2dup simplify-bitand? ]
94 [ 2drop [ >fixnum fixnum-bitand ] ]
97 [ 2dup swap simplify-bitand? ]
98 [ 2drop [ [ >fixnum ] dip fixnum-bitand ] ]
102 ] "custom-inlining" set-word-prop
107 in-d>> first value-info literal>> 1 eq? ;
111 cell-bits tag-bits get - 1 -
113 >fixnum dup 0 < [ 2drop 0 ] [
114 dup _ < [ fixnum-shift ] [
120 ] "custom-inlining" set-word-prop
122 { /i fixnum/i fixnum/i-fast bignum/i } [
124 in-d>> first2 [ value-info ] bi@ {
125 [ drop class>> integer class<= ]
126 [ drop interval>> 0 [a,a] interval>= ]
127 [ nip literal>> integer? ]
128 [ nip literal>> power-of-2? ]
129 } 2&& [ [ log2 neg shift ] ] [ f ] if
130 ] "custom-inlining" set-word-prop
133 ! Generate more efficient code for common idiom
135 in-d>> first value-info literal>> {
136 { V{ } [ [ drop { } 0 vector boa ] ] }
137 { H{ } [ [ drop 0 <hashtable> ] ] }
138 { HS{ } [ [ drop f fast-set ] ] }
141 ] "custom-inlining" set-word-prop
143 ERROR: bad-partial-eval quot word ;
145 : check-effect ( quot word -- )
146 2dup [ infer ] [ stack-effect ] bi* effect<=
147 [ 2drop ] [ bad-partial-eval ] if ;
149 :: define-partial-eval ( word quot n -- )
153 dup [ literal?>> ] all? [
158 dup word check-effect
161 ] "custom-inlining" set-word-prop ;
163 : inline-new ( class -- quot/f )
166 [ depends-on-tuple-layout ]
167 [ drop all-slots [ initial>> literalize ] [ ] map-as ]
173 \ new [ inline-new ] 1 define-partial-eval
177 [ "predicate" word-prop ] [ drop f ] if
178 ] 1 define-partial-eval
181 : nths-quot ( indices -- quot )
182 [ [ '[ _ swap nth ] ] map ] [ length ] bi
183 '[ _ cleave _ narray ] ;
186 shuffle-mapping nths-quot
187 ] 1 define-partial-eval
193 dup length iota zip >hashtable '[ _ at ]
196 ] 1 define-partial-eval
198 : member-eq-quot ( seq -- newquot )
199 [ [ dupd eq? ] curry [ drop t ] ] { } map>assoc
200 [ drop f ] suffix [ cond ] curry ;
203 dup sequence? [ member-eq-quot ] [ drop f ] if
204 ] 1 define-partial-eval
207 : member-quot ( seq -- newquot )
210 [ literalize [ t ] ] { } map>assoc linear-case-quot
216 dup sequence? [ member-quot ] [ drop f ] if
217 ] 1 define-partial-eval
219 ! Fast at for integer maps
220 CONSTANT: lookup-table-at-max 256
222 : lookup-table-at? ( assoc -- ? )
223 #! Can we use a fast byte array test here?
227 [ keys [ integer? ] all? ]
228 [ keys [ 0 lookup-table-at-max between? ] all? ]
231 : lookup-table-seq ( assoc -- table )
232 [ keys supremum 1 + iota ] keep '[ _ at ] { } map-as ;
234 : lookup-table-quot ( seq -- newquot )
239 nth-unsafe dup >boolean
244 : fast-lookup-table-at? ( assoc -- ? )
246 [ [ integer? ] all? ]
247 [ [ 0 254 between? ] all? ]
250 : fast-lookup-table-seq ( assoc -- table )
251 lookup-table-seq [ 255 or ] B{ } map-as ;
253 : fast-lookup-table-quot ( seq -- newquot )
254 fast-lookup-table-seq
258 nth-unsafe dup 255 eq? [ drop f f ] [ t ] if
263 : at-quot ( assoc -- quot )
265 dup lookup-table-at? [
266 dup fast-lookup-table-at? [
267 fast-lookup-table-quot
274 \ at* [ at-quot ] 1 define-partial-eval
276 : diff-quot ( seq -- quot: ( seq' -- seq'' ) )
277 tester '[ [ [ @ not ] filter ] keep set-like ] ;
279 M\ set diff [ diff-quot ] 1 define-partial-eval
281 : intersect-quot ( seq -- quot: ( seq' -- seq'' ) )
282 tester '[ [ _ filter ] keep set-like ] ;
284 M\ set intersect [ intersect-quot ] 1 define-partial-eval
286 : fixnum-bits ( -- n )
287 cell-bits tag-bits get - ;
289 : bit-quot ( #call -- quot/f )
290 in-d>> second value-info interval>> 0 fixnum-bits [a,b] interval-subset?
291 [ [ >fixnum ] dip fixnum-bit? ] f ? ;
293 \ bit? [ bit-quot ] "custom-inlining" set-word-prop
295 ! Speeds up sum-file, sort and reverse-complement benchmarks by
296 ! compiling decoder-readln better
298 in-d>> second value-info class>> growable class<=
299 [ \ push def>> ] [ f ] if
300 ] "custom-inlining" set-word-prop
302 ! We want to constant-fold calls to heap-size, and recompile those
303 ! calls when a C type is redefined
306 [ depends-on-definition ] [ heap-size '[ _ ] ] bi
308 ] 1 define-partial-eval