2005-08-01 16:22:53 -04:00
|
|
|
! Copyright (C) 2004, 2005 Slava Pestov.
|
|
|
|
! See http://factor.sf.net/license.txt for BSD license.
|
|
|
|
IN: inference
|
2005-08-02 00:25:05 -04:00
|
|
|
USING: generic hashtables kernel lists sequences vectors words ;
|
2005-08-01 16:22:53 -04:00
|
|
|
|
|
|
|
! Method inlining optimization
|
2005-08-02 00:25:05 -04:00
|
|
|
|
2005-08-01 16:22:53 -04:00
|
|
|
: min-class? ( class seq -- ? )
|
|
|
|
#! Is this class the smallest class in the sequence?
|
|
|
|
2dup member? [
|
|
|
|
[ dupd class-and ] map
|
|
|
|
[ null = not ] subset
|
|
|
|
[ class< ] all-with?
|
|
|
|
] [
|
|
|
|
2drop f
|
|
|
|
] ifte ;
|
|
|
|
|
2005-08-02 00:25:05 -04:00
|
|
|
GENERIC: dispatching-values ( node word -- seq )
|
|
|
|
|
|
|
|
M: object dispatching-values 2drop { } ;
|
|
|
|
|
|
|
|
M: simple-generic dispatching-values drop node-in-d peek 1vector ;
|
|
|
|
|
|
|
|
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 ;
|
2005-08-01 16:22:53 -04:00
|
|
|
|
|
|
|
: inline-method? ( #call -- ? )
|
2005-08-02 00:25:05 -04:00
|
|
|
dup dispatching-classes dup empty? [
|
|
|
|
2drop f
|
|
|
|
] [
|
|
|
|
dup [ = ] every? [
|
|
|
|
first swap node-param order min-class?
|
2005-08-01 16:22:53 -04:00
|
|
|
] [
|
|
|
|
2drop f
|
|
|
|
] ifte
|
|
|
|
] ifte ;
|
|
|
|
|
2005-08-02 00:25:05 -04:00
|
|
|
: subst-node
|
|
|
|
[ last-node set-node-successor ] keep ;
|
2005-08-01 16:22:53 -04:00
|
|
|
|
|
|
|
: inline-method ( node -- node )
|
2005-08-02 00:25:05 -04:00
|
|
|
dup dispatching-classes first
|
2005-08-01 16:22:53 -04:00
|
|
|
over node-param "methods" word-prop hash
|
|
|
|
over node-in-d dataflow-with
|
2005-08-02 00:25:05 -04:00
|
|
|
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 ;
|
2005-08-01 16:22:53 -04:00
|
|
|
|
|
|
|
M: #call optimize-node* ( node -- node/t )
|
|
|
|
dup node-param [
|
|
|
|
dup inline-method? [
|
|
|
|
inline-method
|
|
|
|
] [
|
2005-08-02 00:25:05 -04:00
|
|
|
dup optimize-predicate? [
|
|
|
|
optimize-predicate
|
2005-08-01 16:22:53 -04:00
|
|
|
] [
|
2005-08-02 00:25:05 -04:00
|
|
|
dup optimize-not? [
|
|
|
|
node-successor dup flip-branches
|
|
|
|
] [
|
|
|
|
drop t
|
|
|
|
] ifte
|
2005-08-01 16:22:53 -04:00
|
|
|
] ifte
|
|
|
|
] ifte
|
|
|
|
] [
|
|
|
|
node-successor
|
|
|
|
] ifte ;
|
|
|
|
|
|
|
|
: post-inline ( #return #call -- node )
|
|
|
|
[ >r node-in-d r> node-out-d ] keep
|
|
|
|
node-successor [ subst-values ] keep ;
|
|
|
|
|
|
|
|
M: #return optimize-node* ( node -- node/t )
|
|
|
|
#! A #return followed by another node is a result of
|
|
|
|
#! method inlining. Do a value substitution and drop both
|
|
|
|
#! nodes.
|
|
|
|
dup node-successor dup [ post-inline ] [ 2drop t ] ifte ;
|