factor/basis/compiler/tree/propagation/simple/simple.factor

159 lines
5.1 KiB
Factor
Raw Normal View History

! Copyright (C) 2008, 2009 Slava Pestov.
2008-07-20 05:24:37 -04:00
! See http://factorcode.org/license.txt for BSD license.
USING: fry accessors kernel sequences sequences.private assocs
words namespaces classes.algebra combinators
combinators.short-circuit classes classes.tuple
classes.tuple.private continuations arrays alien.c-types math
math.private slots generic definitions stack-checker.dependencies
2008-07-22 05:45:03 -04:00
compiler.tree
compiler.tree.propagation.info
compiler.tree.propagation.nodes
2008-07-25 03:07:45 -04:00
compiler.tree.propagation.slots
compiler.tree.propagation.inlining
2008-07-20 05:24:37 -04:00
compiler.tree.propagation.constraints ;
IN: compiler.tree.propagation.simple
! Propagation for straight-line code.
2008-07-20 05:24:37 -04:00
M: #introduce propagate-before
2008-08-14 00:52:49 -04:00
out-d>> [ object-info swap set-value-info ] each ;
2008-07-20 05:24:37 -04:00
M: #push propagate-before
[ literal>> <literal-info> ] [ out-d>> first ] bi
2008-07-22 05:45:03 -04:00
set-value-info ;
: refine-value-infos ( classes values -- )
[ refine-value-info ] 2each ;
: class-infos ( classes -- infos )
[ <class-info> ] map ;
: set-value-infos ( infos values -- )
[ set-value-info ] 2each ;
2008-07-20 05:24:37 -04:00
M: #declare propagate-before
2008-08-31 02:34:00 -04:00
#! We need to force the caller word to recompile when the
#! classes mentioned in the declaration are redefined, since
#! now we're making assumptions but their definitions.
declaration>> [
[ inlined-dependency depends-on ]
[ <class-info> swap refine-value-info ]
bi
] assoc-each ;
2008-07-20 05:24:37 -04:00
2008-07-22 05:45:03 -04:00
: predicate-constraints ( value class boolean-value -- constraint )
[ [ is-instance-of ] dip t--> ]
[ [ class-not is-instance-of ] dip f--> ]
3bi /\ ;
2008-07-20 05:24:37 -04:00
: custom-constraints ( #call quot -- )
[ [ in-d>> ] [ out-d>> ] bi append ] dip
with-datastack first assume ;
: compute-constraints ( #call word -- )
2008-08-31 20:17:04 -04:00
dup "constraints" word-prop [ nip custom-constraints ] [
dup predicate? [
[ [ in-d>> first ] [ out-d>> first ] bi ]
[ "predicating" word-prop ] bi*
swap predicate-constraints assume
] [ 2drop ] if
2008-07-20 05:24:37 -04:00
] if* ;
: call-outputs-quot ( #call word -- infos )
2008-08-31 20:17:04 -04:00
[ in-d>> [ value-info ] map ] [ "outputs" word-prop ] bi*
with-datastack ;
2008-07-25 03:07:45 -04:00
: literal-inputs? ( #call -- ? )
in-d>> [ value-info literal?>> ] all? ;
: input-classes-match? ( #call word -- ? )
[ in-d>> ] [ "input-classes" word-prop ] bi*
[ [ value-info literal>> ] dip instance? ] 2all? ;
: foldable-call? ( #call word -- ? )
{
[ nip "foldable" word-prop ]
[ drop literal-inputs? ]
[ input-classes-match? ]
} 2&& ;
2008-08-31 20:17:04 -04:00
: (fold-call) ( #call word -- info )
2008-09-10 23:11:40 -04:00
[ [ out-d>> ] [ in-d>> [ value-info literal>> ] map ] bi ] [ '[ _ execute ] ] bi*
'[ _ _ with-datastack [ <literal-info> ] map nip ]
2010-01-14 10:10:13 -05:00
[ drop length [ object-info ] replicate ]
2008-08-22 04:12:15 -04:00
recover ;
2008-08-31 20:17:04 -04:00
: fold-call ( #call word -- )
[ (fold-call) ] [ drop out-d>> ] 2bi set-value-infos ;
: predicate-output-infos/literal ( info class -- info )
[ literal>> ] dip
'[ _ _ instance? <literal-info> ]
[ drop object-info ]
recover ;
: predicate-output-infos/class ( info class -- info )
[ class>> ] dip {
{ [ 2dup class<= ] [ t <literal-info> ] }
{ [ 2dup classes-intersect? not ] [ f <literal-info> ] }
[ object-info ]
} cond 2nip ;
: predicate-output-infos ( info class -- info )
over literal?>>
[ predicate-output-infos/literal ]
[ predicate-output-infos/class ]
if ;
: propagate-predicate ( #call word -- infos )
2008-08-31 02:34:00 -04:00
#! We need to force the caller word to recompile when the class
#! is redefined, since now we're making assumptions but the
#! class definition itself.
[ in-d>> first value-info ]
[ "predicating" word-prop dup inlined-dependency depends-on ] bi*
predicate-output-infos 1array ;
: default-output-value-infos ( #call word -- infos )
"default-output-classes" word-prop
[ class-infos ] [ out-d>> length object-info <repetition> ] ?if ;
2008-07-20 05:24:37 -04:00
: output-value-infos ( #call word -- infos )
{
{ [ dup \ <tuple-boa> eq? ] [ drop propagate-<tuple-boa> ] }
2008-07-24 18:34:08 -04:00
{ [ dup sequence-constructor? ] [ propagate-sequence-constructor ] }
{ [ dup predicate? ] [ propagate-predicate ] }
2008-08-31 20:17:04 -04:00
{ [ dup "outputs" word-prop ] [ call-outputs-quot ] }
[ default-output-value-infos ]
} cond ;
2008-07-20 05:24:37 -04:00
M: #call propagate-before
2008-08-31 20:17:04 -04:00
dup word>> {
{ [ 2dup foldable-call? ] [ fold-call ] }
{ [ 2dup do-inlining ] [
[ output-value-infos ] [ drop out-d>> ] 2bi refine-value-infos
] }
2008-08-31 20:17:04 -04:00
[
[ [ output-value-infos ] [ drop out-d>> ] 2bi set-value-infos ]
[ compute-constraints ]
2bi
]
} cond ;
M: #call annotate-node
dup [ in-d>> ] [ out-d>> ] bi append (annotate-node) ;
: propagate-input-classes ( node input-classes -- )
class-infos swap in-d>> refine-value-infos ;
2008-07-22 05:45:03 -04:00
M: #call propagate-after
dup word>> "input-classes" word-prop dup
[ propagate-input-classes ] [ 2drop ] if ;
2008-08-12 03:41:18 -04:00
: propagate-alien-invoke ( node -- )
[ out-d>> ] [ params>> return>> ] bi
[ drop ] [ c-type-class <class-info> swap first set-value-info ] if-void ;
2008-08-12 03:41:18 -04:00
M: #alien-node propagate-before propagate-alien-invoke ;
M: #return annotate-node dup in-d>> (annotate-node) ;