factor/library/compiler/optimizer/inline-methods.factor

103 lines
2.9 KiB
Factor
Raw Normal View History

2006-02-28 00:26:45 -05:00
! Copyright (C) 2004, 2006 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
2005-09-09 00:17:19 -04:00
IN: optimizer
USING: arrays generic hashtables inference kernel lists math
namespaces sequences words ;
2005-08-01 16:22:53 -04:00
! Method inlining optimization
GENERIC: dispatching-values ( node word -- seq )
M: object dispatching-values 2drop { } ;
2006-02-28 00:26:45 -05:00
M: standard-generic dispatching-values
"combination" word-prop first swap
node-in-d reverse-slice nth 1array ;
M: 2generic dispatching-values drop node-in-d 2 swap tail* ;
2005-08-07 00:00:57 -04:00
: node-classes* ( node seq -- seq )
>r node-classes r>
2005-09-23 01:22:04 -04:00
[ swap ?hash [ object ] unless* ] map-with ;
: dispatching-classes ( node -- seq )
2005-11-19 04:09:30 -05:00
dup node-in-d empty? [
drop { }
] [
dup dup node-param dispatching-values node-classes*
] if ;
2005-08-01 16:22:53 -04:00
: already-inlined? ( node -- ? )
#! Was this node inlined from definition of 'word'?
dup node-param swap node-history memq? ;
2005-08-02 06:32:48 -04:00
: inlining-class ( #call -- class )
#! If the generic dispatch can be eliminated, return the
#! class of the method that will always be invoked here.
dup already-inlined? [
drop f
] [
dup dispatching-classes dup empty? [
2005-08-01 16:22:53 -04:00
2drop f
] [
2005-09-18 01:37:28 -04:00
dup all-eq? [
first swap node-param order min-class
] [
2drop f
2005-09-24 15:21:17 -04:00
] if
] if
] if ;
2005-08-01 16:22:53 -04:00
: will-inline ( node -- quot )
dup inlining-class swap node-param "methods" word-prop hash ;
: method-dataflow ( node -- dataflow )
dup will-inline swap node-in-d dataflow-with ;
2005-08-01 16:22:53 -04:00
2006-03-02 01:12:32 -05:00
: post-inline ( #return/#values #call/#merge -- )
dup [
[
>r node-in-d r> node-out-d
2array unify-lengths first2
] keep subst-values
2006-03-02 01:12:32 -05:00
] [
2drop
] if ;
: subst-node ( old new -- )
#! The last node of 'new' becomes 'old', then values are
#! substituted. A subsequent optimizer phase kills the
#! last node of 'new' and the first node of 'old'.
last-node 2dup swap post-inline set-node-successor ;
2005-08-08 15:21:14 -04:00
: inline-method ( node -- node )
2005-08-13 04:01:21 -04:00
#! We set the #call node's param to f so that it gets killed
#! later.
dup method-dataflow
[ >r node-param r> remember-node ] 2keep
[ subst-node ] keep ;
2005-08-02 00:33:01 -04:00
: related? ( actual testing -- ? )
#! If actual is a subset of testing or if the two classes
#! are disjoint, return t.
2005-08-16 15:53:30 -04:00
2dup class< >r classes-intersect? not r> or ;
: optimize-predicate? ( #call -- ? )
dup node-param "predicating" word-prop dup [
2005-08-07 00:00:57 -04:00
>r dup node-in-d node-classes* first r> related?
] [
2drop f
2005-09-24 15:21:17 -04:00
] if ;
2006-03-02 01:12:32 -05:00
: inline-literals ( node literals -- node )
#! Make #push -> #return -> successor
over drop-inputs [
>r >list [ literalize ] map dataflow [ subst-node ] keep
r> set-node-successor
] keep ;
: optimize-predicate ( #call -- node )
dup node-param "predicating" word-prop >r
2005-08-07 00:00:57 -04:00
dup dup node-in-d node-classes* first r> class<
1array inline-literals ;