started some class inference, dataflow optimizer improvements
parent
ac6ad36ae4
commit
869430fae0
|
@ -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"
|
||||||
|
|
|
@ -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 ;
|
||||||
|
|
||||||
|
|
|
@ -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 -- )
|
||||||
|
|
|
@ -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 ;
|
|
@ -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 ;
|
||||||
|
|
|
@ -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?
|
||||||
|
|
|
@ -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 ;
|
||||||
|
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
Loading…
Reference in New Issue