2008-07-20 05:24:37 -04:00
|
|
|
! Copyright (C) 2008 Slava Pestov.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
|
|
USING: fry accessors namespaces assocs dequeues search-dequeues
|
2008-08-13 15:17:04 -04:00
|
|
|
kernel sequences words sets arrays
|
|
|
|
stack-checker.state stack-checker.inlining
|
2008-07-24 00:50:21 -04:00
|
|
|
compiler.tree
|
2008-08-08 14:14:36 -04:00
|
|
|
compiler.tree.combinators
|
2008-07-27 21:25:42 -04:00
|
|
|
compiler.tree.dataflow-analysis
|
2008-08-08 14:14:36 -04:00
|
|
|
compiler.tree.dataflow-analysis.backward ;
|
2008-07-20 05:24:37 -04:00
|
|
|
IN: compiler.tree.dead-code
|
|
|
|
|
|
|
|
! Dead code elimination: remove #push and flushable #call whose
|
2008-07-24 00:50:21 -04:00
|
|
|
! outputs are unused using backward DFA.
|
2008-07-20 05:24:37 -04:00
|
|
|
GENERIC: mark-live-values ( node -- )
|
|
|
|
|
|
|
|
M: #if mark-live-values look-at-inputs ;
|
|
|
|
|
|
|
|
M: #dispatch mark-live-values look-at-inputs ;
|
|
|
|
|
|
|
|
M: #call mark-live-values
|
2008-07-24 00:50:21 -04:00
|
|
|
dup word>> "flushable" word-prop
|
2008-08-13 15:17:04 -04:00
|
|
|
[ drop ] [ look-at-inputs ] if ;
|
2008-07-20 05:24:37 -04:00
|
|
|
|
2008-08-13 15:17:04 -04:00
|
|
|
M: #alien-invoke mark-live-values look-at-inputs ;
|
2008-08-12 03:41:18 -04:00
|
|
|
|
2008-08-13 15:17:04 -04:00
|
|
|
M: #alien-indirect mark-live-values look-at-inputs ;
|
2008-08-12 03:41:18 -04:00
|
|
|
|
2008-08-13 15:17:04 -04:00
|
|
|
M: #return mark-live-values look-at-inputs ;
|
2008-07-20 05:24:37 -04:00
|
|
|
|
|
|
|
M: node mark-live-values drop ;
|
|
|
|
|
2008-07-24 00:50:21 -04:00
|
|
|
SYMBOL: live-values
|
2008-07-20 05:24:37 -04:00
|
|
|
|
2008-07-24 00:50:21 -04:00
|
|
|
: live-value? ( value -- ? ) live-values get at ;
|
2008-07-20 05:24:37 -04:00
|
|
|
|
2008-08-13 15:17:04 -04:00
|
|
|
GENERIC: remove-dead-code* ( node -- node' )
|
2008-07-20 05:24:37 -04:00
|
|
|
|
2008-08-13 15:17:04 -04:00
|
|
|
M: #introduce remove-dead-code*
|
|
|
|
dup value>> live-value? [
|
|
|
|
dup value>> 1array #drop 2array
|
|
|
|
] unless ;
|
2008-07-20 05:24:37 -04:00
|
|
|
|
|
|
|
: filter-live ( values -- values' )
|
|
|
|
[ live-value? ] filter ;
|
|
|
|
|
2008-08-13 15:17:04 -04:00
|
|
|
M: #>r remove-dead-code*
|
|
|
|
[ filter-live ] change-out-r
|
2008-08-08 14:14:36 -04:00
|
|
|
[ filter-live ] change-in-d
|
2008-08-13 15:17:04 -04:00
|
|
|
dup in-d>> empty? [ drop f ] when ;
|
|
|
|
|
|
|
|
M: #r> remove-dead-code*
|
2008-08-08 14:14:36 -04:00
|
|
|
[ filter-live ] change-out-d
|
2008-08-13 15:17:04 -04:00
|
|
|
[ filter-live ] change-in-r
|
|
|
|
dup in-r>> empty? [ drop f ] when ;
|
2008-08-08 14:14:36 -04:00
|
|
|
|
2008-08-13 15:17:04 -04:00
|
|
|
M: #push remove-dead-code*
|
|
|
|
dup out-d>> first live-value? [ drop f ] unless ;
|
|
|
|
|
|
|
|
: dead-flushable-call? ( #call -- ? )
|
|
|
|
[ word>> "flushable" word-prop ]
|
|
|
|
[ out-d>> [ live-value? not ] all? ] bi and ;
|
2008-08-08 14:14:36 -04:00
|
|
|
|
2008-08-13 15:17:04 -04:00
|
|
|
: remove-flushable-call ( #call -- node )
|
|
|
|
in-d>> #drop remove-dead-code* ;
|
|
|
|
|
|
|
|
: some-outputs-dead? ( #call -- ? )
|
|
|
|
out-d>> [ live-value? not ] contains? ;
|
|
|
|
|
|
|
|
: remove-dead-outputs ( #call -- nodes )
|
|
|
|
[ out-d>> ] [ [ [ <value> ] replicate ] change-out-d ] bi
|
|
|
|
[ nip ] [ out-d>> swap #copy remove-dead-code* ] 2bi
|
|
|
|
2array ;
|
|
|
|
|
|
|
|
M: #call remove-dead-code*
|
|
|
|
dup dead-flushable-call? [
|
|
|
|
remove-flushable-call
|
|
|
|
] [
|
|
|
|
dup some-outputs-dead? [
|
|
|
|
remove-dead-outputs
|
|
|
|
] when
|
|
|
|
] if ;
|
|
|
|
|
|
|
|
M: #recursive remove-dead-code*
|
|
|
|
[ filter-live ] change-in-d ;
|
|
|
|
|
|
|
|
M: #call-recursive remove-dead-code*
|
2008-08-08 14:14:36 -04:00
|
|
|
[ filter-live ] change-in-d
|
2008-08-13 15:17:04 -04:00
|
|
|
[ filter-live ] change-out-d ;
|
2008-08-08 14:14:36 -04:00
|
|
|
|
2008-08-13 15:17:04 -04:00
|
|
|
M: #enter-recursive remove-dead-code*
|
2008-08-08 14:14:36 -04:00
|
|
|
[ filter-live ] change-in-d
|
2008-08-13 15:17:04 -04:00
|
|
|
[ filter-live ] change-out-d ;
|
2008-08-08 14:14:36 -04:00
|
|
|
|
2008-08-13 15:17:04 -04:00
|
|
|
M: #return-recursive remove-dead-code*
|
2008-08-08 14:14:36 -04:00
|
|
|
[ filter-live ] change-in-d
|
2008-08-13 15:17:04 -04:00
|
|
|
[ filter-live ] change-out-d ;
|
2008-08-08 14:14:36 -04:00
|
|
|
|
2008-08-13 15:17:04 -04:00
|
|
|
M: #shuffle remove-dead-code*
|
2008-07-20 05:24:37 -04:00
|
|
|
[ filter-live ] change-in-d
|
|
|
|
[ filter-live ] change-out-d
|
2008-08-13 15:17:04 -04:00
|
|
|
dup in-d>> empty? [ drop f ] when ;
|
2008-07-20 05:24:37 -04:00
|
|
|
|
2008-08-13 15:17:04 -04:00
|
|
|
M: #copy remove-dead-code*
|
2008-07-24 00:50:21 -04:00
|
|
|
[ in-d>> ] [ out-d>> ] bi
|
2008-08-13 15:17:04 -04:00
|
|
|
2dup swap zip #shuffle
|
|
|
|
remove-dead-code* ;
|
|
|
|
|
|
|
|
: filter-corresponding-values ( in out -- in' out' )
|
|
|
|
zip live-values get '[ drop _ , key? ] assoc-filter unzip ;
|
2008-07-20 05:24:37 -04:00
|
|
|
|
|
|
|
: remove-dead-phi-d ( #phi -- #phi )
|
|
|
|
dup
|
2008-07-22 05:45:03 -04:00
|
|
|
[ phi-in-d>> ] [ out-d>> ] bi
|
2008-07-20 05:24:37 -04:00
|
|
|
filter-corresponding-values
|
2008-07-22 05:45:03 -04:00
|
|
|
[ >>phi-in-d ] [ >>out-d ] bi* ;
|
2008-07-20 05:24:37 -04:00
|
|
|
|
|
|
|
: remove-dead-phi-r ( #phi -- #phi )
|
|
|
|
dup
|
2008-07-22 05:45:03 -04:00
|
|
|
[ phi-in-r>> ] [ out-r>> ] bi
|
2008-07-20 05:24:37 -04:00
|
|
|
filter-corresponding-values
|
2008-07-22 05:45:03 -04:00
|
|
|
[ >>phi-in-r ] [ >>out-r ] bi* ;
|
2008-07-20 05:24:37 -04:00
|
|
|
|
2008-08-13 15:17:04 -04:00
|
|
|
M: #phi remove-dead-code*
|
2008-07-20 05:24:37 -04:00
|
|
|
remove-dead-phi-d
|
2008-08-13 15:17:04 -04:00
|
|
|
remove-dead-phi-r ;
|
2008-07-24 00:50:21 -04:00
|
|
|
|
2008-08-13 15:17:04 -04:00
|
|
|
M: node remove-dead-code* ;
|
2008-07-20 05:24:37 -04:00
|
|
|
|
|
|
|
: remove-dead-code ( node -- newnode )
|
2008-08-13 15:17:04 -04:00
|
|
|
[ [ mark-live-values ] backward-dfa live-values set ]
|
|
|
|
[ [ remove-dead-code* ] map-nodes ]
|
|
|
|
bi ;
|