1 ! Copyright (C) 2005, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 IN: optimizer.known-words
4 USING: alien arrays generic hashtables inference.dataflow
5 inference.class kernel assocs math math.order math.private
6 kernel.private sequences words parser vectors strings sbufs io
7 namespaces assocs quotations sequences.private io.binary
8 io.streams.string layouts splitting math.intervals
9 math.floats.private classes.tuple classes.tuple.private classes
10 classes.algebra optimizer.def-use optimizer.backend
11 optimizer.pattern-match optimizer.inlining float-arrays
12 sequences.private combinators byte-arrays byte-vectors ;
14 { <tuple> <tuple-boa> } [
16 dup node-in-d peek node-literal
17 dup tuple-layout? [ layout-class ] [ drop tuple ] if
19 ] "output-classes" set-word-prop
23 dup node-in-d peek node-literal
24 dup class? [ drop tuple ] unless 1array f
25 ] "output-classes" set-word-prop
27 ! the output of clone has the same type as the input
30 node-in-d [ value-class* ] map f
31 ] "output-classes" set-word-prop
34 ! not [ A ] [ B ] if ==> [ B ] [ A ] if
35 : flip-branches? ( #call -- ? ) sole-consumer #if? ;
37 : (flip-branches) ( #if -- )
38 dup node-children reverse swap set-node-children ;
40 : flip-branches ( #call -- #if )
41 #! If a not is followed by an #if, flip branches and
43 dup sole-consumer (flip-branches) [ ] f splice-quot ;
46 { [ dup flip-branches? ] [ flip-branches ] }
49 ! eq? on objects of disjoint types is always f
50 : disjoint-eq? ( node -- ? )
51 node-input-classes first2 2dup and
52 [ classes-intersect? not ] [ 2drop f ] if ;
55 { [ dup disjoint-eq? ] [ [ f ] inline-literals ] }
58 : literal-member? ( #call -- ? )
59 node-in-d peek dup value?
60 [ value-literal sequence? ] [ drop f ] if ;
62 : expand-member ( #call quot -- )
63 >r dup node-in-d peek value-literal r> call f splice-quot ;
65 : bit-member-n 256 ; inline
67 : bit-member? ( seq -- ? )
68 #! Can we use a fast byte array test here?
70 { [ dup length 8 < ] [ f ] }
71 { [ dup [ integer? not ] contains? ] [ f ] }
72 { [ dup [ 0 < ] contains? ] [ f ] }
73 { [ dup [ bit-member-n >= ] contains? ] [ f ] }
77 : bit-member-seq ( seq -- flags )
78 bit-member-n swap [ member? 1 0 ? ] curry B{ } map-as ;
80 : exact-float? ( f -- ? )
81 dup float? [ dup >integer >float = ] [ drop f ] if ; inline
83 : bit-member-quot ( seq -- newquot )
85 [ drop ] % ! drop the sequence itself; we don't use it at run time
89 { [ over fixnum? ] [ ?nth 1 eq? ] }
90 { [ over bignum? ] [ ?nth 1 eq? ] }
91 { [ over exact-float? ] [ ?nth 1 eq? ] }
97 : member-quot ( seq -- newquot )
101 [ literalize [ t ] ] { } map>assoc
102 [ drop f ] suffix [ nip case ] curry
106 { [ dup literal-member? ] [ [ member-quot ] expand-member ] }
109 : memq-quot ( seq -- newquot )
110 [ [ dupd eq? ] curry [ drop t ] ] { } map>assoc
111 [ drop f ] suffix [ nip cond ] curry ;
114 { [ dup literal-member? ] [ [ memq-quot ] expand-member ] }
117 ! if the result of eq? is t and the second input is a literal,
118 ! the first input is equal to the second
120 dup node-in-d second dup value? [
122 value-literal 0 `input literal,
123 \ f class-not 0 `output class,
128 ] "constraints" set-word-prop
130 ! eq? on the same object is always t
132 { { @ @ } [ 2drop t ] }
136 { first first2 first3 first4 }
137 [ { array } "specializer" set-word-prop ] each
139 { peek pop* pop push } [
140 { vector } "specializer" set-word-prop
144 { { string sbuf } { array vector } { byte-array byte-vector } }
145 "specializer" set-word-prop
148 { { string string } { array array } }
149 "specializer" set-word-prop
152 { { fixnum fixnum string } { fixnum fixnum array } }
153 "specializer" set-word-prop
156 { { string } { array } }
157 "specializer" set-word-prop
161 "specializer" set-word-prop
163 \ find-last-sep { string sbuf } "specializer" set-word-prop
165 \ >string { sbuf } "specializer" set-word-prop
167 \ >array { { string } { vector } } "specializer" set-word-prop
169 \ >vector { { array } { vector } } "specializer" set-word-prop
171 \ >sbuf { string } "specializer" set-word-prop
173 \ split, { string string } "specializer" set-word-prop
175 \ memq? { array } "specializer" set-word-prop
177 \ member? { fixnum string } "specializer" set-word-prop
179 \ assoc-stack { vector } "specializer" set-word-prop
181 \ >le { { fixnum fixnum } { bignum fixnum } } "specializer" set-word-prop
183 \ >be { { bignum fixnum } { fixnum fixnum } } "specializer" set-word-prop