factor/basis/compiler/tree/propagation/inlining/inlining.factor

175 lines
4.7 KiB
Factor
Raw Normal View History

! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors kernel arrays sequences math math.order
2008-08-31 20:17:04 -04:00
math.partial-dispatch generic generic.standard generic.math
classes.algebra classes.union sets quotations assocs combinators
words namespaces continuations
compiler.tree
compiler.tree.builder
compiler.tree.recursive
compiler.tree.combinators
compiler.tree.normalization
compiler.tree.propagation.info
compiler.tree.propagation.nodes ;
IN: compiler.tree.propagation.inlining
! We count nodes up-front; if there are relatively few nodes,
! we are more eager to inline
SYMBOL: node-count
: count-nodes ( nodes -- )
0 swap [ drop 1+ ] each-node node-count set ;
! Splicing nodes
GENERIC: splicing-nodes ( #call word/quot/f -- nodes )
M: word splicing-nodes
[ [ in-d>> ] [ out-d>> ] bi ] dip #call 1array ;
M: quotation splicing-nodes
2008-09-12 06:36:06 -04:00
build-sub-tree analyze-recursive normalize ;
: propagate-body ( #call -- )
body>> (propagate) ;
! Dispatch elimination
: eliminate-dispatch ( #call class/f word/quot/f -- ? )
2008-08-30 03:31:27 -04:00
dup [
[ >>class ] dip
over method>> over = [ drop ] [
2dup splicing-nodes
[ >>method ] [ >>body ] bi*
] if
propagate-body t
2008-08-30 03:31:27 -04:00
] [ 2drop f >>method f >>body f >>class drop f ] if ;
2008-08-30 03:31:27 -04:00
: inlining-standard-method ( #call word -- class/f method/f )
[ in-d>> <reversed> ] [ [ dispatch# ] keep ] bi*
2008-08-30 03:31:27 -04:00
[ swap nth value-info class>> dup ] dip
specific-method ;
: inline-standard-method ( #call word -- ? )
dupd inlining-standard-method eliminate-dispatch ;
: normalize-math-class ( class -- class' )
{
null
fixnum bignum integer
ratio rational
float real
complex number
object
} [ class<= ] with find nip ;
2008-08-30 03:31:27 -04:00
: inlining-math-method ( #call word -- class/f quot/f )
swap in-d>>
first2 [ value-info class>> normalize-math-class ] bi@
2008-08-30 03:31:27 -04:00
3dup math-both-known?
[ math-method* ] [ 3drop f ] if
number swap ;
: inline-math-method ( #call word -- ? )
dupd inlining-math-method eliminate-dispatch ;
2008-08-30 03:31:27 -04:00
: inlining-math-partial ( #call word -- class/f quot/f )
[ "derived-from" word-prop first inlining-math-method ]
[ nip 1quotation ] 2bi
[ = not ] [ drop ] 2bi and ;
: inline-math-partial ( #call word -- ? )
dupd inlining-math-partial eliminate-dispatch ;
! Method body inlining
SYMBOL: recursive-calls
DEFER: (flat-length)
: word-flat-length ( word -- n )
{
! not inline
{ [ dup inline? not ] [ drop 1 ] }
! recursive and inline
{ [ dup recursive-calls get key? ] [ drop 10 ] }
! inline
[ [ recursive-calls get conjoin ] [ def>> (flat-length) ] bi ]
} cond ;
: (flat-length) ( seq -- n )
[
{
{ [ dup quotation? ] [ (flat-length) 2 + ] }
{ [ dup array? ] [ (flat-length) ] }
{ [ dup word? ] [ word-flat-length ] }
[ drop 0 ]
} cond
] sigma ;
: flat-length ( word -- n )
H{ } clone recursive-calls [
[ recursive-calls get conjoin ]
[ def>> (flat-length) 5 /i ]
bi
] with-variable ;
: classes-known? ( #call -- ? )
in-d>> [
value-info class>>
[ class-types length 1 = ]
[ union-class? not ]
bi and
] contains? ;
: inlining-rank ( #call word -- n )
[ classes-known? 2 0 ? ]
[
{
[ drop node-count get 45 swap [-] 8 /i ]
[ flat-length 24 swap [-] 4 /i ]
[ "default" word-prop -4 0 ? ]
[ "specializer" word-prop 1 0 ? ]
[ method-body? 1 0 ? ]
} cleave
] bi* + + + + + ;
: should-inline? ( #call word -- ? )
inlining-rank 5 >= ;
SYMBOL: history
: remember-inlining ( word -- )
2008-08-15 00:35:19 -04:00
history [ swap suffix ] change ;
2008-08-28 23:28:34 -04:00
: inline-word ( #call word -- ? )
dup history get memq? [
2008-08-28 23:28:34 -04:00
2drop f
] [
[
dup remember-inlining
dupd def>> splicing-nodes >>body
propagate-body
] with-scope
2008-08-28 23:28:34 -04:00
t
] if ;
: inline-method-body ( #call word -- ? )
2008-08-28 23:28:34 -04:00
2dup should-inline? [ inline-word ] [ 2drop f ] if ;
2008-08-02 00:31:43 -04:00
: always-inline-word? ( word -- ? )
{ curry compose } memq? ;
2008-08-31 20:17:04 -04:00
: custom-inlining? ( word -- ? )
"custom-inlining" word-prop ;
: inline-custom ( #call word -- ? )
[ dup 1array ] [ "custom-inlining" word-prop ] bi* with-datastack
first object swap eliminate-dispatch ;
2008-08-31 20:17:04 -04:00
: do-inlining ( #call word -- ? )
{
{ [ dup custom-inlining? ] [ inline-custom ] }
2008-08-31 20:17:04 -04:00
{ [ dup always-inline-word? ] [ inline-word ] }
{ [ dup standard-generic? ] [ inline-standard-method ] }
{ [ dup math-generic? ] [ inline-math-method ] }
{ [ dup method-body? ] [ inline-method-body ] }
[ 2drop f ]
} cond ;