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

129 lines
3.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
kernel-internals lists math namespaces prettyprint sequences
words ;
2005-08-01 16:22:53 -04:00
! Some utilities for splicing in dataflow IR subtrees
2006-03-02 01:12:32 -05:00
: post-inline ( #return/#values #call/#merge -- )
[
>r node-in-d r> node-out-d 2array unify-lengths first2
] keep subst-values ;
: ?hash-union ( hash/f hash -- hash )
over [ hash-union ] [ nip ] if ;
: add-node-literals ( hash node -- )
[ node-literals ?hash-union ] keep set-node-literals ;
: add-node-classes ( hash node -- )
[ node-classes ?hash-union ] keep set-node-classes ;
: (subst-classes) ( literals classes node -- )
2006-03-02 01:12:32 -05:00
dup [
3dup [ add-node-classes ] keep add-node-literals
node-successor (subst-classes)
2006-03-02 01:12:32 -05:00
] [
3drop
2006-03-02 01:12:32 -05:00
] if ;
: subst-classes ( #return/#values #call/#merge -- )
>r dup node-literals swap node-classes r> (subst-classes) ;
2006-03-02 01:12:32 -05:00
: 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 2dup post-inline subst-classes
set-node-successor ;
2006-03-02 01:12:32 -05:00
2006-05-02 03:05:57 -04:00
: (inline-method) ( #call quot -- node )
dup t eq? [
2drop t
] [
over node-in-d dataflow-with
2dup infer-classes/node
over node-param over remember-node
2006-05-09 12:38:57 -04:00
[ subst-node ] keep
2006-05-02 03:05:57 -04:00
] if ;
! Single dispatch method inlining optimization
: dispatch# ( #call -- n )
node-param "combination" word-prop first ;
: dispatching-class ( node -- seq ) dup dispatch# node-class# ;
: already-inlined? ( node -- ? )
#! Was this node inlined from definition of 'word'?
dup node-param swap node-history memq? ;
: specific-method ( word class -- ? ) swap order min-class ;
: inlining-class ( #call -- class )
#! If the generic dispatch can be eliminated, return the
#! class of the method that will always be invoked here.
2006-05-02 20:26:48 -04:00
dup node-param swap dispatching-class specific-method ;
: will-inline-method ( node -- quot/t )
#! t indicates failure
dup inlining-class dup [
swap node-param "methods" word-prop hash
] [
2drop t
2005-09-24 15:21:17 -04:00
] if ;
: inline-standard-method ( node -- node )
dup will-inline-method (inline-method) ;
2006-03-02 01:12:32 -05:00
: inline-standard-method? ( #call -- ? )
dup already-inlined? not swap node-param standard-generic?
and ;
2006-05-02 03:05:57 -04:00
! Partial dispatch of 2generic words
2006-05-02 03:05:57 -04:00
: math-both-known? ( word left right -- ? )
math-class-max specific-method ;
2006-05-02 03:05:57 -04:00
: will-inline-math-method ( word left right -- quot/t )
#! t indicates failure
3dup math-both-known? [ math-method ] [ 3drop t ] if ;
2006-05-02 03:05:57 -04:00
: inline-math-method ( #call -- node )
dup node-param over 1 node-class# pick 0 node-class#
2006-05-02 03:05:57 -04:00
will-inline-math-method (inline-method) ;
: inline-math-method? ( #call -- ? )
2006-05-02 20:26:48 -04:00
dup node-history [ 2generic? ] contains? not
swap node-param 2generic? and ;
2006-05-02 03:05:57 -04:00
: inline-method ( #call -- node )
{
{ [ dup inline-standard-method? ] [ inline-standard-method ] }
{ [ dup inline-math-method? ] [ inline-math-method ] }
{ [ t ] [ drop t ] }
} cond ;
! Resolve type checks at compile time where possible
: comparable? ( actual testing -- ? )
#! If actual is a subset of testing or if the two classes
#! are disjoint, return t.
2dup class< >r classes-intersect? not r> or ;
: optimize-predicate? ( #call -- ? )
dup node-param "predicating" word-prop dup [
2006-05-02 20:26:48 -04:00
>r 0 node-class# r> comparable?
] [
2drop f
] if ;
: inline-literals ( node literals -- node )
#! Make #shuffle -> #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
dup 0 node-class# r> class< 1array inline-literals ;