optimize out arithmetic dispatch and known-outcome type predicates
parent
1d0ccef23d
commit
f780ad0b33
|
@ -180,13 +180,6 @@ SYMBOL: object
|
||||||
] ifte
|
] ifte
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
||||||
: class-or-list ( list -- class )
|
|
||||||
#! Return a class that every class in the list is a
|
|
||||||
#! subclass of.
|
|
||||||
[
|
|
||||||
[ builtin-supertypes [ unique, ] each ] each
|
|
||||||
] make-list lookup-union ;
|
|
||||||
|
|
||||||
: class-and ( class class -- class )
|
: class-and ( class class -- class )
|
||||||
#! Return a class that is a subclass of both, or null in
|
#! Return a class that is a subclass of both, or null in
|
||||||
#! the degenerate case.
|
#! the degenerate case.
|
||||||
|
|
|
@ -7,7 +7,7 @@ IN: generic
|
||||||
USING: kernel kernel-internals lists math namespaces parser
|
USING: kernel kernel-internals lists math namespaces parser
|
||||||
sequences strings vectors words ;
|
sequences strings vectors words ;
|
||||||
|
|
||||||
: simple-generic ( class generic def -- )
|
: define-typecheck ( class generic def -- )
|
||||||
#! Just like:
|
#! Just like:
|
||||||
#! GENERIC: generic
|
#! GENERIC: generic
|
||||||
#! M: class generic def ;
|
#! M: class generic def ;
|
||||||
|
@ -15,7 +15,7 @@ sequences strings vectors words ;
|
||||||
|
|
||||||
: define-slot-word ( class slot word quot -- )
|
: define-slot-word ( class slot word quot -- )
|
||||||
over [
|
over [
|
||||||
>r swap >fixnum r> cons simple-generic
|
>r swap >fixnum r> cons define-typecheck
|
||||||
] [
|
] [
|
||||||
2drop 2drop
|
2drop 2drop
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
|
@ -88,9 +88,8 @@ M: node child-ties ( node -- seq )
|
||||||
M: #call infer-classes* ( node -- )
|
M: #call infer-classes* ( node -- )
|
||||||
dup node-param [
|
dup node-param [
|
||||||
dup create-ties
|
dup create-ties
|
||||||
dup node-param "infer-effect" word-prop 2unseq
|
dup node-param "infer-effect" word-prop second
|
||||||
pick node-out-d intersect-classes
|
swap node-out-d intersect-classes
|
||||||
swap node-in-d intersect-classes
|
|
||||||
] [
|
] [
|
||||||
drop
|
drop
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
|
@ -118,5 +118,8 @@ SYMBOL: current-node
|
||||||
: last-node ( node -- last )
|
: last-node ( node -- last )
|
||||||
dup node-successor [ last-node ] [ ] ?ifte ;
|
dup node-successor [ last-node ] [ ] ?ifte ;
|
||||||
|
|
||||||
|
: drop-inputs ( node -- #drop )
|
||||||
|
node-in-d in-d-node <#drop> ;
|
||||||
|
|
||||||
! Recursive state. An alist, mapping words to labels.
|
! Recursive state. An alist, mapping words to labels.
|
||||||
SYMBOL: recursive-state
|
SYMBOL: recursive-state
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
! 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 sequences words ;
|
USING: generic hashtables kernel lists sequences vectors words ;
|
||||||
|
|
||||||
! Method inlining optimization
|
! Method inlining optimization
|
||||||
|
|
||||||
: min-class? ( class seq -- ? )
|
: min-class? ( class seq -- ? )
|
||||||
#! Is this class the smallest class in the sequence?
|
#! Is this class the smallest class in the sequence?
|
||||||
2dup member? [
|
2dup member? [
|
||||||
|
@ -14,42 +15,83 @@ USING: generic hashtables kernel sequences words ;
|
||||||
2drop f
|
2drop f
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
||||||
: node-dispatching-class ( node -- class )
|
GENERIC: dispatching-values ( node word -- seq )
|
||||||
dup node-in-d peek dup value-safe? [
|
|
||||||
swap node-classes ?hash
|
M: object dispatching-values 2drop { } ;
|
||||||
] [
|
|
||||||
2drop object
|
M: simple-generic dispatching-values drop node-in-d peek 1vector ;
|
||||||
] ifte ;
|
|
||||||
|
M: 2generic dispatching-values drop node-in-d 2 swap tail* ;
|
||||||
|
|
||||||
|
: safe-node-classes ( node seq -- seq )
|
||||||
|
>r node-classes r> [
|
||||||
|
dup value-safe? [
|
||||||
|
swap ?hash [ object ] unless*
|
||||||
|
] [
|
||||||
|
2drop object
|
||||||
|
] ifte
|
||||||
|
] map-with ;
|
||||||
|
|
||||||
|
: dispatching-classes ( node -- seq )
|
||||||
|
dup dup node-param dispatching-values safe-node-classes ;
|
||||||
|
|
||||||
: inline-method? ( #call -- ? )
|
: inline-method? ( #call -- ? )
|
||||||
dup node-param "picker" word-prop [ dup ] = [
|
dup dispatching-classes dup empty? [
|
||||||
dup node-dispatching-class dup [
|
2drop f
|
||||||
swap node-param order min-class?
|
] [
|
||||||
|
dup [ = ] every? [
|
||||||
|
first swap node-param order min-class?
|
||||||
] [
|
] [
|
||||||
2drop f
|
2drop f
|
||||||
] ifte
|
] ifte
|
||||||
] [
|
|
||||||
drop f
|
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
||||||
: subst-node ( old new -- )
|
: subst-node
|
||||||
last-node set-node-successor ;
|
[ last-node set-node-successor ] keep ;
|
||||||
|
|
||||||
: inline-method ( node -- node )
|
: inline-method ( node -- node )
|
||||||
dup node-dispatching-class
|
dup dispatching-classes first
|
||||||
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 ] keep ;
|
subst-node ;
|
||||||
|
|
||||||
|
: related? ( class class -- ? )
|
||||||
|
#! If one of the two classes is contained in the other.
|
||||||
|
2dup class< >r swap class< r> or ;
|
||||||
|
|
||||||
|
: optimize-predicate? ( #call -- ? )
|
||||||
|
dup node-param "predicating" word-prop dup [
|
||||||
|
swap dup node-in-d safe-node-classes first related?
|
||||||
|
] [
|
||||||
|
2drop f
|
||||||
|
] ifte ;
|
||||||
|
|
||||||
|
: subst-literal ( successor literal -- #push )
|
||||||
|
#! Make #push -> #return -> successor
|
||||||
|
literalize dataflow [ last-node set-node-successor ] keep ;
|
||||||
|
|
||||||
|
: inline-literal ( node literal -- node )
|
||||||
|
over drop-inputs
|
||||||
|
[ >r subst-literal r> set-node-successor ] keep ;
|
||||||
|
|
||||||
|
: optimize-predicate ( #call -- node )
|
||||||
|
dup node-param "predicating" word-prop
|
||||||
|
over dup node-in-d safe-node-classes first class<
|
||||||
|
inline-literal ;
|
||||||
|
|
||||||
M: #call optimize-node* ( node -- node/t )
|
M: #call optimize-node* ( node -- node/t )
|
||||||
dup node-param [
|
dup node-param [
|
||||||
dup inline-method? [
|
dup inline-method? [
|
||||||
inline-method
|
inline-method
|
||||||
] [
|
] [
|
||||||
dup optimize-not? [
|
dup optimize-predicate? [
|
||||||
node-successor dup flip-branches
|
optimize-predicate
|
||||||
] [
|
] [
|
||||||
drop t
|
dup optimize-not? [
|
||||||
|
node-successor dup flip-branches
|
||||||
|
] [
|
||||||
|
drop t
|
||||||
|
] ifte
|
||||||
] ifte
|
] ifte
|
||||||
] ifte
|
] ifte
|
||||||
] [
|
] [
|
||||||
|
|
|
@ -206,7 +206,7 @@ SYMBOL: branch-returns
|
||||||
node-in-d first dup safe-literal? ;
|
node-in-d first dup safe-literal? ;
|
||||||
|
|
||||||
: static-branch ( conditional n -- node )
|
: static-branch ( conditional n -- node )
|
||||||
>r [ node-in-d in-d-node <#drop> ] keep r>
|
>r [ drop-inputs ] keep r>
|
||||||
over node-children nth
|
over node-children nth
|
||||||
over node-successor over last-node set-node-successor
|
over node-successor over last-node set-node-successor
|
||||||
pick set-node-successor drop ;
|
pick set-node-successor drop ;
|
||||||
|
|
|
@ -199,3 +199,8 @@ TUPLE: delegating ;
|
||||||
|
|
||||||
[ << shit f >> "shit" ] [ << shit f >> big-generic-test ] unit-test
|
[ << shit f >> "shit" ] [ << shit f >> big-generic-test ] unit-test
|
||||||
[ << shit f >> "shit" ] [ << delegating << shit f >> >> big-generic-test ] unit-test
|
[ << shit f >> "shit" ] [ << delegating << shit f >> >> big-generic-test ] unit-test
|
||||||
|
|
||||||
|
[ t ] [ \ = simple-generic? ] unit-test
|
||||||
|
[ f ] [ \ each simple-generic? ] unit-test
|
||||||
|
[ f ] [ \ object simple-generic? ] unit-test
|
||||||
|
[ t ] [ \ + 2generic? ] unit-test
|
||||||
|
|
Loading…
Reference in New Issue