factor/library/inference/kill-literals.factor

122 lines
2.8 KiB
Factor
Raw Normal View History

2005-08-07 00:00:57 -04:00
! 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
2005-08-07 00:00:57 -04:00
USING: generic hashtables inference kernel lists
matrices namespaces sequences vectors ;
2005-09-07 17:21:11 -04:00
GENERIC: literals* ( node -- seq )
2005-08-07 00:00:57 -04:00
: literals ( node -- seq )
[ [ literals* % ] each-node ] { } make prune ;
2005-08-07 00:00:57 -04:00
2005-09-07 17:21:11 -04:00
GENERIC: can-kill* ( literal node -- ? )
: can-kill? ( literal node -- ? )
2005-09-07 17:21:11 -04:00
dup [
2dup can-kill* [
node-successor can-kill?
] [
2drop f
] ifte
] [
2drop t
] ifte ;
2005-08-07 00:00:57 -04:00
: kill-set ( node -- list )
#! Push a list of literals that may be killed in the IR.
2005-09-07 17:21:11 -04:00
dup literals [ swap can-kill? ] subset-with ;
2005-08-07 00:00:57 -04:00
: remove-values ( values node -- )
2dup [ node-in-d seq-diff ] keep set-node-in-d
2dup [ node-out-d seq-diff ] keep set-node-out-d
2dup [ node-in-r seq-diff ] keep set-node-in-r
[ node-out-r seq-diff ] keep set-node-out-r ;
: kill-node ( literals node -- )
2005-09-07 17:21:11 -04:00
[ remove-values ] each-node-with ;
2005-08-07 00:00:57 -04:00
! Generic nodes
2005-09-07 17:21:11 -04:00
M: node literals* ( node -- ) drop { } ;
2005-08-07 00:00:57 -04:00
M: node can-kill* ( literal node -- ? )
uses-value? not ;
2005-08-07 00:00:57 -04:00
2005-09-04 17:07:59 -04:00
! #shuffle
M: #shuffle literals* ( node -- )
node-out-d [ literal? ] subset ;
2005-09-07 17:21:11 -04:00
M: #shuffle can-kill* ( literal node -- ? ) 2drop t ;
2005-08-07 00:00:57 -04:00
! #call-label
2005-09-07 17:21:11 -04:00
M: #call-label can-kill* ( literal node -- ? ) 2drop t ;
2005-08-07 00:00:57 -04:00
! #merge
2005-09-07 17:21:11 -04:00
M: #merge can-kill* ( literal node -- ? ) 2drop t ;
2005-08-07 00:00:57 -04:00
! #entry
2005-09-07 17:21:11 -04:00
M: #entry can-kill* ( literal node -- ? ) 2drop t ;
! #values
M: #values can-kill* ( literal node -- ? ) 2drop t ;
2005-09-07 17:21:11 -04:00
! #return
SYMBOL: branch-returns
GENERIC: returns*
UNION: #branch #ifte #dispatch ;
M: #branch returns*
node-children [ last-node returns* ] each ;
M: #return returns* , ;
M: node returns* node-successor returns* ;
: returns ( node -- seq )
#! Trace all control flow paths, build a sequence of
#! final #return nodes.
[ returns* ] { } make ;
: branch-values ( branches -- )
returns [ node-in-d ] map unify-lengths flip \ returns set ;
2005-09-07 17:21:11 -04:00
M: #return can-kill* ( literal node -- ? )
#! Values returned by local labels can be killed.
dup node-param [
dupd uses-value? [
\ returns get
2005-09-07 17:21:11 -04:00
[ memq? ] subset-with
[ [ eq? ] monotonic? ] all?
] [
drop t
] ifte
] [
delegate can-kill*
] ifte ;
: can-kill-branches? ( literal node -- ? )
#! Check if the literal appears in either branch. This
#! assumes that the last element of each branch is a #return
#! node.
2dup uses-value? [
2drop f
] [
[
dup branch-values
node-children [ can-kill? ] all-with?
2005-09-07 17:21:11 -04:00
] with-scope
] ifte ;
! #ifte
M: #ifte can-kill* ( literal node -- ? )
can-kill-branches? ;
! #dispatch
M: #dispatch can-kill* ( literal node -- ? )
can-kill-branches? ;
! #label
M: #label can-kill* ( literal node -- ? )
node-child can-kill? ;