started some class inference, dataflow optimizer improvements

cvs
Slava Pestov 2005-07-28 19:17:31 +00:00
parent ac6ad36ae4
commit 869430fae0
8 changed files with 101 additions and 35 deletions

View File

@ -18,8 +18,6 @@ words ;
"Loading compiler backend..." print "Loading compiler backend..." print
cpu "x86" = [ cpu "x86" = [
"/library/compiler/vops.factor"
"/library/compiler/intrinsics.factor"
"/library/compiler/x86/assembler.factor" "/library/compiler/x86/assembler.factor"
"/library/compiler/x86/generator.factor" "/library/compiler/x86/generator.factor"
"/library/compiler/x86/slots.factor" "/library/compiler/x86/slots.factor"

View File

@ -166,6 +166,10 @@ M: hashtable hashcode ( hash -- n )
pick rot >r >r call dup r> r> set-hash pick rot >r >r call dup r> r> set-hash
] ifte* ; inline ] ifte* ; inline
: map>hash ( seq quot -- hash | quot: elt -- value )
over >r map r> dup length <hashtable> -rot
[ pick set-hash ] 2each ; inline
: ?hash ( key hash/f -- value/f ) : ?hash ( key hash/f -- value/f )
dup [ hash ] [ 2drop f ] ifte ; dup [ hash ] [ 2drop f ] ifte ;

View File

@ -118,9 +118,7 @@ M: object empty? ( seq -- ? ) length 0 = ;
M: object >list ( seq -- list ) dup length 0 rot (>list) ; M: object >list ( seq -- list ) dup length 0 rot (>list) ;
: index ( obj seq -- n ) [ = ] find-with drop ; : index ( obj seq -- n ) [ = ] find-with drop ;
: indq ( obj seq -- n ) [ eq? ] find-with drop ;
: index* ( obj i seq -- n ) [ = ] find-with* drop ; : index* ( obj i seq -- n ) [ = ] find-with* drop ;
: indq* ( obj i seq -- n ) [ eq? ] find-with* drop ;
: member? ( obj seq -- ? ) [ = ] contains-with? ; : member? ( obj seq -- ? ) [ = ] contains-with? ;
: memq? ( obj seq -- ? ) [ eq? ] contains-with? ; : memq? ( obj seq -- ? ) [ eq? ] contains-with? ;
: remove ( obj list -- list ) [ = not ] subset-with ; : remove ( obj list -- list ) [ = not ] subset-with ;
@ -189,9 +187,6 @@ M: object reverse ( seq -- seq ) [ <reversed> ] keep like ;
: seq-diff ( seq1 seq2 -- seq2-seq1 ) : seq-diff ( seq1 seq2 -- seq2-seq1 )
[ swap member? not ] subset-with ; [ swap member? not ] subset-with ;
: seq-diffq ( seq1 seq2 -- seq2-seq1 )
[ swap memq? not ] subset-with ;
: seq-union ( seq1 seq2 -- seq1\/seq2 ) : seq-union ( seq1 seq2 -- seq1\/seq2 )
append prune ; append prune ;
@ -237,7 +232,7 @@ M: object reverse ( seq -- seq ) [ <reversed> ] keep like ;
#! Substitute elements of old in seq with corresponding #! Substitute elements of old in seq with corresponding
#! elements from new. #! elements from new.
[ [
dup pick indq dup -1 = [ drop ] [ nip pick nth ] ifte dup pick index dup -1 = [ drop ] [ nip pick nth ] ifte
] map 2nip ; ] map 2nip ;
: copy-into ( to from -- ) : copy-into ( to from -- )

View File

@ -0,0 +1,63 @@
! Copyright (C) 2004, 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license.
IN: inference
USING: generic hashtables kernel namespaces sequences words ;
! Infer possible classes of values in a dataflow IR.
! Variables used by the class inferencer
! Current value --> class mapping
SYMBOL: value-classes
TUPLE: possibility value class ;
! Maps possibilities to possibilities.
SYMBOL: possible-classes
GENERIC: infer-classes* ( node -- )
: value-class ( value -- class )
value-classes get hash [ object ] unless* ;
: annotate-node ( node -- )
#! Annotate the node with the currently-inferred set of
#! value classes.
dup node-values [ value-class ] map>hash
swap set-node-classes ;
M: node infer-classes* ( node -- ) drop ;
: assume-classes ( classes values -- )
[ value-classes get set-hash ] 2each ;
: intersect-classes ( classes values -- )
[ [ value-class class-and ] 2map ] keep assume-classes ;
M: #call infer-classes* ( node -- )
dup node-param "infer-effect" word-prop 2unseq
pick node-out-d assume-classes
swap node-in-d intersect-classes ;
M: #push infer-classes* ( node -- )
node-out-d [
dup safe-literal? [
[ literal-value class ] keep
value-classes get set-hash
] [
drop
] ifte
] each ;
: (infer-classes) ( node -- )
dup infer-classes*
dup annotate-node
dup node-children [ (infer-classes) ] each
node-successor [ (infer-classes) ] when* ;
: infer-classes ( node -- )
[
<namespace> value-classes set
<namespace> possible-classes set
(infer-classes)
] with-scope ;

View File

@ -9,15 +9,16 @@ sequences vectors words ;
! code with stack flow information and types. ! code with stack flow information and types.
TUPLE: node param in-d out-d in-r out-r TUPLE: node param in-d out-d in-r out-r
successor children ; classes successor children ;
: make-node ( effect param in-d out-d in-r out-r node -- node ) M: node = eq? ;
[ >r f <node> r> set-delegate ] keep ;
: empty-node f f f f f f f f ; : make-node ( param in-d out-d in-r out-r node -- node )
: param-node ( label) f f f f f ; [ >r f f f <node> r> set-delegate ] keep ;
: in-d-node ( inputs) >r f r> f f f f ;
: out-d-node ( outputs) >r f f r> f f f ; : param-node ( label) f f f f ;
: in-d-node ( inputs) >r f r> f f f ;
: out-d-node ( outputs) >r f f r> f f ;
: d-tail ( n -- list ) meta-d get tail* >vector ; : d-tail ( n -- list ) meta-d get tail* >vector ;
: r-tail ( n -- list ) meta-r get tail* >vector ; : r-tail ( n -- list ) meta-r get tail* >vector ;
@ -106,13 +107,13 @@ SYMBOL: current-node
: node-effect ( node -- [[ d-in meta-d ]] ) : node-effect ( node -- [[ d-in meta-d ]] )
dup node-in-d swap node-out-d cons ; dup node-in-d swap node-out-d cons ;
: consumes-literal? ( literal node -- ? ) : node-values ( node -- values )
#! Does the dataflow node consume the literal? [
2dup node-in-d memq? >r node-in-r memq? r> or ; dup node-in-d % dup node-out-d %
dup node-in-r % node-out-r %
] make-vector ;
: produces-literal? ( literal node -- ? ) : uses-value? ( value node -- ? ) node-values memq? ;
#! Does the dataflow node produce the literal?
2dup node-out-d memq? >r node-out-r memq? r> or ;
: last-node ( node -- last ) : last-node ( node -- last )
dup node-successor [ last-node ] [ ] ?ifte ; dup node-successor [ last-node ] [ ] ?ifte ;

View File

@ -29,10 +29,10 @@ GENERIC: can-kill* ( literal node -- ? )
dup literals [ swap can-kill? ] subset-with ; dup literals [ swap can-kill? ] subset-with ;
: remove-value ( value node -- ) : remove-value ( value node -- )
2dup [ node-in-d seq-diffq ] keep set-node-in-d 2dup [ node-in-d seq-diff ] keep set-node-in-d
2dup [ node-out-d seq-diffq ] keep set-node-out-d 2dup [ node-out-d seq-diff ] keep set-node-out-d
2dup [ node-in-r seq-diffq ] keep set-node-in-r 2dup [ node-in-r seq-diff ] keep set-node-in-r
[ node-out-r seq-diffq ] keep set-node-out-r ; [ node-out-r seq-diff ] keep set-node-out-r ;
GENERIC: kill-node* ( literals node -- ) GENERIC: kill-node* ( literals node -- )
@ -92,7 +92,7 @@ M: f can-kill* ( literal node -- ? )
2drop t ; 2drop t ;
M: node can-kill* ( literal node -- ? ) M: node can-kill* ( literal node -- ? )
2dup consumes-literal? >r produces-literal? r> or not ; uses-value? ;
M: node kill-node* ( literals node -- ) M: node kill-node* ( literals node -- )
2drop ; 2drop ;
@ -110,7 +110,7 @@ M: #push can-kill* ( literal node -- ? )
2drop t ; 2drop t ;
M: #push kill-node* ( literals node -- ) M: #push kill-node* ( literals node -- )
[ node-out-d seq-diffq ] keep set-node-out-d ; [ node-out-d seq-diff ] keep set-node-out-d ;
M: #push optimize-node* ( node -- node/t ) M: #push optimize-node* ( node -- node/t )
[ node-out-d empty? ] prune-if ; [ node-out-d empty? ] prune-if ;
@ -198,7 +198,7 @@ SYMBOL: branch-returns
#! Check if the literal appears in either branch. This #! Check if the literal appears in either branch. This
#! assumes that the last element of each branch is a #values #! assumes that the last element of each branch is a #values
#! node. #! node.
2dup consumes-literal? [ 2dup uses-value? [
2drop f 2drop f
] [ ] [
[ [
@ -229,7 +229,7 @@ M: #dispatch can-kill* ( literal node -- ? )
! #values ! #values
M: #values can-kill* ( literal node -- ? ) M: #values can-kill* ( literal node -- ? )
dupd consumes-literal? [ dupd uses-value? [
branch-returns get branch-returns get
[ memq? ] subset-with [ memq? ] subset-with
[ [ eq? ] fiber? ] all? [ [ eq? ] fiber? ] all?

View File

@ -1,6 +1,6 @@
IN: inference IN: inference
USING: generic inference io kernel kernel-internals math USING: generic hashtables inference io kernel kernel-internals
namespaces prettyprint sequences vectors words ; math namespaces prettyprint sequences vectors words ;
! A simple tool for turning dataflow IR into quotations, for ! A simple tool for turning dataflow IR into quotations, for
! debugging purposes. ! debugging purposes.
@ -13,13 +13,16 @@ M: annotation prettyprint* ( ann -- )
"( " over annotation-text " )" append3 "( " over annotation-text " )" append3
swap annotation-node object. ; swap annotation-node object. ;
: value-str ( values -- str ) : value-str ( classes values -- str )
length "x" <repeated> " " join ; [ swap ?hash [ [ object ] ] unless* ] map-with
[ word-name ] map
" " join ;
: effect-str ( node -- str ) : effect-str ( node -- str )
[ [
dup node-in-d value-str % dup node-classes swap
"-" % 2dup node-in-d value-str %
"--" %
node-out-d value-str % node-out-d value-str %
] make-string ; ] make-string ;

View File

@ -11,6 +11,8 @@ C: value ( recursion -- value )
[ t swap set-value-safe? ] keep [ t swap set-value-safe? ] keep
[ set-value-recursion ] keep ; [ set-value-recursion ] keep ;
M: value = eq? ;
TUPLE: computed ; TUPLE: computed ;
C: computed ( -- value ) C: computed ( -- value )