2010-01-29 03:40:09 -05:00
|
|
|
! Copyright (C) 2008, 2010 Slava Pestov.
|
2008-07-27 21:25:42 -04:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2016-03-18 11:28:01 -04:00
|
|
|
USING: accessors classes classes.algebra combinators compiler.tree
|
|
|
|
compiler.tree.combinators compiler.tree.propagation.branches
|
|
|
|
compiler.tree.propagation.info compiler.utilities fry kernel layouts
|
|
|
|
math math.intervals math.partial-dispatch math.private namespaces
|
|
|
|
sequences stack-checker.branches stack-checker.dependencies words ;
|
2008-07-27 21:25:42 -04:00
|
|
|
IN: compiler.tree.cleanup
|
|
|
|
|
2008-08-15 00:35:19 -04:00
|
|
|
GENERIC: delete-node ( node -- )
|
|
|
|
|
|
|
|
M: #call-recursive delete-node
|
2015-05-12 21:50:34 -04:00
|
|
|
dup label>> calls>> [ node>> eq? ] with reject! drop ;
|
2008-08-15 00:35:19 -04:00
|
|
|
|
|
|
|
M: #return-recursive delete-node
|
|
|
|
label>> f >>return drop ;
|
|
|
|
|
|
|
|
M: node delete-node drop ;
|
|
|
|
|
|
|
|
: delete-nodes ( nodes -- ) [ delete-node ] each-node ;
|
2008-07-30 04:38:10 -04:00
|
|
|
|
2015-06-06 00:08:18 -04:00
|
|
|
GENERIC: cleanup-tree* ( node -- node/nodes )
|
2008-07-30 04:38:10 -04:00
|
|
|
|
2015-06-06 00:08:18 -04:00
|
|
|
: cleanup-tree ( nodes -- nodes' )
|
|
|
|
[ cleanup-tree* ] map-flat ;
|
2008-07-30 04:38:10 -04:00
|
|
|
|
2010-01-20 16:25:53 -05:00
|
|
|
! Constant folding
|
2008-07-30 16:37:40 -04:00
|
|
|
: cleanup-folding? ( #call -- ? )
|
2008-09-06 20:13:59 -04:00
|
|
|
node-output-infos
|
|
|
|
[ f ] [ [ literal?>> ] all? ] if-empty ;
|
2008-07-30 16:37:40 -04:00
|
|
|
|
2010-01-20 16:25:53 -05:00
|
|
|
: (cleanup-folding) ( #call -- nodes )
|
2008-07-30 04:38:10 -04:00
|
|
|
[
|
|
|
|
[ node-output-infos ] [ out-d>> ] bi
|
2011-11-06 23:41:31 -05:00
|
|
|
[ [ literal>> ] dip <#push> ] 2map
|
2008-07-30 04:38:10 -04:00
|
|
|
]
|
2011-11-06 23:41:31 -05:00
|
|
|
[ in-d>> <#drop> ]
|
2010-01-20 16:25:53 -05:00
|
|
|
bi prefix ;
|
|
|
|
|
2010-02-19 18:01:47 -05:00
|
|
|
: >predicate-folding< ( #call -- value-info class result )
|
|
|
|
[ node-input-infos first ]
|
2010-01-29 03:40:09 -05:00
|
|
|
[ word>> "predicating" word-prop ]
|
2010-02-19 18:01:47 -05:00
|
|
|
[ node-output-infos first literal>> ] tri ;
|
|
|
|
|
|
|
|
: record-predicate-folding ( #call -- )
|
|
|
|
>predicate-folding< pick literal?>>
|
2012-06-21 02:55:24 -04:00
|
|
|
[ [ literal>> ] 2dip add-depends-on-instance-predicate ]
|
|
|
|
[ [ class>> ] 2dip add-depends-on-class-predicate ]
|
2010-02-19 18:01:47 -05:00
|
|
|
if ;
|
2010-01-29 03:40:09 -05:00
|
|
|
|
2010-01-20 16:25:53 -05:00
|
|
|
: record-folding ( #call -- )
|
|
|
|
dup word>> predicate?
|
2010-01-29 03:40:09 -05:00
|
|
|
[ record-predicate-folding ]
|
2012-06-21 02:55:24 -04:00
|
|
|
[ word>> add-depends-on-definition ]
|
2010-01-20 16:25:53 -05:00
|
|
|
if ;
|
|
|
|
|
|
|
|
: cleanup-folding ( #call -- nodes )
|
|
|
|
[ (cleanup-folding) ] [ record-folding ] bi ;
|
2008-07-30 04:38:10 -04:00
|
|
|
|
2010-01-20 16:25:53 -05:00
|
|
|
! Method inlining
|
2008-08-30 03:31:27 -04:00
|
|
|
: add-method-dependency ( #call -- )
|
|
|
|
dup method>> word? [
|
2012-06-21 02:55:24 -04:00
|
|
|
[ [ class>> ] [ word>> ] bi add-depends-on-generic ]
|
|
|
|
[ [ class>> ] [ word>> ] [ method>> ] tri add-depends-on-method ]
|
2010-01-29 03:40:09 -05:00
|
|
|
bi
|
2008-08-30 03:31:27 -04:00
|
|
|
] [ drop ] if ;
|
|
|
|
|
2010-01-29 03:40:09 -05:00
|
|
|
: record-inlining ( #call -- )
|
|
|
|
dup method>>
|
|
|
|
[ add-method-dependency ]
|
2012-06-21 02:55:24 -04:00
|
|
|
[ word>> add-depends-on-definition ] if ;
|
2010-01-29 03:40:09 -05:00
|
|
|
|
2008-07-30 04:38:10 -04:00
|
|
|
: cleanup-inlining ( #call -- nodes )
|
2015-06-06 00:08:18 -04:00
|
|
|
[ record-inlining ] [ body>> cleanup-tree ] bi ;
|
2008-07-30 04:38:10 -04:00
|
|
|
|
2008-07-30 16:37:40 -04:00
|
|
|
! Removing overflow checks
|
2008-08-29 01:26:47 -04:00
|
|
|
: (remove-overflow-check?) ( #call -- ? )
|
|
|
|
node-output-infos first class>> fixnum class<= ;
|
|
|
|
|
|
|
|
: small-shift? ( #call -- ? )
|
|
|
|
node-input-infos second interval>>
|
2008-08-29 05:23:39 -04:00
|
|
|
cell-bits tag-bits get - [ neg ] keep [a,b] interval-subset? ;
|
2008-08-29 01:26:47 -04:00
|
|
|
|
2008-07-30 16:37:40 -04:00
|
|
|
: remove-overflow-check? ( #call -- ? )
|
2008-08-29 01:26:47 -04:00
|
|
|
{
|
2016-03-18 11:28:01 -04:00
|
|
|
{
|
|
|
|
[ dup word>> \ fixnum-shift eq? ]
|
|
|
|
[ [ (remove-overflow-check?) ] [ small-shift? ] bi and ]
|
|
|
|
}
|
2008-08-29 01:26:47 -04:00
|
|
|
{ [ dup word>> no-overflow-variant ] [ (remove-overflow-check?) ] }
|
|
|
|
[ drop f ]
|
|
|
|
} cond ;
|
2008-07-30 16:37:40 -04:00
|
|
|
|
|
|
|
: remove-overflow-check ( #call -- #call )
|
2015-06-06 00:08:18 -04:00
|
|
|
[ no-overflow-variant ] change-word cleanup-tree* ;
|
2008-07-30 16:37:40 -04:00
|
|
|
|
2015-06-06 00:08:18 -04:00
|
|
|
M: #call cleanup-tree*
|
2008-07-30 04:38:10 -04:00
|
|
|
{
|
|
|
|
{ [ dup body>> ] [ cleanup-inlining ] }
|
2008-07-30 16:37:40 -04:00
|
|
|
{ [ dup cleanup-folding? ] [ cleanup-folding ] }
|
|
|
|
{ [ dup remove-overflow-check? ] [ remove-overflow-check ] }
|
2008-07-30 04:38:10 -04:00
|
|
|
[ ]
|
|
|
|
} cond ;
|
|
|
|
|
|
|
|
: delete-unreachable-branches ( #branch -- )
|
|
|
|
dup live-branches>> '[
|
2008-09-10 23:11:40 -04:00
|
|
|
_
|
2008-07-30 04:38:10 -04:00
|
|
|
[ [ [ drop ] [ delete-nodes ] if ] 2each ]
|
|
|
|
[ select-children ]
|
|
|
|
2bi
|
|
|
|
] change-children drop ;
|
|
|
|
|
|
|
|
: fold-only-branch ( #branch -- node/nodes )
|
2008-08-29 05:40:53 -04:00
|
|
|
dup live-children sift dup length {
|
2011-11-06 23:41:31 -05:00
|
|
|
{ 0 [ drop in-d>> <#drop> ] }
|
|
|
|
{ 1 [ first swap in-d>> <#drop> prefix ] }
|
2008-08-29 05:40:53 -04:00
|
|
|
[ 2drop ]
|
|
|
|
} case ;
|
2008-07-30 04:38:10 -04:00
|
|
|
|
|
|
|
SYMBOL: live-branches
|
|
|
|
|
|
|
|
: cleanup-children ( #branch -- )
|
2015-06-06 00:08:18 -04:00
|
|
|
[ [ cleanup-tree ] map ] change-children drop ;
|
2008-07-30 04:38:10 -04:00
|
|
|
|
2015-06-06 00:08:18 -04:00
|
|
|
M: #branch cleanup-tree*
|
2008-07-30 04:38:10 -04:00
|
|
|
{
|
|
|
|
[ delete-unreachable-branches ]
|
|
|
|
[ cleanup-children ]
|
|
|
|
[ fold-only-branch ]
|
2008-08-10 00:00:27 -04:00
|
|
|
[ live-branches>> live-branches set ]
|
2008-07-30 04:38:10 -04:00
|
|
|
} cleave ;
|
|
|
|
|
2008-08-29 05:40:53 -04:00
|
|
|
: output-fs ( values -- nodes )
|
2011-11-06 23:41:31 -05:00
|
|
|
[ f swap <#push> ] map ;
|
2008-08-29 05:40:53 -04:00
|
|
|
|
2008-08-19 18:11:33 -04:00
|
|
|
: eliminate-single-phi ( #phi -- node )
|
|
|
|
[ phi-in-d>> first ] [ out-d>> ] bi over [ +bottom+ eq? ] all?
|
2008-08-29 05:40:53 -04:00
|
|
|
[ [ drop ] [ output-fs ] bi* ]
|
2011-11-06 23:41:31 -05:00
|
|
|
[ <#copy> ]
|
2008-08-19 18:11:33 -04:00
|
|
|
if ;
|
|
|
|
|
2008-08-18 22:30:10 -04:00
|
|
|
: eliminate-phi ( #phi -- node )
|
2008-08-19 22:48:08 -04:00
|
|
|
live-branches get sift length {
|
2008-08-29 05:40:53 -04:00
|
|
|
{ 0 [ out-d>> output-fs ] }
|
2008-08-19 18:11:33 -04:00
|
|
|
{ 1 [ eliminate-single-phi ] }
|
2008-08-18 22:30:10 -04:00
|
|
|
[ drop ]
|
|
|
|
} case ;
|
|
|
|
|
2015-06-06 00:08:18 -04:00
|
|
|
M: #phi cleanup-tree*
|
2015-09-08 19:15:10 -04:00
|
|
|
! Remove #phi function inputs which no longer exist.
|
2008-08-18 21:49:03 -04:00
|
|
|
live-branches get
|
2008-09-10 23:11:40 -04:00
|
|
|
[ '[ _ sift-children ] change-phi-in-d ]
|
|
|
|
[ '[ _ sift-children ] change-phi-info-d ]
|
|
|
|
[ '[ _ sift-children ] change-terminated ] tri
|
2008-08-18 22:30:10 -04:00
|
|
|
eliminate-phi
|
2008-08-10 00:00:27 -04:00
|
|
|
live-branches off ;
|
2008-07-30 04:38:10 -04:00
|
|
|
|
2011-11-06 23:41:31 -05:00
|
|
|
: >copy ( node -- #copy ) [ in-d>> ] [ out-d>> ] bi <#copy> ;
|
2008-07-30 04:38:10 -04:00
|
|
|
|
|
|
|
: flatten-recursive ( #recursive -- nodes )
|
|
|
|
child>>
|
|
|
|
unclip >copy prefix
|
|
|
|
unclip-last >copy suffix ;
|
|
|
|
|
2015-06-06 00:08:18 -04:00
|
|
|
M: #recursive cleanup-tree*
|
2015-09-08 19:15:10 -04:00
|
|
|
! Inline bodies of #recursive blocks with no calls left.
|
2015-06-06 00:08:18 -04:00
|
|
|
[ cleanup-tree ] change-child
|
2008-07-30 04:38:10 -04:00
|
|
|
dup label>> calls>> empty? [ flatten-recursive ] when ;
|
|
|
|
|
2015-06-06 00:08:18 -04:00
|
|
|
M: #alien-callback cleanup-tree*
|
|
|
|
[ cleanup-tree ] change-child ;
|
2010-07-28 00:49:26 -04:00
|
|
|
|
2015-06-06 00:08:18 -04:00
|
|
|
M: node cleanup-tree* ;
|