factor/library/compiler/optimizer/class-infer.factor

170 lines
4.3 KiB
Factor
Raw Normal View History

! Copyright (C) 2004, 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license.
2005-09-09 00:17:19 -04:00
IN: optimizer
USING: arrays generic hashtables inference kernel
2005-09-14 00:37:50 -04:00
kernel-internals math namespaces sequences words ;
! Infer possible classes of values in a dataflow IR.
2006-05-02 03:05:57 -04:00
: node-class ( value node -- class )
node-classes ?hash [ object ] unless* ;
! Variables used by the class inferencer
! Current value --> class mapping
SYMBOL: value-classes
2005-07-28 18:20:31 -04:00
! Current value --> literal mapping
SYMBOL: value-literals
2005-07-30 02:08:59 -04:00
! Maps ties to ties
SYMBOL: ties
2005-07-28 18:20:31 -04:00
GENERIC: apply-tie ( tie -- )
M: f apply-tie ( f -- ) drop ;
TUPLE: class-tie value class ;
2006-01-22 16:56:27 -05:00
: set-value-class* ( class value -- )
2005-07-28 18:20:31 -04:00
2dup swap <class-tie> ties get hash [ apply-tie ] when*
value-classes get set-hash ;
M: class-tie apply-tie ( tie -- )
dup class-tie-class swap class-tie-value
2006-01-22 17:33:52 -05:00
set-value-class* ;
2005-07-28 18:20:31 -04:00
TUPLE: literal-tie value literal ;
2006-01-22 16:56:27 -05:00
: set-value-literal* ( literal value -- )
over class over set-value-class*
2005-07-28 18:20:31 -04:00
2dup swap <literal-tie> ties get hash [ apply-tie ] when*
value-literals get set-hash ;
M: literal-tie apply-tie ( tie -- )
dup literal-tie-literal swap literal-tie-value
2006-01-22 16:56:27 -05:00
set-value-literal* ;
2005-07-28 18:20:31 -04:00
GENERIC: infer-classes* ( node -- )
2005-07-28 18:20:31 -04:00
M: node infer-classes* ( node -- ) drop ;
! For conditionals, a map of child node # --> possibility
GENERIC: child-ties ( node -- seq )
M: node child-ties ( node -- seq )
2005-12-24 18:29:31 -05:00
node-children length f <array> ;
2005-07-28 18:20:31 -04:00
2006-01-22 16:56:27 -05:00
: value-class* ( value -- class )
value-classes get hash [ object ] unless* ;
2006-01-22 16:56:27 -05:00
: value-literal* ( value -- class )
2005-07-28 18:20:31 -04:00
value-literals get hash ;
: annotate-node ( node -- )
#! Annotate the node with the currently-inferred set of
#! value classes.
dup node-values
2006-01-22 16:56:27 -05:00
[ dup value-class* ] map>hash swap set-node-classes ;
: intersect-classes ( classes values -- )
[
2006-01-22 16:56:27 -05:00
[ value-class* class-and ] keep set-value-class*
] 2each ;
: set-tie ( tie tie -- ) ties get set-hash ;
: type/tag-ties ( node n -- )
over node-out-d first over [ <literal-tie> ] map-with
>r swap node-in-d first swap [ type>class <class-tie> ] map-with r>
[ set-tie ] 2each ;
\ type [ num-types type/tag-ties ] "create-ties" set-word-prop
\ tag [ num-tags type/tag-ties ] "create-ties" set-word-prop
\ eq? [
dup node-in-d second value? [
2006-01-22 16:56:27 -05:00
dup node-in-d first2 value-literal* <literal-tie>
over node-out-d first general-t <class-tie>
set-tie
] when drop
] "create-ties" set-word-prop
2005-07-28 18:20:31 -04:00
: create-ties ( #call -- )
#! If the node is calling a class test predicate, create a
#! tie.
dup node-param "create-ties" word-prop dup [
call
2005-07-28 18:20:31 -04:00
] [
drop dup node-param "predicating" word-prop dup [
>r dup node-in-d first r> <class-tie>
swap node-out-d first general-t <class-tie>
set-tie
] [
2drop
2005-09-24 15:21:17 -04:00
] if
] if ;
2005-07-28 18:20:31 -04:00
2005-08-02 01:28:38 -04:00
\ make-tuple [
2006-01-22 18:07:05 -05:00
dup node-in-d first value-literal 1array
2005-08-02 01:28:38 -04:00
] "output-classes" set-word-prop
: output-classes ( node -- seq )
dup node-param "output-classes" word-prop [
call
] [
node-param "infer-effect" word-prop second
2005-09-14 00:37:50 -04:00
dup integer? [ drop f ] when
2005-09-24 15:21:17 -04:00
] ?if ;
2005-08-02 01:28:38 -04:00
M: #call infer-classes* ( node -- )
2005-08-01 16:22:53 -04:00
dup node-param [
dup create-ties
2005-09-14 00:37:50 -04:00
dup output-classes
[ over node-out-d intersect-classes ] when*
] when drop ;
2006-04-17 17:17:34 -04:00
M: #push infer-classes* ( node -- )
node-out-d
2006-01-22 18:07:05 -05:00
[ [ value-literal ] keep set-value-literal* ] each ;
2005-07-28 18:20:31 -04:00
2005-09-24 15:21:17 -04:00
M: #if child-ties ( node -- seq )
2005-07-28 18:20:31 -04:00
node-in-d first dup general-t <class-tie>
swap f <literal-tie> 2array ;
2005-07-28 18:20:31 -04:00
M: #dispatch child-ties ( node -- seq )
dup node-in-d first
swap node-children length [ <literal-tie> ] map-with ;
M: #declare infer-classes* ( node -- )
dup node-param swap node-in-d [ set-value-class* ] 2each ;
2005-07-28 18:20:31 -04:00
DEFER: (infer-classes)
: infer-children ( node -- )
dup node-children swap child-ties [
[
value-classes [ clone ] change
ties [ clone ] change
apply-tie
(infer-classes)
] with-scope
] 2each ;
: (infer-classes) ( node -- )
2005-08-01 16:22:53 -04:00
[
dup infer-classes*
dup annotate-node
dup infer-children
node-successor (infer-classes)
] when* ;
: infer-classes ( node -- )
[
H{ } clone value-classes set
H{ } clone value-literals set
H{ } clone ties set
(infer-classes)
] with-scope ;