2009-08-09 17:29:21 -04:00
|
|
|
! Copyright (C) 2008, 2009 Slava Pestov.
|
2008-08-07 07:34:28 -04:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2009-08-09 17:29:21 -04:00
|
|
|
USING: namespaces assocs accessors kernel kernel.private combinators
|
2008-12-06 12:17:19 -05:00
|
|
|
classes.algebra sequences slots.private fry vectors
|
2008-08-08 14:14:36 -04:00
|
|
|
classes.tuple.private math math.private arrays
|
2009-08-09 17:29:21 -04:00
|
|
|
stack-checker.branches stack-checker.values
|
2008-12-06 12:17:19 -05:00
|
|
|
compiler.utilities
|
2008-08-08 14:14:36 -04:00
|
|
|
compiler.tree
|
2009-08-09 17:29:21 -04:00
|
|
|
compiler.tree.builder
|
|
|
|
compiler.tree.cleanup
|
2008-08-08 14:14:36 -04:00
|
|
|
compiler.tree.combinators
|
2009-08-09 17:29:21 -04:00
|
|
|
compiler.tree.propagation
|
2008-08-22 16:30:57 -04:00
|
|
|
compiler.tree.propagation.info
|
2008-08-08 14:14:36 -04:00
|
|
|
compiler.tree.escape-analysis.simple
|
|
|
|
compiler.tree.escape-analysis.allocations ;
|
2008-08-07 07:34:28 -04:00
|
|
|
IN: compiler.tree.tuple-unboxing
|
|
|
|
|
|
|
|
! This pass must run after escape analysis
|
|
|
|
|
2008-08-08 14:14:36 -04:00
|
|
|
GENERIC: unbox-tuples* ( node -- node/nodes )
|
2008-08-07 07:34:28 -04:00
|
|
|
|
2008-08-08 14:14:36 -04:00
|
|
|
: unbox-output? ( node -- values )
|
2008-08-07 07:34:28 -04:00
|
|
|
out-d>> first unboxed-allocation ;
|
|
|
|
|
2008-08-08 14:14:36 -04:00
|
|
|
: (expand-#push) ( object value -- nodes )
|
|
|
|
dup unboxed-allocation dup [
|
|
|
|
[ object-slots ] [ drop ] [ ] tri*
|
2008-12-06 12:17:19 -05:00
|
|
|
[ (expand-#push) ] 2map-flat
|
2008-08-08 14:14:36 -04:00
|
|
|
] [
|
2011-11-06 23:41:31 -05:00
|
|
|
drop <#push>
|
2008-08-08 14:14:36 -04:00
|
|
|
] if ;
|
2008-08-07 07:34:28 -04:00
|
|
|
|
2008-08-08 14:14:36 -04:00
|
|
|
: expand-#push ( #push -- nodes )
|
|
|
|
[ literal>> ] [ out-d>> first ] bi (expand-#push) ;
|
2008-08-07 07:34:28 -04:00
|
|
|
|
2008-08-08 14:14:36 -04:00
|
|
|
M: #push unbox-tuples* ( #push -- nodes )
|
|
|
|
dup unbox-output? [ expand-#push ] when ;
|
2008-08-07 07:34:28 -04:00
|
|
|
|
2008-08-08 14:14:36 -04:00
|
|
|
: unbox-<tuple-boa> ( #call -- nodes )
|
2011-11-06 23:41:31 -05:00
|
|
|
dup unbox-output? [ in-d>> 1 tail* <#drop> ] when ;
|
2008-08-07 07:34:28 -04:00
|
|
|
|
2008-12-06 12:17:19 -05:00
|
|
|
: (flatten-values) ( values accum -- )
|
|
|
|
dup '[
|
|
|
|
dup unboxed-allocation
|
|
|
|
[ _ (flatten-values) ] [ _ push ] ?if
|
|
|
|
] each ;
|
2008-08-07 07:34:28 -04:00
|
|
|
|
|
|
|
: flatten-values ( values -- values' )
|
2008-12-06 12:17:19 -05:00
|
|
|
dup empty? [
|
|
|
|
10 <vector> [ (flatten-values) ] keep
|
|
|
|
] unless ;
|
2008-08-07 07:34:28 -04:00
|
|
|
|
2008-08-08 14:14:36 -04:00
|
|
|
: prepare-slot-access ( #call -- tuple-values outputs slot-values )
|
2008-08-10 00:00:27 -04:00
|
|
|
[ in-d>> flatten-values ]
|
2008-08-07 07:34:28 -04:00
|
|
|
[ out-d>> flatten-values ]
|
2008-08-08 14:14:36 -04:00
|
|
|
[
|
|
|
|
out-d>> first slot-accesses get at
|
2008-08-10 00:00:27 -04:00
|
|
|
[ slot#>> ] [ value>> ] bi allocation nth
|
|
|
|
1array flatten-values
|
2008-08-08 14:14:36 -04:00
|
|
|
] tri ;
|
2008-08-07 07:34:28 -04:00
|
|
|
|
2008-08-08 14:14:36 -04:00
|
|
|
: slot-access-shuffle ( tuple-values outputs slot-values -- #shuffle )
|
2011-11-06 23:41:31 -05:00
|
|
|
[ drop ] [ zip ] 2bi <#data-shuffle> ;
|
2008-08-07 07:34:28 -04:00
|
|
|
|
2008-08-08 14:14:36 -04:00
|
|
|
: unbox-slot-access ( #call -- nodes )
|
|
|
|
dup out-d>> first unboxed-slot-access? [
|
2008-08-22 16:30:57 -04:00
|
|
|
prepare-slot-access slot-access-shuffle
|
2008-08-08 14:14:36 -04:00
|
|
|
] when ;
|
2008-08-07 07:34:28 -04:00
|
|
|
|
2008-08-08 14:14:36 -04:00
|
|
|
M: #call unbox-tuples*
|
2008-08-07 07:34:28 -04:00
|
|
|
dup word>> {
|
2008-08-22 16:30:57 -04:00
|
|
|
{ \ <tuple-boa> [ unbox-<tuple-boa> ] }
|
2008-08-07 07:34:28 -04:00
|
|
|
{ \ slot [ unbox-slot-access ] }
|
2008-08-08 14:14:36 -04:00
|
|
|
[ drop ]
|
2008-08-07 07:34:28 -04:00
|
|
|
} case ;
|
|
|
|
|
2008-08-08 17:04:33 -04:00
|
|
|
M: #declare unbox-tuples*
|
2009-08-09 17:29:21 -04:00
|
|
|
#! We don't look at declarations after escape analysis anyway.
|
|
|
|
drop f ;
|
2008-08-08 17:04:33 -04:00
|
|
|
|
2008-08-08 14:14:36 -04:00
|
|
|
M: #copy unbox-tuples*
|
|
|
|
[ flatten-values ] change-in-d
|
|
|
|
[ flatten-values ] change-out-d ;
|
2008-08-07 07:34:28 -04:00
|
|
|
|
2008-08-08 14:14:36 -04:00
|
|
|
M: #shuffle unbox-tuples*
|
|
|
|
[ flatten-values ] change-in-d
|
|
|
|
[ flatten-values ] change-out-d
|
2008-11-11 19:46:31 -05:00
|
|
|
[ flatten-values ] change-in-r
|
|
|
|
[ flatten-values ] change-out-r
|
2008-08-08 14:14:36 -04:00
|
|
|
[ unzip [ flatten-values ] bi@ zip ] change-mapping ;
|
2008-08-07 07:34:28 -04:00
|
|
|
|
2008-08-08 14:14:36 -04:00
|
|
|
M: #terminate unbox-tuples*
|
2008-08-15 00:35:19 -04:00
|
|
|
[ flatten-values ] change-in-d
|
|
|
|
[ flatten-values ] change-in-r ;
|
2008-08-07 07:34:28 -04:00
|
|
|
|
2008-08-08 17:04:33 -04:00
|
|
|
M: #phi unbox-tuples*
|
2009-05-23 16:50:35 -04:00
|
|
|
! pad-with-bottom is only needed if some branches are terminated,
|
|
|
|
! which means all output values are bottom
|
2008-08-14 00:52:49 -04:00
|
|
|
[ [ flatten-values ] map pad-with-bottom ] change-phi-in-d
|
2008-08-18 21:49:03 -04:00
|
|
|
[ flatten-values ] change-out-d ;
|
2008-08-08 17:04:33 -04:00
|
|
|
|
|
|
|
M: #recursive unbox-tuples*
|
2008-08-22 04:12:15 -04:00
|
|
|
[ label>> [ flatten-values ] change-enter-out drop ]
|
|
|
|
[ [ flatten-values ] change-in-d ]
|
|
|
|
bi ;
|
2008-08-08 17:04:33 -04:00
|
|
|
|
|
|
|
M: #enter-recursive unbox-tuples*
|
|
|
|
[ flatten-values ] change-in-d
|
|
|
|
[ flatten-values ] change-out-d ;
|
|
|
|
|
|
|
|
M: #call-recursive unbox-tuples*
|
|
|
|
[ flatten-values ] change-in-d
|
|
|
|
[ flatten-values ] change-out-d ;
|
|
|
|
|
|
|
|
M: #return-recursive unbox-tuples*
|
|
|
|
[ flatten-values ] change-in-d
|
|
|
|
[ flatten-values ] change-out-d ;
|
|
|
|
|
2009-08-09 17:29:21 -04:00
|
|
|
: value-declaration ( value -- quot )
|
|
|
|
value-class [ 1array '[ _ declare ] ] [ [ ] ] if* ;
|
|
|
|
|
|
|
|
: unbox-parameter-quot ( allocation -- quot )
|
|
|
|
dup unboxed-allocation {
|
|
|
|
{ [ dup not ] [ 2drop [ ] ] }
|
|
|
|
{ [ dup array? ] [
|
|
|
|
[ value-declaration ] [
|
|
|
|
[
|
|
|
|
[ unbox-parameter-quot ] [ 2 + '[ _ slot ] ] bi*
|
|
|
|
prepose
|
|
|
|
] map-index
|
|
|
|
] bi* '[ @ _ cleave ]
|
|
|
|
] }
|
|
|
|
} cond ;
|
|
|
|
|
|
|
|
: unbox-parameters-quot ( values -- quot )
|
|
|
|
[ unbox-parameter-quot ] map
|
|
|
|
dup [ [ ] = ] all? [ drop [ ] ] [ '[ _ spread ] ] if ;
|
|
|
|
|
|
|
|
: unbox-parameters-nodes ( new-values old-values -- nodes )
|
|
|
|
[ flatten-values ] [ unbox-parameters-quot ] bi build-sub-tree ;
|
|
|
|
|
|
|
|
: new-and-old-values ( values -- new-values old-values )
|
|
|
|
[ length [ <value> ] replicate ] keep ;
|
|
|
|
|
|
|
|
: unbox-hairy-introduce ( #introduce -- nodes )
|
|
|
|
dup out-d>> new-and-old-values
|
|
|
|
[ drop >>out-d ] [ unbox-parameters-nodes ] 2bi
|
|
|
|
swap prefix propagate ;
|
|
|
|
|
|
|
|
M: #introduce unbox-tuples*
|
|
|
|
! For every output that is unboxed, insert slot accessors
|
|
|
|
! to convert the stack value into its unboxed form
|
|
|
|
dup out-d>> [ unboxed-allocation ] any? [
|
|
|
|
unbox-hairy-introduce
|
|
|
|
] when ;
|
|
|
|
|
2008-08-07 07:34:28 -04:00
|
|
|
! These nodes never participate in unboxing
|
2008-08-08 17:04:33 -04:00
|
|
|
: assert-not-unboxed ( values -- )
|
|
|
|
dup array?
|
2009-01-29 23:19:07 -05:00
|
|
|
[ [ unboxed-allocation ] any? ] [ unboxed-allocation ] if
|
2008-08-08 17:04:33 -04:00
|
|
|
[ "Unboxing wrong value" throw ] when ;
|
|
|
|
|
|
|
|
M: #branch unbox-tuples* dup in-d>> assert-not-unboxed ;
|
|
|
|
|
|
|
|
M: #return unbox-tuples* dup in-d>> assert-not-unboxed ;
|
2008-08-07 07:34:28 -04:00
|
|
|
|
2010-01-06 22:06:07 -05:00
|
|
|
M: #alien-node unbox-tuples* dup in-d>> assert-not-unboxed ;
|
2008-08-12 03:41:18 -04:00
|
|
|
|
2008-08-18 16:47:49 -04:00
|
|
|
M: #alien-callback unbox-tuples* ;
|
|
|
|
|
2008-08-24 02:21:23 -04:00
|
|
|
: unbox-tuples ( nodes -- nodes )
|
2011-10-14 13:23:52 -04:00
|
|
|
(allocation) escaping-allocations get assoc-diff assoc-empty?
|
2008-08-24 02:21:23 -04:00
|
|
|
[ [ unbox-tuples* ] map-nodes ] unless ;
|