partial evaluation of branches

cvs
Slava Pestov 2004-12-27 20:27:18 +00:00
parent 97d77d0ecc
commit 9669067924
6 changed files with 47 additions and 46 deletions

View File

@ -85,11 +85,12 @@ USE: kernel-internals
: default-cli-args : default-cli-args
#! Some flags are *on* by default, unless user specifies #! Some flags are *on* by default, unless user specifies
#! -no-<flag> CLI switch #! -no-<flag> CLI switch
t "user-init" set "user-init" on
t "interactive" set "interactive" on
t "smart-terminal" set "smart-terminal" on
t "verbose-compile" set "verbose-compile" on
t "compile" set ; "compile" on
os "win32" = [ "graphical" on ] when ;
: cli-args ( -- args ) 10 getenv ; : cli-args ( -- args ) 10 getenv ;

View File

@ -41,6 +41,7 @@ USE: strings
USE: unparser USE: unparser
USE: vectors USE: vectors
USE: words USE: words
USE: test
: supported-cpu? ( -- ? ) : supported-cpu? ( -- ? )
cpu "unknown" = not ; cpu "unknown" = not ;
@ -97,7 +98,7 @@ M: compound (compile) ( word -- )
: compile-all ( -- ) : compile-all ( -- )
#! Compile all words. #! Compile all words.
supported-cpu? [ supported-cpu? [
[ try-compile ] each-word [ [ try-compile ] each-word ] time
] [ ] [
"Unsupported CPU" print "Unsupported CPU" print
] ifte ; ] ifte ;

View File

@ -39,6 +39,10 @@ USE: words
USE: hashtables USE: hashtables
USE: prettyprint USE: prettyprint
! If this symbol is on, partial evalution of conditionals is
! disabled.
SYMBOL: inferring-base-case
: vector-length< ( vec1 vec2 -- ? ) : vector-length< ( vec1 vec2 -- ? )
swap vector-length swap vector-length < ; swap vector-length swap vector-length < ;
@ -127,9 +131,8 @@ SYMBOL: cloned
d-in [ deep-clone-vector ] change d-in [ deep-clone-vector ] change
dataflow-graph off ; dataflow-graph off ;
: infer-branch ( value save-effect -- namespace ) : infer-branch ( value -- namespace )
<namespace> [ <namespace> [
save-effect set
uncons [ unswons [ \ value-class set ] bind ] when* uncons [ unswons [ \ value-class set ] bind ] when*
dup value-recursion recursive-state set dup value-recursion recursive-state set
copy-inference copy-inference
@ -154,7 +157,7 @@ SYMBOL: dual-recursive-state
#! Return effect namespace if inference didn't fail. #! Return effect namespace if inference didn't fail.
[ [
[ dual-branch dual-recursive-state set ] keep [ dual-branch dual-recursive-state set ] keep
f infer-branch infer-branch
] [ ] [
[ 2drop f ] when [ 2drop f ] when
] catch ; ] catch ;
@ -167,12 +170,16 @@ SYMBOL: dual-recursive-state
#! Either the word is not recursive, or it is recursive #! Either the word is not recursive, or it is recursive
#! and the base case throws an error. #! and the base case throws an error.
[ [
inferring-base-case on
[ terminator-quot? not ] subset dup length 1 > [ [ terminator-quot? not ] subset dup length 1 > [
infer-base-cases unify-effects infer-base-cases unify-effects
effect dual-recursive-state get set-base effect dual-recursive-state get set-base
] [ ] [
drop drop
] ifte ] ifte
inferring-base-case off
] with-scope ; ] with-scope ;
: (infer-branches) ( branchlist -- list ) : (infer-branches) ( branchlist -- list )
@ -182,7 +189,7 @@ SYMBOL: dual-recursive-state
#! is a pair [ value | class ] indicating a type propagation #! is a pair [ value | class ] indicating a type propagation
#! for the given branch. #! for the given branch.
dup infer-base-case [ dup infer-base-case [
dup t infer-branch swap terminator-quot? [ dup infer-branch swap terminator-quot? [
[ meta-d off meta-r off d-in off ] extend [ meta-d off meta-r off d-in off ] extend
] when ] when
] map ; ] map ;
@ -198,11 +205,17 @@ SYMBOL: dual-recursive-state
#! parameter is a vector. #! parameter is a vector.
(infer-branches) dup unify-effects unify-dataflow ; (infer-branches) dup unify-effects unify-dataflow ;
: static-branch? ( value -- )
literal? inferring-base-case get not and ;
: static-ifte ( true false -- ) : static-ifte ( true false -- )
#! If the branch taken is statically known, just infer #! If the branch taken is statically known, just infer
#! along that branch. #! along that branch.
pop-d literal-value [ drop ] [ nip ] ifte dataflow-drop, pop-d literal-value [ drop ] [ nip ] ifte
literal-value infer-quot ; gensym [
dup value-recursion recursive-state set
literal-value infer-quot
] (with-block) ;
: dynamic-ifte ( true false -- ) : dynamic-ifte ( true false -- )
#! If branch taken is computed, infer along both paths and #! If branch taken is computed, infer along both paths and
@ -219,11 +232,11 @@ SYMBOL: dual-recursive-state
[ object general-list general-list ] ensure-d [ object general-list general-list ] ensure-d
dataflow-drop, pop-d dataflow-drop, pop-d
dataflow-drop, pop-d swap dataflow-drop, pop-d swap
! peek-d literal? [ peek-d static-branch? [
! static-ifte static-ifte
! ] [ ] [
dynamic-ifte ; dynamic-ifte
! ] ifte ; ] ifte ;
\ ifte [ infer-ifte ] "infer" set-word-property \ ifte [ infer-ifte ] "infer" set-word-property

View File

@ -59,12 +59,6 @@ SYMBOL: entry-effect
! makes a local jump to this label. ! makes a local jump to this label.
SYMBOL: recursive-label SYMBOL: recursive-label
! When inferring stack effects of mutually recursive words, we
! don't want to save the fact that one word does not have a
! stack effect before the base case of its mutual pair is
! inferred.
SYMBOL: save-effect
! A value has the following slots: ! A value has the following slots:
GENERIC: literal-value ( value -- obj ) GENERIC: literal-value ( value -- obj )
GENERIC: value= ( literal value -- ? ) GENERIC: value= ( literal value -- ? )
@ -149,8 +143,7 @@ M: literal value-class-and ( class value -- )
init-interpreter init-interpreter
0 <vector> d-in set 0 <vector> d-in set
recursive-state set recursive-state set
dataflow-graph off dataflow-graph off ;
save-effect on ;
DEFER: apply-word DEFER: apply-word

View File

@ -109,29 +109,14 @@ USE: prettyprint
[ swap <chained-error> rethrow ] when* [ swap <chained-error> rethrow ] when*
] catch ; ] catch ;
: (infer-compound) ( word -- effect ) : infer-compound ( word -- effect )
#! Infer a word's stack effect in a separate inferencer #! Infer a word's stack effect in a separate inferencer
#! instance. #! instance.
[ [
recursive-state get init-inference recursive-state get init-inference
dup inline-compound dup dup inline-compound
[ "infer-effect" set-word-property ] keep [ "infer-effect" set-word-property ] keep
] with-scope ; ] with-scope consume/produce ;
: infer-compound ( word -- )
#! Infer the stack effect of a compound word in a separate
#! inferencer instance, caching the result.
[
dup (infer-compound) consume/produce
] [
[
swap save-effect get [
t "no-effect" set-word-property
] [
drop
] ifte rethrow
] when*
] catch ;
GENERIC: (apply-word) GENERIC: (apply-word)

View File

@ -41,7 +41,6 @@ USE: generic
[ [ call ] infer old-effect ] unit-test-fails [ [ call ] infer old-effect ] unit-test-fails
[ [ 2 | 4 ] ] [ [ 2dup ] infer old-effect ] unit-test [ [ 2 | 4 ] ] [ [ 2dup ] infer old-effect ] unit-test
[ [ 2 | 0 ] ] [ [ set-vector-length ] infer old-effect ] unit-test
[ [ 2 | 0 ] ] [ [ vector-push ] infer old-effect ] unit-test [ [ 2 | 0 ] ] [ [ vector-push ] infer old-effect ] unit-test
[ [ 1 | 0 ] ] [ [ [ ] [ ] ifte ] infer old-effect ] unit-test [ [ 1 | 0 ] ] [ [ [ ] [ ] ifte ] infer old-effect ] unit-test
@ -99,6 +98,13 @@ USE: generic
[ [ bad-recursion-2 ] infer old-effect ] unit-test-fails [ [ bad-recursion-2 ] infer old-effect ] unit-test-fails
! Not sure how to fix this one
! : funny-recursion
! dup [ funny-recursion 1 ] [ 2 ] ifte drop ;
!
! [ [ 1 | 1 ] ] [ [ funny-recursion ] infer old-effect ] unit-test
! Simple combinators ! Simple combinators
[ [ 1 | 2 ] ] [ [ [ car ] keep cdr ] infer old-effect ] unit-test [ [ 1 | 2 ] ] [ [ [ car ] keep cdr ] infer old-effect ] unit-test
@ -123,6 +129,9 @@ DEFER: foe
2drop f 2drop f
] ifte ; ] ifte ;
[ [ 2 | 1 ] ] [ [ fie ] infer old-effect ] unit-test
[ [ 2 | 1 ] ] [ [ foe ] infer old-effect ] unit-test
! This form should not have a stack effect ! This form should not have a stack effect
: bad-bin 5 [ 5 bad-bin bad-bin 5 ] [ 2drop ] ifte ; : bad-bin 5 [ 5 bad-bin bad-bin 5 ] [ 2drop ] ifte ;
[ [ bad-bin ] infer old-effect ] unit-test-fails [ [ bad-bin ] infer old-effect ] unit-test-fails
@ -149,9 +158,8 @@ SYMBOL: sym-test
[ [ 0 | 1 ] ] [ [ sym-test ] infer old-effect ] unit-test [ [ 0 | 1 ] ] [ [ sym-test ] infer old-effect ] unit-test
[ [ 2 | 1 ] ] [ [ fie ] infer old-effect ] unit-test
[ [ 2 | 1 ] ] [ [ foe ] infer old-effect ] unit-test
[ [ 2 | 0 ] ] [ [ set-vector-length ] infer old-effect ] unit-test
[ [ 2 | 1 ] ] [ [ 2list ] infer old-effect ] unit-test [ [ 2 | 1 ] ] [ [ 2list ] infer old-effect ] unit-test
[ [ 3 | 1 ] ] [ [ 3list ] infer old-effect ] unit-test [ [ 3 | 1 ] ] [ [ 3list ] infer old-effect ] unit-test
[ [ 2 | 1 ] ] [ [ append ] infer old-effect ] unit-test [ [ 2 | 1 ] ] [ [ append ] infer old-effect ] unit-test