dataflow optimizer fixes, minor generic word cleanups
parent
eab5d999af
commit
ff7b3f9762
|
|
@ -14,7 +14,7 @@ BUILTIN: cons 2 cons? { 0 "car" f } { 1 "cdr" f } ;
|
||||||
M: f car ;
|
M: f car ;
|
||||||
M: f cdr ;
|
M: f cdr ;
|
||||||
|
|
||||||
UNION: general-list f cons ;
|
UNION: general-list POSTPONE: f cons ;
|
||||||
|
|
||||||
GENERIC: >list ( seq -- list )
|
GENERIC: >list ( seq -- list )
|
||||||
M: general-list >list ( list -- list ) ;
|
M: general-list >list ( list -- list ) ;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +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: compiler-frontend
|
IN: compiler-frontend
|
||||||
USING: compiler-backend errors generic inference kernel
|
USING: compiler-backend errors generic lists inference kernel
|
||||||
kernel-internals lists math namespaces prettyprint sequences
|
kernel-internals math namespaces prettyprint sequences
|
||||||
strings words ;
|
strings words ;
|
||||||
|
|
||||||
GENERIC: linearize-node* ( node -- )
|
GENERIC: linearize-node* ( node -- )
|
||||||
|
|
@ -22,10 +22,13 @@ M: f linearize-node* ( f -- ) drop ;
|
||||||
M: #label linearize-node* ( node -- )
|
M: #label linearize-node* ( node -- )
|
||||||
<label> dup %return-to , >r
|
<label> dup %return-to , >r
|
||||||
dup node-param %label ,
|
dup node-param %label ,
|
||||||
node-children car linearize-node
|
node-children first linearize-node
|
||||||
f %return ,
|
f %return ,
|
||||||
r> %label , ;
|
r> %label , ;
|
||||||
|
|
||||||
|
M: #simple-label linearize-node* ( node -- )
|
||||||
|
node-children first linearize-node ;
|
||||||
|
|
||||||
M: #call linearize-node* ( node -- )
|
M: #call linearize-node* ( node -- )
|
||||||
dup node-param
|
dup node-param
|
||||||
dup "intrinsic" word-prop [
|
dup "intrinsic" word-prop [
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@ builtin 50 "priority" set-word-prop
|
||||||
builtin [ (class<) ] "class<" set-word-prop
|
builtin [ (class<) ] "class<" set-word-prop
|
||||||
|
|
||||||
: builtin-predicate ( class predicate -- )
|
: builtin-predicate ( class predicate -- )
|
||||||
2dup register-predicate
|
[
|
||||||
[ \ type , swap "builtin-type" word-prop , \ eq? , ] make-list
|
\ type , over "builtin-type" word-prop , \ eq? ,
|
||||||
define-compound ;
|
] make-list define-predicate ;
|
||||||
|
|
||||||
: register-builtin ( class -- )
|
: register-builtin ( class -- )
|
||||||
dup "builtin-type" word-prop builtins get set-nth ;
|
dup "builtin-type" word-prop builtins get set-nth ;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ math-internals ;
|
||||||
: predicate-word ( word -- word )
|
: predicate-word ( word -- word )
|
||||||
word-name "?" append create-in ;
|
word-name "?" append create-in ;
|
||||||
|
|
||||||
: register-predicate ( class predicate -- )
|
: define-predicate ( class predicate quot -- )
|
||||||
|
dupd define-compound
|
||||||
2dup unit "predicate" set-word-prop
|
2dup unit "predicate" set-word-prop
|
||||||
swap "predicating" set-word-prop ;
|
swap "predicating" set-word-prop ;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,11 +45,11 @@ predicate [
|
||||||
] ifte
|
] ifte
|
||||||
] "class<" set-word-prop
|
] "class<" set-word-prop
|
||||||
|
|
||||||
: define-predicate ( class predicate definition -- )
|
: define-predicate-class ( class predicate definition -- )
|
||||||
pick over "definition" set-word-prop
|
3dup nip "definition" set-word-prop
|
||||||
|
pick predicate "metaclass" set-word-prop
|
||||||
pick "superclass" word-prop "predicate" word-prop
|
pick "superclass" word-prop "predicate" word-prop
|
||||||
[ \ dup , % , [ drop f ] , \ ifte , ] make-list
|
[ \ dup , % , [ drop f ] , \ ifte , ] make-list
|
||||||
define-compound
|
define-predicate ;
|
||||||
predicate "metaclass" set-word-prop ;
|
|
||||||
|
|
||||||
PREDICATE: word predicate metaclass predicate = ;
|
PREDICATE: word predicate metaclass predicate = ;
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,8 @@ BUILTIN: tuple 18 tuple? ;
|
||||||
#! 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
|
dup predicate-word
|
||||||
2dup register-predicate
|
[ \ class , over literal, \ eq? , ] make-list
|
||||||
swap [ \ class , literal, \ eq? , ] make-list
|
define-predicate ;
|
||||||
define-compound ;
|
|
||||||
|
|
||||||
: forget-tuple ( class -- )
|
: forget-tuple ( class -- )
|
||||||
dup forget "predicate" word-prop car [ forget ] when* ;
|
dup forget "predicate" word-prop car [ forget ] when* ;
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ union 50 "priority" set-word-prop
|
||||||
|
|
||||||
union [ (class<) ] "class<" set-word-prop
|
union [ (class<) ] "class<" set-word-prop
|
||||||
|
|
||||||
: union-predicate ( definition -- list )
|
: union-predicate ( members -- list )
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
\ dup ,
|
\ dup ,
|
||||||
|
|
@ -35,18 +35,10 @@ union [ (class<) ] "class<" set-word-prop
|
||||||
[ drop f ]
|
[ drop f ]
|
||||||
] ifte* ;
|
] ifte* ;
|
||||||
|
|
||||||
: define-union ( class predicate definition -- )
|
: define-union ( class predicate members -- )
|
||||||
#! We have to turn the f object into the f word, same for t.
|
#! We have to turn the f object into the f word, same for t.
|
||||||
[
|
3dup nip "members" set-word-prop
|
||||||
[
|
pick union define-class
|
||||||
[
|
union-predicate define-predicate ;
|
||||||
[[ f POSTPONE: f ]]
|
|
||||||
[[ t POSTPONE: t ]]
|
|
||||||
] assoc dup
|
|
||||||
] keep ?
|
|
||||||
] map
|
|
||||||
[ union-predicate define-compound ] keep
|
|
||||||
dupd "members" set-word-prop
|
|
||||||
union define-class ;
|
|
||||||
|
|
||||||
PREDICATE: word union metaclass union = ;
|
PREDICATE: word union metaclass union = ;
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,10 @@ TUPLE: #label ;
|
||||||
C: #label make-node ;
|
C: #label make-node ;
|
||||||
: #label ( label -- node ) param-node <#label> ;
|
: #label ( label -- node ) param-node <#label> ;
|
||||||
|
|
||||||
|
TUPLE: #simple-label ;
|
||||||
|
C: #simple-label make-node ;
|
||||||
|
: #simple-label ( label -- node ) param-node <#simple-label> ;
|
||||||
|
|
||||||
TUPLE: #call ;
|
TUPLE: #call ;
|
||||||
C: #call make-node ;
|
C: #call make-node ;
|
||||||
: #call ( word -- node ) param-node <#call> ;
|
: #call ( word -- node ) param-node <#call> ;
|
||||||
|
|
@ -118,6 +122,13 @@ SYMBOL: current-node
|
||||||
: last-node ( node -- last )
|
: last-node ( node -- last )
|
||||||
dup node-successor [ last-node ] [ ] ?ifte ;
|
dup node-successor [ last-node ] [ ] ?ifte ;
|
||||||
|
|
||||||
|
: penultimate-node ( node -- penultimate )
|
||||||
|
dup node-successor dup [
|
||||||
|
dup node-successor [ nip penultimate-node ] [ drop ] ifte
|
||||||
|
] [
|
||||||
|
2drop f
|
||||||
|
] ifte ;
|
||||||
|
|
||||||
: drop-inputs ( node -- #drop )
|
: drop-inputs ( node -- #drop )
|
||||||
node-in-d in-d-node <#drop> ;
|
node-in-d in-d-node <#drop> ;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 lists sequences vectors words ;
|
USING: namespaces generic hashtables kernel lists sequences
|
||||||
|
vectors words ;
|
||||||
|
|
||||||
! Method inlining optimization
|
! Method inlining optimization
|
||||||
|
|
||||||
|
|
@ -33,6 +34,9 @@ M: 2generic dispatching-values drop node-in-d 2 swap tail* ;
|
||||||
: inlining-class ( #call -- class )
|
: inlining-class ( #call -- class )
|
||||||
#! If the generic dispatch can be eliminated, return the
|
#! If the generic dispatch can be eliminated, return the
|
||||||
#! class of the method that will always be invoked here.
|
#! class of the method that will always be invoked here.
|
||||||
|
dup node-param recursive-state get member? [
|
||||||
|
drop f
|
||||||
|
] [
|
||||||
dup dispatching-classes dup empty? [
|
dup dispatching-classes dup empty? [
|
||||||
2drop f
|
2drop f
|
||||||
] [
|
] [
|
||||||
|
|
@ -41,15 +45,29 @@ M: 2generic dispatching-values drop node-in-d 2 swap tail* ;
|
||||||
] [
|
] [
|
||||||
2drop f
|
2drop f
|
||||||
] ifte
|
] ifte
|
||||||
|
] ifte
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
||||||
: subst-node
|
: unlink-last ( node -- butlast last )
|
||||||
[ last-node set-node-successor ] keep ;
|
dup penultimate-node
|
||||||
|
dup node-successor
|
||||||
|
f rot set-node-successor ;
|
||||||
|
|
||||||
|
: subst-node ( label old new -- new )
|
||||||
|
#! #simple-label<label> ---> new-last ---> old
|
||||||
|
#! |---> new-butlast
|
||||||
|
dup node-successor [
|
||||||
|
unlink-last rot over set-node-successor
|
||||||
|
>r >r #simple-label r> 1vector over set-node-children
|
||||||
|
r> over set-node-successor
|
||||||
|
] [
|
||||||
|
[ set-node-successor drop ] keep
|
||||||
|
] ifte ;
|
||||||
|
|
||||||
: inline-method ( node class -- node )
|
: inline-method ( node class -- node )
|
||||||
over node-param "methods" word-prop hash
|
over node-param "methods" word-prop hash
|
||||||
over node-in-d dataflow-with
|
over node-in-d dataflow-with
|
||||||
subst-node ;
|
>r [ node-param ] keep r> subst-node ;
|
||||||
|
|
||||||
: related? ( actual testing -- ? )
|
: related? ( actual testing -- ? )
|
||||||
#! If actual is a subset of testing or if the two classes
|
#! If actual is a subset of testing or if the two classes
|
||||||
|
|
@ -72,8 +90,8 @@ M: 2generic dispatching-values drop node-in-d 2 swap tail* ;
|
||||||
[ >r subst-literal r> set-node-successor ] keep ;
|
[ >r subst-literal r> set-node-successor ] keep ;
|
||||||
|
|
||||||
: optimize-predicate ( #call -- node )
|
: optimize-predicate ( #call -- node )
|
||||||
dup node-param "predicating" word-prop
|
dup node-param "predicating" word-prop >r
|
||||||
over dup node-in-d safe-node-classes first class<
|
dup dup node-in-d safe-node-classes first r> class<
|
||||||
inline-literal ;
|
inline-literal ;
|
||||||
|
|
||||||
M: #call optimize-node* ( node -- node/t )
|
M: #call optimize-node* ( node -- node/t )
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
! 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 inference kernel lists matrices
|
USING: #<unknown> generic hashtables inference kernel lists
|
||||||
namespaces sequences vectors ;
|
matrices namespaces sequences vectors ;
|
||||||
|
|
||||||
|
! We use the recursive-state variable here, to track nested
|
||||||
|
! label scopes, to prevent infinite loops when inlining
|
||||||
|
! recursive methods.
|
||||||
|
|
||||||
GENERIC: literals* ( node -- )
|
GENERIC: literals* ( node -- )
|
||||||
|
|
||||||
|
|
@ -57,11 +61,18 @@ GENERIC: optimize-node* ( node -- node )
|
||||||
|
|
||||||
DEFER: optimize-node ( node -- node/t )
|
DEFER: optimize-node ( node -- node/t )
|
||||||
|
|
||||||
: optimize-children ( node -- )
|
GENERIC: optimize-children
|
||||||
|
|
||||||
|
M: node optimize-children ( node -- )
|
||||||
f swap [
|
f swap [
|
||||||
node-children [ optimize-node swap >r or r> ] map
|
node-children [ optimize-node swap >r or r> ] map
|
||||||
] keep set-node-children ;
|
] keep set-node-children ;
|
||||||
|
|
||||||
|
: optimize-label ( node -- node )
|
||||||
|
dup node-param recursive-state [ cons ] change
|
||||||
|
delegate optimize-children
|
||||||
|
recursive-state [ cdr ] change ;
|
||||||
|
|
||||||
: keep-optimizing ( node -- node ? )
|
: keep-optimizing ( node -- node ? )
|
||||||
dup optimize-node* dup t =
|
dup optimize-node* dup t =
|
||||||
[ drop f ] [ nip keep-optimizing t or ] ifte ;
|
[ drop f ] [ nip keep-optimizing t or ] ifte ;
|
||||||
|
|
@ -77,10 +88,12 @@ DEFER: optimize-node ( node -- node/t )
|
||||||
: optimize ( dataflow -- dataflow )
|
: optimize ( dataflow -- dataflow )
|
||||||
#! Remove redundant literals from the IR. The original IR
|
#! Remove redundant literals from the IR. The original IR
|
||||||
#! is destructively modified.
|
#! is destructively modified.
|
||||||
|
[
|
||||||
|
recursive-state off
|
||||||
dup kill-set over kill-node
|
dup kill-set over kill-node
|
||||||
dup infer-classes
|
dup infer-classes
|
||||||
optimize-node
|
optimize-node
|
||||||
[ optimize ] when ;
|
] with-scope [ optimize ] when ;
|
||||||
|
|
||||||
: prune-if ( node quot -- successor/t )
|
: prune-if ( node quot -- successor/t )
|
||||||
over >r call [ r> node-successor ] [ r> drop t ] ifte ;
|
over >r call [ r> node-successor ] [ r> drop t ] ifte ;
|
||||||
|
|
@ -182,6 +195,13 @@ M: #call-label can-kill* ( literal node -- ? )
|
||||||
M: #label can-kill* ( literal node -- ? )
|
M: #label can-kill* ( literal node -- ? )
|
||||||
node-children first can-kill? ;
|
node-children first can-kill? ;
|
||||||
|
|
||||||
|
M: #simple-label can-kill* ( literal node -- ? )
|
||||||
|
node-children first can-kill? ;
|
||||||
|
|
||||||
|
M: #label optimize-children optimize-label ;
|
||||||
|
|
||||||
|
M: #simple-label optimize-children optimize-label ;
|
||||||
|
|
||||||
! #ifte
|
! #ifte
|
||||||
SYMBOL: branch-returns
|
SYMBOL: branch-returns
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,9 @@ M: #label node>quot ( ? node -- )
|
||||||
[ "#label: " over node-param word-name append comment, ] 2keep
|
[ "#label: " over node-param word-name append comment, ] 2keep
|
||||||
node-children first swap dataflow>quot , \ call , ;
|
node-children first swap dataflow>quot , \ call , ;
|
||||||
|
|
||||||
|
M: #simple-label node>quot ( ? node -- )
|
||||||
|
node-children first swap dataflow>quot % ;
|
||||||
|
|
||||||
M: #ifte node>quot ( ? node -- )
|
M: #ifte node>quot ( ? node -- )
|
||||||
[ "#ifte" comment, ] 2keep
|
[ "#ifte" comment, ] 2keep
|
||||||
node-children [ swap dataflow>quot ] map-with % \ ifte , ;
|
node-children [ swap dataflow>quot ] map-with % \ ifte , ;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
IN: kernel
|
IN: kernel
|
||||||
USING: generic kernel-internals vectors ;
|
USING: generic kernel-internals vectors ;
|
||||||
|
|
||||||
UNION: boolean f t ;
|
UNION: boolean POSTPONE: f POSTPONE: t ;
|
||||||
COMPLEMENT: general-t f
|
COMPLEMENT: general-t f
|
||||||
|
|
||||||
GENERIC: hashcode ( obj -- n )
|
GENERIC: hashcode ( obj -- n )
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,7 @@ USING: syntax generic kernel lists namespaces parser words ;
|
||||||
CREATE dup intern-symbol
|
CREATE dup intern-symbol
|
||||||
dup rot "superclass" set-word-prop
|
dup rot "superclass" set-word-prop
|
||||||
dup predicate-word
|
dup predicate-word
|
||||||
[ dupd unit "predicate" set-word-prop ] keep
|
[ define-predicate-class ] [ ] ; parsing
|
||||||
[ define-predicate ] [ ] ; parsing
|
|
||||||
|
|
||||||
: TUPLE:
|
: TUPLE:
|
||||||
#! Followed by a tuple name, then slot names, then ;
|
#! Followed by a tuple name, then slot names, then ;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
IN: temporary
|
|
||||||
|
GENERIC: xyz
|
||||||
|
M: cons xyz xyz ;
|
||||||
|
|
||||||
|
[ ] [ \ xyz compile ] unit-testIN: temporary
|
||||||
USING: generic kernel-internals strings vectors ;
|
USING: generic kernel-internals strings vectors ;
|
||||||
USE: test
|
USE: test
|
||||||
USE: assembler
|
USE: assembler
|
||||||
|
|
@ -111,3 +115,42 @@ GENERIC: xyz
|
||||||
M: cons xyz xyz ;
|
M: cons xyz xyz ;
|
||||||
|
|
||||||
[ ] [ \ xyz compile ] unit-test
|
[ ] [ \ xyz compile ] unit-test
|
||||||
|
|
||||||
|
! Test predicate inlining
|
||||||
|
: pred-test-1
|
||||||
|
dup cons? [
|
||||||
|
dup general-list? [ "general-list" ] [ "nope" ] ifte
|
||||||
|
] [
|
||||||
|
"not a cons"
|
||||||
|
] ifte ; compiled
|
||||||
|
|
||||||
|
[ [[ 1 2 ]] "general-list" ] [ [[ 1 2 ]] pred-test-1 ] unit-test
|
||||||
|
|
||||||
|
: pred-test-2
|
||||||
|
dup fixnum? [
|
||||||
|
dup integer? [ "integer" ] [ "nope" ] ifte
|
||||||
|
] [
|
||||||
|
"not a fixnum"
|
||||||
|
] ifte ; compiled
|
||||||
|
|
||||||
|
[ 1 "integer" ] [ 1 pred-test-2 ] unit-test
|
||||||
|
|
||||||
|
TUPLE: pred-test ;
|
||||||
|
|
||||||
|
: pred-test-3
|
||||||
|
dup tuple? [
|
||||||
|
dup pred-test? [ "pred-test" ] [ "nope" ] ifte
|
||||||
|
] [
|
||||||
|
"not a tuple"
|
||||||
|
] ifte ; compiled
|
||||||
|
|
||||||
|
[ 1 "pred-test" ] [ << pred-test >> pred-test-3 ] unit-test
|
||||||
|
|
||||||
|
: pred-test-4
|
||||||
|
dup pred-test? [
|
||||||
|
dup tuple? [ "pred-test" ] [ "nope" ] ifte
|
||||||
|
] [
|
||||||
|
"not a tuple"
|
||||||
|
] ifte ; compiled
|
||||||
|
|
||||||
|
[ << pred-test >> "pred-test" ] [ << pred-test >> pred-test-4 ] unit-test
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,7 @@ DEFER: bah
|
||||||
FORGET: bah
|
FORGET: bah
|
||||||
UNION: bah fixnum alien ;
|
UNION: bah fixnum alien ;
|
||||||
[ bah ] [ fixnum alien class-or ] unit-test
|
[ bah ] [ fixnum alien class-or ] unit-test
|
||||||
|
[ bah ] [ \ bah? "predicating" word-prop ] unit-test
|
||||||
|
|
||||||
DEFER: complement-test
|
DEFER: complement-test
|
||||||
FORGET: complement-test
|
FORGET: complement-test
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue