working on type inference

cvs
Slava Pestov 2005-07-28 22:20:31 +00:00
parent 869430fae0
commit 43cd7b171e
13 changed files with 114 additions and 67 deletions

View File

@ -90,6 +90,7 @@ parser prettyprint sequences io vectors words ;
"/library/inference/words.factor" "/library/inference/words.factor"
"/library/inference/stack.factor" "/library/inference/stack.factor"
"/library/inference/partial-eval.factor" "/library/inference/partial-eval.factor"
"/library/inference/class-infer.factor"
"/library/inference/optimizer.factor" "/library/inference/optimizer.factor"
"/library/inference/print-dataflow.factor" "/library/inference/print-dataflow.factor"

View File

@ -4,8 +4,6 @@ USING: alien assembler command-line compiler generic hashtables
kernel lists memory namespaces parser sequences io unparser kernel lists memory namespaces parser sequences io unparser
words ; words ;
\ fiber? t "inline" set-word-prop
: pull-in ( ? list -- ) : pull-in ( ? list -- )
swap [ swap [
[ [

View File

@ -24,13 +24,9 @@ builtin 50 "priority" set-word-prop
! All builtin types are equivalent in ordering ! All builtin types are equivalent in ordering
builtin [ 2drop t ] "class<" set-word-prop builtin [ 2drop t ] "class<" set-word-prop
: builtin-predicate ( class -- ) : builtin-predicate ( class predicate -- )
dup "predicate" word-prop car 2dup register-predicate
dup t "inline" set-word-prop [ \ type , swap "builtin-type" word-prop , \ eq? , ] make-list
swap
[
\ type , "builtin-type" word-prop , \ eq? ,
] make-list
define-compound ; define-compound ;
: register-builtin ( class -- ) : register-builtin ( class -- )
@ -41,8 +37,7 @@ builtin [ 2drop t ] "class<" set-word-prop
dup intern-symbol dup intern-symbol
dup r> "builtin-type" set-word-prop dup r> "builtin-type" set-word-prop
dup builtin define-class dup builtin define-class
dup r> unit "predicate" set-word-prop dup r> builtin-predicate
dup builtin-predicate
dup r> intern-slots 2dup "slots" set-word-prop dup r> intern-slots 2dup "slots" set-word-prop
define-slots define-slots
register-builtin ; register-builtin ;

View File

@ -8,23 +8,12 @@ math-internals ;
! A simple single-dispatch generic word system. ! A simple single-dispatch generic word system.
: predicate-word ( word -- word ) : predicate-word ( word -- word )
word-name "?" append create-in word-name "?" append create-in ;
dup t "inline" set-word-prop ;
! Terminology: : register-predicate ( class predicate -- )
! - type: a datatype built in to the runtime, eg fixnum, word 2dup unit "predicate" set-word-prop
! cons. All objects have exactly one type, new types cannot be swap "predicating" set-word-prop ;
! defined, and types are disjoint.
! - class: a user defined way of differentiating objects, either
! based on type, or some combination of type, predicate, or
! method map.
! - metaclass: a metaclass is a symbol with a handful of word
! properties: "builtin-supertypes" "priority" "add-method"
! "class<"
! So far, only tuples can have delegates, which also must be
! tuples (the UI uses numbers as delegates in a couple of places
! but this is Unsupported(tm)).
GENERIC: delegate GENERIC: delegate
GENERIC: set-delegate GENERIC: set-delegate

View File

@ -18,8 +18,6 @@ hashtables errors sequences vectors ;
#! specifying an incorrect size. #! specifying an incorrect size.
<tuple> [ 2 set-slot ] keep ; <tuple> [ 2 set-slot ] keep ;
: class-tuple 2 slot ; inline
IN: generic IN: generic
DEFER: tuple? DEFER: tuple?
@ -30,18 +28,15 @@ M: tuple set-delegate 3 set-slot ;
: class ( obj -- class ) : class ( obj -- class )
#! The class of an object. #! The class of an object.
dup tuple? [ class-tuple ] [ type builtin-type ] ifte ; dup tuple? [ 2 slot ] [ type builtin-type ] ifte ; inline
: tuple-predicate ( word -- ) : tuple-predicate ( word -- )
#! Make a foo? word for testing the tuple class at the top #! Make a foo? word for testing the tuple class at the top
#! of the stack. #! of the stack.
dup predicate-word 2dup unit "predicate" set-word-prop dup predicate-word
swap [ 2dup register-predicate
[ dup tuple? ] % swap [ \ class , literal, \ eq? , ] make-list
[ \ class-tuple , literal, \ eq? , ] make-list , define-compound ;
[ drop f ] ,
\ ifte ,
] make-list define-compound ;
: forget-tuple ( class -- ) : forget-tuple ( class -- )
dup forget "predicate" word-prop car [ forget ] when* ; dup forget "predicate" word-prop car [ forget ] when* ;
@ -136,7 +131,7 @@ M: tuple set-delegate 3 set-slot ;
#! for methods defined on the given generic. #! for methods defined on the given generic.
dup default-tuple-method \ drop swons dup default-tuple-method \ drop swons
over tuple-methods hash>quot over tuple-methods hash>quot
>r "picker" word-prop [ class-tuple ] r> append3 ; >r "picker" word-prop [ class ] r> append3 ;
: add-tuple-dispatch ( word vtable -- ) : add-tuple-dispatch ( word vtable -- )
>r tuple-dispatch-quot tuple r> set-vtable ; >r tuple-dispatch-quot tuple r> set-vtable ;

View File

@ -1,7 +1,8 @@
! Copyright (C) 2004, 2005 Slava Pestov. ! Copyright (C) 2004, 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license. ! See http://factor.sf.net/license.txt for BSD license.
IN: inference IN: inference
USING: generic hashtables kernel namespaces sequences words ; USING: generic hashtables kernel namespaces sequences vectors
words ;
! Infer possible classes of values in a dataflow IR. ! Infer possible classes of values in a dataflow IR.
@ -10,54 +11,121 @@ USING: generic hashtables kernel namespaces sequences words ;
! Current value --> class mapping ! Current value --> class mapping
SYMBOL: value-classes SYMBOL: value-classes
TUPLE: possibility value class ; ! Current value --> literal mapping
SYMBOL: value-literals
! Maps possibilities to possibilities. GENERIC: apply-tie ( tie -- )
SYMBOL: possible-classes
M: f apply-tie ( f -- ) drop ;
TUPLE: class-tie value class ;
: set-value-class ( class value -- )
2dup swap <class-tie> ties get hash [ apply-tie ] when*
value-classes get set-hash ;
M: class-tie apply-tie ( tie -- )
dup class-tie-class swap class-tie-value
set-value-class ;
TUPLE: literal-tie value literal ;
: set-value-literal ( literal value -- )
over class over set-value-class
2dup swap <literal-tie> ties get hash [ apply-tie ] when*
value-literals get set-hash ;
M: literal-tie apply-tie ( tie -- )
dup literal-tie-literal swap literal-tie-value
set-value-literal ;
! Maps ties to ties
SYMBOL: ties
GENERIC: infer-classes* ( node -- ) GENERIC: infer-classes* ( node -- )
M: node infer-classes* ( node -- ) drop ;
! For conditionals, a map of child node # --> possibility
GENERIC: child-ties ( node -- seq )
M: node child-ties ( node -- seq )
node-children length f <repeated> ;
: value-class ( value -- class ) : value-class ( value -- class )
value-classes get hash [ object ] unless* ; value-classes get hash [ object ] unless* ;
: value-literal ( value -- class )
value-literals get hash ;
: annotate-node ( node -- ) : annotate-node ( node -- )
#! Annotate the node with the currently-inferred set of #! Annotate the node with the currently-inferred set of
#! value classes. #! value classes.
dup node-values [ value-class ] map>hash dup node-values ( 2dup )
swap set-node-classes ; [ value-class ] map>hash swap set-node-classes
( [ value-literal ] map>hash swap set-node-literals ) ;
M: node infer-classes* ( node -- ) drop ;
: assume-classes ( classes values -- ) : assume-classes ( classes values -- )
[ value-classes get set-hash ] 2each ; [ set-value-class ] 2each ;
: assume-literals ( literals values -- )
[ set-value-literal ] 2each ;
: intersect-classes ( classes values -- ) : intersect-classes ( classes values -- )
[ [ value-class class-and ] 2map ] keep assume-classes ; [ [ value-class class-and ] 2map ] keep assume-classes ;
: create-ties ( #call -- )
#! If the node is calling a class test predicate, create a
#! tie.
dup node-param "predicating" word-prop dup [
>r dup node-in-d first r> <class-tie>
swap node-out-d first general-t <class-tie>
ties get set-hash
] [
2drop
] ifte ;
M: #call infer-classes* ( node -- ) M: #call infer-classes* ( node -- )
dup create-ties
dup node-param "infer-effect" word-prop 2unseq dup node-param "infer-effect" word-prop 2unseq
pick node-out-d assume-classes pick node-out-d assume-classes
swap node-in-d intersect-classes ; swap node-in-d intersect-classes ;
M: #push infer-classes* ( node -- ) M: #push infer-classes* ( node -- )
node-out-d [ node-out-d [ safe-literal? ] subset
dup safe-literal? [ dup [ literal-value ] map
[ literal-value class ] keep swap assume-literals ;
value-classes get set-hash
] [ M: #ifte child-ties ( node -- seq )
drop node-in-d first dup general-t <class-tie>
] ifte swap f <literal-tie> 2vector ;
] each ;
M: #dispatch child-ties ( node -- seq )
dup node-in-d first
swap node-children length [ <literal-tie> ] map-with ;
DEFER: (infer-classes)
: infer-children ( node -- )
dup node-children swap child-ties [
[
value-classes [ clone ] change
ties [ clone ] change
apply-tie
(infer-classes)
] with-scope
] 2each ;
: (infer-classes) ( node -- ) : (infer-classes) ( node -- )
dup infer-classes* dup infer-classes*
dup annotate-node dup annotate-node
dup node-children [ (infer-classes) ] each dup infer-children
node-successor [ (infer-classes) ] when* ; node-successor [ (infer-classes) ] when* ;
: infer-classes ( node -- ) : infer-classes ( node -- )
[ [
<namespace> value-classes set <namespace> value-classes set
<namespace> possible-classes set <namespace> value-literals set
<namespace> ties set
(infer-classes) (infer-classes)
] with-scope ; ] with-scope ;

View File

@ -9,12 +9,12 @@ sequences vectors words ;
! code with stack flow information and types. ! code with stack flow information and types.
TUPLE: node param in-d out-d in-r out-r TUPLE: node param in-d out-d in-r out-r
classes successor children ; classes literals successor children ;
M: node = eq? ; M: node = eq? ;
: make-node ( param in-d out-d in-r out-r node -- node ) : make-node ( param in-d out-d in-r out-r node -- node )
[ >r f f f <node> r> set-delegate ] keep ; [ >r f f f f <node> r> set-delegate ] keep ;
: param-node ( label) f f f f ; : param-node ( label) f f f f ;
: in-d-node ( inputs) >r f r> f f f ; : in-d-node ( inputs) >r f r> f f f ;

View File

@ -92,7 +92,7 @@ M: f can-kill* ( literal node -- ? )
2drop t ; 2drop t ;
M: node can-kill* ( literal node -- ? ) M: node can-kill* ( literal node -- ? )
uses-value? ; uses-value? not ;
M: node kill-node* ( literals node -- ) M: node kill-node* ( literals node -- )
2drop ; 2drop ;

View File

@ -14,7 +14,7 @@ M: annotation prettyprint* ( ann -- )
swap annotation-node object. ; swap annotation-node object. ;
: value-str ( classes values -- str ) : value-str ( classes values -- str )
[ swap ?hash [ [ object ] ] unless* ] map-with [ swap ?hash [ object ] unless* ] map-with
[ word-name ] map [ word-name ] map
" " join ; " " join ;

View File

@ -5,18 +5,18 @@ USING: gadgets namespaces styles test ;
0 x set 0 x set
0 y set 0 y set
[ [ 255 0 0 ] ] [ { 1 0 0 } red green <gradient> 0 gradient-color ] unit-test [ { 255 0 0 } ] [ { 1 0 0 } red green <gradient> 0 gradient-color ] unit-test
[ [ 0 255 0 ] ] [ { 1 0 0 } red green <gradient> 1 gradient-color ] unit-test [ { 0 255 0 } ] [ { 1 0 0 } red green <gradient> 1 gradient-color ] unit-test
[ 0 100 0 [ 255 0 0 ] ] [ 0 100 0 { 255 0 0 } ]
[ { 0 1 0 } red green <gradient> { 100 200 0 } 0 (gradient-x) ] unit-test [ { 0 1 0 } red green <gradient> { 100 200 0 } 0 (gradient-x) ] unit-test
[ 0 100 100 [ 255/2 255/2 0 ] ] [ 0 100 100 [ 255/2 255/2 0 ] ]
[ { 0 1 0 } red green <gradient> { 100 200 0 } 100 (gradient-x) ] unit-test [ { 0 1 0 } red green <gradient> { 100 200 0 } 100 (gradient-x) ] unit-test
[ 0 0 200 [ 255 0 0 ] ] [ 0 0 200 { 255 0 0 } ]
[ { 1 0 0 } red green <gradient> { 100 200 0 } 0 (gradient-y) ] unit-test [ { 1 0 0 } red green <gradient> { 100 200 0 } 0 (gradient-y) ] unit-test
[ 50 0 200 [ 255/2 255/2 0 ] ] [ 50 0 200 { 255/2 255/2 0 } ]
[ { 1 0 0 } red green <gradient> { 100 200 0 } 50 (gradient-y) ] unit-test [ { 1 0 0 } red green <gradient> { 100 200 0 } 50 (gradient-y) ] unit-test
] with-scope ] with-scope

View File

@ -8,7 +8,6 @@ USE: strings
USE: sequences USE: sequences
[ { [ 3 2 1 ] [ 5 4 3 ] [ 6 ] } ] [ { [ 3 2 1 ] [ 5 4 3 ] [ 6 ] } ]
[ [ 1 2 3 ] [ 3 4 5 ] [ 6 ] 3vector [ reverse ] map ] unit-test
[ [ "a" 43 [ ] ] ] [ [ "a" 43 43 43 [ ] 43 "a" [ ] ] prune ] unit-test [ [ "a" 43 [ ] ] ] [ [ "a" 43 43 43 [ ] 43 "a" [ ] ] prune ] unit-test

View File

@ -8,4 +8,4 @@ USE: test
: foo 1 2 3 ; : foo 1 2 3 ;
[ 1 2 3 1 2 3 ] [ bar ] unit-test [ 1 2 3 1 2 3 ] [ bar ] unit-test
[ [ [ ] [ fixnum fixnum fixnum ] ] ] [ [ foo ] infer ] unit-test [ [ [ 0 3 ] ] ] [ [ foo ] infer ] unit-test

View File

@ -69,3 +69,5 @@ unit-test
[ { 1 2 3 } ] [ 1 2 3 3vector ] unit-test [ { 1 2 3 } ] [ 1 2 3 3vector ] unit-test
[ { } ] [ { } seq-transpose ] unit-test [ { } ] [ { } seq-transpose ] unit-test
[ [ 1 2 3 ] [ 3 4 5 ] [ 6 ] 3vector [ reverse ] map ] unit-test