define-partial-eval framework in propagation pass makes it easy to add transforms; moving some transforms from stack checker to propagation, making them stronger
parent
b4c522f045
commit
ee3e84a1f8
|
@ -14,7 +14,8 @@ compiler.tree.propagation.nodes
|
||||||
compiler.tree.propagation.slots
|
compiler.tree.propagation.slots
|
||||||
compiler.tree.propagation.simple
|
compiler.tree.propagation.simple
|
||||||
compiler.tree.propagation.constraints
|
compiler.tree.propagation.constraints
|
||||||
compiler.tree.propagation.call-effect ;
|
compiler.tree.propagation.call-effect
|
||||||
|
compiler.tree.propagation.transforms ;
|
||||||
IN: compiler.tree.propagation.known-words
|
IN: compiler.tree.propagation.known-words
|
||||||
|
|
||||||
\ fixnum
|
\ fixnum
|
||||||
|
@ -227,39 +228,6 @@ generic-comparison-ops [
|
||||||
] "outputs" set-word-prop
|
] "outputs" set-word-prop
|
||||||
] assoc-each
|
] assoc-each
|
||||||
|
|
||||||
: rem-custom-inlining ( #call -- quot/f )
|
|
||||||
second value-info literal>> dup integer?
|
|
||||||
[ power-of-2? [ 1- bitand ] f ? ] [ drop f ] if ;
|
|
||||||
|
|
||||||
{
|
|
||||||
mod-integer-integer
|
|
||||||
mod-integer-fixnum
|
|
||||||
mod-fixnum-integer
|
|
||||||
fixnum-mod
|
|
||||||
} [
|
|
||||||
[
|
|
||||||
in-d>> dup first value-info interval>> [0,inf] interval-subset?
|
|
||||||
[ rem-custom-inlining ] [ drop f ] if
|
|
||||||
] "custom-inlining" set-word-prop
|
|
||||||
] each
|
|
||||||
|
|
||||||
\ rem [
|
|
||||||
in-d>> rem-custom-inlining
|
|
||||||
] "custom-inlining" set-word-prop
|
|
||||||
|
|
||||||
{
|
|
||||||
bitand-integer-integer
|
|
||||||
bitand-integer-fixnum
|
|
||||||
bitand-fixnum-integer
|
|
||||||
} [
|
|
||||||
[
|
|
||||||
in-d>> second value-info >literal< [
|
|
||||||
0 most-positive-fixnum between?
|
|
||||||
[ [ >fixnum ] bi@ fixnum-bitand ] f ?
|
|
||||||
] when
|
|
||||||
] "custom-inlining" set-word-prop
|
|
||||||
] each
|
|
||||||
|
|
||||||
{ numerator denominator }
|
{ numerator denominator }
|
||||||
[ [ drop integer <class-info> ] "outputs" set-word-prop ] each
|
[ [ drop integer <class-info> ] "outputs" set-word-prop ] each
|
||||||
|
|
||||||
|
@ -314,15 +282,6 @@ generic-comparison-ops [
|
||||||
"outputs" set-word-prop
|
"outputs" set-word-prop
|
||||||
] each
|
] each
|
||||||
|
|
||||||
! Generate more efficient code for common idiom
|
|
||||||
\ clone [
|
|
||||||
in-d>> first value-info literal>> {
|
|
||||||
{ V{ } [ [ drop { } 0 vector boa ] ] }
|
|
||||||
{ H{ } [ [ drop 0 <hashtable> ] ] }
|
|
||||||
[ drop f ]
|
|
||||||
} case
|
|
||||||
] "custom-inlining" set-word-prop
|
|
||||||
|
|
||||||
\ slot [
|
\ slot [
|
||||||
dup literal?>>
|
dup literal?>>
|
||||||
[ literal>> swap value-info-slot ] [ 2drop object-info ] if
|
[ literal>> swap value-info-slot ] [ 2drop object-info ] if
|
||||||
|
@ -346,29 +305,3 @@ generic-comparison-ops [
|
||||||
bi
|
bi
|
||||||
] [ 2drop object-info ] if
|
] [ 2drop object-info ] if
|
||||||
] "outputs" set-word-prop
|
] "outputs" set-word-prop
|
||||||
|
|
||||||
\ instance? [
|
|
||||||
in-d>> second value-info literal>> dup class?
|
|
||||||
[ "predicate" word-prop '[ drop @ ] ] [ drop f ] if
|
|
||||||
] "custom-inlining" set-word-prop
|
|
||||||
|
|
||||||
\ equal? [
|
|
||||||
! If first input has a known type and second input is an
|
|
||||||
! object, we convert this to [ swap equal? ].
|
|
||||||
in-d>> first2 value-info class>> object class= [
|
|
||||||
value-info class>> \ equal? specific-method
|
|
||||||
[ swap equal? ] f ?
|
|
||||||
] [ drop f ] if
|
|
||||||
] "custom-inlining" set-word-prop
|
|
||||||
|
|
||||||
: inline-new ( class -- quot/f )
|
|
||||||
dup tuple-class? [
|
|
||||||
dup inlined-dependency depends-on
|
|
||||||
[ all-slots [ initial>> literalize ] map ]
|
|
||||||
[ tuple-layout '[ _ <tuple-boa> ] ]
|
|
||||||
bi append [ drop ] prepend >quotation
|
|
||||||
] [ drop f ] if ;
|
|
||||||
|
|
||||||
\ new [
|
|
||||||
in-d>> first value-info literal>> inline-new
|
|
||||||
] "custom-inlining" set-word-prop
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ compiler.tree.propagation.info compiler.tree.def-use
|
||||||
compiler.tree.debugger compiler.tree.checker
|
compiler.tree.debugger compiler.tree.checker
|
||||||
slots.private words hashtables classes assocs locals
|
slots.private words hashtables classes assocs locals
|
||||||
specialized-arrays.double system sorting math.libm
|
specialized-arrays.double system sorting math.libm
|
||||||
math.intervals quotations ;
|
math.intervals quotations effects ;
|
||||||
IN: compiler.tree.propagation.tests
|
IN: compiler.tree.propagation.tests
|
||||||
|
|
||||||
[ V{ } ] [ [ ] final-classes ] unit-test
|
[ V{ } ] [ [ ] final-classes ] unit-test
|
||||||
|
@ -717,3 +717,26 @@ M: number whatever drop foo ;
|
||||||
: that-thing ( -- class ) foo ;
|
: that-thing ( -- class ) foo ;
|
||||||
|
|
||||||
[ f ] [ [ that-thing new ] { new } inlined? ] unit-test
|
[ f ] [ [ that-thing new ] { new } inlined? ] unit-test
|
||||||
|
|
||||||
|
GENERIC: whatever2 ( x -- y )
|
||||||
|
M: number whatever2 drop H{ { 1 1 } { 2 2 } { 3 3 } { 4 4 } { 5 6 } } ;
|
||||||
|
M: f whatever2 ;
|
||||||
|
|
||||||
|
[ t ] [ [ 1 whatever2 at ] { at* hashcode* } inlined? ] unit-test
|
||||||
|
[ f ] [ [ whatever2 at ] { at* hashcode* } inlined? ] unit-test
|
||||||
|
|
||||||
|
[ t ] [ [ { 1 2 3 } member? ] { member? } inlined? ] unit-test
|
||||||
|
[ f ] [ [ { 1 2 3 } swap member? ] { member? } inlined? ] unit-test
|
||||||
|
|
||||||
|
[ t ] [ [ { 1 2 3 } memq? ] { memq? } inlined? ] unit-test
|
||||||
|
[ f ] [ [ { 1 2 3 } swap memq? ] { memq? } inlined? ] unit-test
|
||||||
|
|
||||||
|
[ t ] [ [ V{ } clone ] { clone (clone) } inlined? ] unit-test
|
||||||
|
[ f ] [ [ { } clone ] { clone (clone) } inlined? ] unit-test
|
||||||
|
|
||||||
|
[ f ] [ [ instance? ] { instance? } inlined? ] unit-test
|
||||||
|
[ f ] [ [ 5 instance? ] { instance? } inlined? ] unit-test
|
||||||
|
[ t ] [ [ array instance? ] { instance? } inlined? ] unit-test
|
||||||
|
|
||||||
|
[ t ] [ [ (( a b c -- c b a )) shuffle ] { shuffle } inlined? ] unit-test
|
||||||
|
[ f ] [ [ { 1 2 3 } swap shuffle ] { shuffle } inlined? ] unit-test
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Slava Pestov
|
||||||
|
Daniel Ehrenberg
|
|
@ -0,0 +1,195 @@
|
||||||
|
! Copyright (C) 2008, 2009 Slava Pestov, Daniel Ehrenberg.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: kernel sequences words fry generic accessors classes.tuple
|
||||||
|
classes classes.algebra definitions stack-checker.state quotations
|
||||||
|
classes.tuple.private math math.partial-dispatch math.private
|
||||||
|
math.intervals layouts math.order vectors hashtables
|
||||||
|
combinators effects generalizations assocs sets
|
||||||
|
combinators.short-circuit sequences.private locals
|
||||||
|
stack-checker
|
||||||
|
compiler.tree.propagation.info ;
|
||||||
|
IN: compiler.tree.propagation.transforms
|
||||||
|
|
||||||
|
\ equal? [
|
||||||
|
! If first input has a known type and second input is an
|
||||||
|
! object, we convert this to [ swap equal? ].
|
||||||
|
in-d>> first2 value-info class>> object class= [
|
||||||
|
value-info class>> \ equal? specific-method
|
||||||
|
[ swap equal? ] f ?
|
||||||
|
] [ drop f ] if
|
||||||
|
] "custom-inlining" set-word-prop
|
||||||
|
|
||||||
|
: rem-custom-inlining ( #call -- quot/f )
|
||||||
|
second value-info literal>> dup integer?
|
||||||
|
[ power-of-2? [ 1- bitand ] f ? ] [ drop f ] if ;
|
||||||
|
|
||||||
|
{
|
||||||
|
mod-integer-integer
|
||||||
|
mod-integer-fixnum
|
||||||
|
mod-fixnum-integer
|
||||||
|
fixnum-mod
|
||||||
|
} [
|
||||||
|
[
|
||||||
|
in-d>> dup first value-info interval>> [0,inf] interval-subset?
|
||||||
|
[ rem-custom-inlining ] [ drop f ] if
|
||||||
|
] "custom-inlining" set-word-prop
|
||||||
|
] each
|
||||||
|
|
||||||
|
\ rem [
|
||||||
|
in-d>> rem-custom-inlining
|
||||||
|
] "custom-inlining" set-word-prop
|
||||||
|
|
||||||
|
{
|
||||||
|
bitand-integer-integer
|
||||||
|
bitand-integer-fixnum
|
||||||
|
bitand-fixnum-integer
|
||||||
|
} [
|
||||||
|
[
|
||||||
|
in-d>> second value-info >literal< [
|
||||||
|
0 most-positive-fixnum between?
|
||||||
|
[ [ >fixnum ] bi@ fixnum-bitand ] f ?
|
||||||
|
] when
|
||||||
|
] "custom-inlining" set-word-prop
|
||||||
|
] each
|
||||||
|
|
||||||
|
! Generate more efficient code for common idiom
|
||||||
|
\ clone [
|
||||||
|
in-d>> first value-info literal>> {
|
||||||
|
{ V{ } [ [ drop { } 0 vector boa ] ] }
|
||||||
|
{ H{ } [ [ drop 0 <hashtable> ] ] }
|
||||||
|
[ drop f ]
|
||||||
|
} case
|
||||||
|
] "custom-inlining" set-word-prop
|
||||||
|
|
||||||
|
: prepare-partial-eval ( #call n -- value-infos ? )
|
||||||
|
|
||||||
|
ERROR: bad-partial-eval quot word ;
|
||||||
|
|
||||||
|
: check-effect ( quot word -- )
|
||||||
|
2dup [ infer ] [ stack-effect ] bi* effect<=
|
||||||
|
[ 2drop ] [ bad-partial-eval ] if ;
|
||||||
|
|
||||||
|
: values ( #call n -- infos )
|
||||||
|
[ in-d>> ] dip tail* [ value-info ] map ;
|
||||||
|
|
||||||
|
:: define-partial-eval ( word quot n -- )
|
||||||
|
word [
|
||||||
|
n values
|
||||||
|
dup [ literal?>> ] all? [
|
||||||
|
[ literal>> ] map
|
||||||
|
n firstn
|
||||||
|
quot call dup [
|
||||||
|
[ n ndrop ] prepose
|
||||||
|
dup word check-effect
|
||||||
|
] when
|
||||||
|
] [ drop f ] if
|
||||||
|
] "custom-inlining" set-word-prop ;
|
||||||
|
|
||||||
|
: inline-new ( class -- quot/f )
|
||||||
|
dup tuple-class? [
|
||||||
|
dup inlined-dependency depends-on
|
||||||
|
[ all-slots [ initial>> literalize ] map ]
|
||||||
|
[ tuple-layout '[ _ <tuple-boa> ] ]
|
||||||
|
bi append >quotation
|
||||||
|
] [ drop f ] if ;
|
||||||
|
|
||||||
|
\ new [ inline-new ] 1 define-partial-eval
|
||||||
|
|
||||||
|
\ instance? [
|
||||||
|
dup class?
|
||||||
|
[ "predicate" word-prop ] [ drop f ] if
|
||||||
|
] 1 define-partial-eval
|
||||||
|
|
||||||
|
! Shuffling
|
||||||
|
: nths-quot ( indices -- quot )
|
||||||
|
[ [ '[ _ swap nth ] ] map ] [ length ] bi
|
||||||
|
'[ _ cleave _ narray ] ;
|
||||||
|
|
||||||
|
\ shuffle [
|
||||||
|
shuffle-mapping nths-quot
|
||||||
|
] 1 define-partial-eval
|
||||||
|
|
||||||
|
! Index search
|
||||||
|
\ index [
|
||||||
|
dup sequence? [
|
||||||
|
dup length 4 >= [
|
||||||
|
dup length zip >hashtable '[ _ at ]
|
||||||
|
] [ drop f ] if
|
||||||
|
] [ drop f ] if
|
||||||
|
] 1 define-partial-eval
|
||||||
|
|
||||||
|
: memq-quot ( seq -- newquot )
|
||||||
|
[ [ dupd eq? ] curry [ drop t ] ] { } map>assoc
|
||||||
|
[ drop f ] suffix [ cond ] curry ;
|
||||||
|
|
||||||
|
\ memq? [
|
||||||
|
dup sequence? [ memq-quot ] [ drop f ] if
|
||||||
|
] 1 define-partial-eval
|
||||||
|
|
||||||
|
! Membership testing
|
||||||
|
: member-quot ( seq -- newquot )
|
||||||
|
dup length 4 <= [
|
||||||
|
[ drop f ] swap
|
||||||
|
[ literalize [ t ] ] { } map>assoc linear-case-quot
|
||||||
|
] [
|
||||||
|
unique [ key? ] curry
|
||||||
|
] if ;
|
||||||
|
|
||||||
|
\ member? [
|
||||||
|
dup sequence? [ member-quot ] [ drop f ] if
|
||||||
|
] 1 define-partial-eval
|
||||||
|
|
||||||
|
! Fast at for integer maps
|
||||||
|
CONSTANT: lookup-table-at-max 256
|
||||||
|
|
||||||
|
: lookup-table-at? ( assoc -- ? )
|
||||||
|
#! Can we use a fast byte array test here?
|
||||||
|
{
|
||||||
|
[ assoc-size 4 > ]
|
||||||
|
[ values [ ] all? ]
|
||||||
|
[ keys [ integer? ] all? ]
|
||||||
|
[ keys [ 0 lookup-table-at-max between? ] all? ]
|
||||||
|
} 1&& ;
|
||||||
|
|
||||||
|
: lookup-table-seq ( assoc -- table )
|
||||||
|
[ keys supremum 1+ ] keep '[ _ at ] { } map-as ;
|
||||||
|
|
||||||
|
: lookup-table-quot ( seq -- newquot )
|
||||||
|
lookup-table-seq
|
||||||
|
'[
|
||||||
|
_ over integer? [
|
||||||
|
2dup bounds-check? [
|
||||||
|
nth-unsafe dup >boolean
|
||||||
|
] [ 2drop f f ] if
|
||||||
|
] [ 2drop f f ] if
|
||||||
|
] ;
|
||||||
|
|
||||||
|
: fast-lookup-table-at? ( assoc -- ? )
|
||||||
|
values {
|
||||||
|
[ [ integer? ] all? ]
|
||||||
|
[ [ 0 254 between? ] all? ]
|
||||||
|
} 1&& ;
|
||||||
|
|
||||||
|
: fast-lookup-table-seq ( assoc -- table )
|
||||||
|
lookup-table-seq [ 255 or ] B{ } map-as ;
|
||||||
|
|
||||||
|
: fast-lookup-table-quot ( seq -- newquot )
|
||||||
|
fast-lookup-table-seq
|
||||||
|
'[
|
||||||
|
_ over integer? [
|
||||||
|
2dup bounds-check? [
|
||||||
|
nth-unsafe dup 255 eq? [ drop f f ] [ t ] if
|
||||||
|
] [ 2drop f f ] if
|
||||||
|
] [ 2drop f f ] if
|
||||||
|
] ;
|
||||||
|
|
||||||
|
: at-quot ( assoc -- quot )
|
||||||
|
dup lookup-table-at? [
|
||||||
|
dup fast-lookup-table-at? [
|
||||||
|
fast-lookup-table-quot
|
||||||
|
] [
|
||||||
|
lookup-table-quot
|
||||||
|
] if
|
||||||
|
] [ drop f ] if ;
|
||||||
|
|
||||||
|
\ at* [ at-quot ] 1 define-partial-eval
|
|
@ -107,97 +107,3 @@ IN: stack-checker.transforms
|
||||||
] 1 define-transform
|
] 1 define-transform
|
||||||
|
|
||||||
\ boa t "no-compile" set-word-prop
|
\ boa t "no-compile" set-word-prop
|
||||||
|
|
||||||
! Fast at for integer maps
|
|
||||||
CONSTANT: lookup-table-at-max 256
|
|
||||||
|
|
||||||
: lookup-table-at? ( assoc -- ? )
|
|
||||||
#! Can we use a fast byte array test here?
|
|
||||||
{
|
|
||||||
[ assoc-size 4 > ]
|
|
||||||
[ values [ ] all? ]
|
|
||||||
[ keys [ integer? ] all? ]
|
|
||||||
[ keys [ 0 lookup-table-at-max between? ] all? ]
|
|
||||||
} 1&& ;
|
|
||||||
|
|
||||||
: lookup-table-seq ( assoc -- table )
|
|
||||||
[ keys supremum 1+ ] keep '[ _ at ] { } map-as ;
|
|
||||||
|
|
||||||
: lookup-table-quot ( seq -- newquot )
|
|
||||||
lookup-table-seq
|
|
||||||
'[
|
|
||||||
_ over integer? [
|
|
||||||
2dup bounds-check? [
|
|
||||||
nth-unsafe dup >boolean
|
|
||||||
] [ 2drop f f ] if
|
|
||||||
] [ 2drop f f ] if
|
|
||||||
] ;
|
|
||||||
|
|
||||||
: fast-lookup-table-at? ( assoc -- ? )
|
|
||||||
values {
|
|
||||||
[ [ integer? ] all? ]
|
|
||||||
[ [ 0 254 between? ] all? ]
|
|
||||||
} 1&& ;
|
|
||||||
|
|
||||||
: fast-lookup-table-seq ( assoc -- table )
|
|
||||||
lookup-table-seq [ 255 or ] B{ } map-as ;
|
|
||||||
|
|
||||||
: fast-lookup-table-quot ( seq -- newquot )
|
|
||||||
fast-lookup-table-seq
|
|
||||||
'[
|
|
||||||
_ over integer? [
|
|
||||||
2dup bounds-check? [
|
|
||||||
nth-unsafe dup 255 eq? [ drop f f ] [ t ] if
|
|
||||||
] [ 2drop f f ] if
|
|
||||||
] [ 2drop f f ] if
|
|
||||||
] ;
|
|
||||||
|
|
||||||
: at-quot ( assoc -- quot )
|
|
||||||
dup lookup-table-at? [
|
|
||||||
dup fast-lookup-table-at? [
|
|
||||||
fast-lookup-table-quot
|
|
||||||
] [
|
|
||||||
lookup-table-quot
|
|
||||||
] if
|
|
||||||
] [ drop f ] if ;
|
|
||||||
|
|
||||||
\ at* [ at-quot ] 1 define-transform
|
|
||||||
|
|
||||||
! Membership testing
|
|
||||||
: member-quot ( seq -- newquot )
|
|
||||||
dup length 4 <= [
|
|
||||||
[ drop f ] swap
|
|
||||||
[ literalize [ t ] ] { } map>assoc linear-case-quot
|
|
||||||
] [
|
|
||||||
unique [ key? ] curry
|
|
||||||
] if ;
|
|
||||||
|
|
||||||
\ member? [
|
|
||||||
dup sequence? [ member-quot ] [ drop f ] if
|
|
||||||
] 1 define-transform
|
|
||||||
|
|
||||||
: memq-quot ( seq -- newquot )
|
|
||||||
[ [ dupd eq? ] curry [ drop t ] ] { } map>assoc
|
|
||||||
[ drop f ] suffix [ cond ] curry ;
|
|
||||||
|
|
||||||
\ memq? [
|
|
||||||
dup sequence? [ memq-quot ] [ drop f ] if
|
|
||||||
] 1 define-transform
|
|
||||||
|
|
||||||
! Index search
|
|
||||||
\ index [
|
|
||||||
dup sequence? [
|
|
||||||
dup length 4 >= [
|
|
||||||
dup length zip >hashtable '[ _ at ]
|
|
||||||
] [ drop f ] if
|
|
||||||
] [ drop f ] if
|
|
||||||
] 1 define-transform
|
|
||||||
|
|
||||||
! Shuffling
|
|
||||||
: nths-quot ( indices -- quot )
|
|
||||||
[ [ '[ _ swap nth ] ] map ] [ length ] bi
|
|
||||||
'[ _ cleave _ narray ] ;
|
|
||||||
|
|
||||||
\ shuffle [
|
|
||||||
shuffle-mapping nths-quot
|
|
||||||
] 1 define-transform
|
|
||||||
|
|
Loading…
Reference in New Issue