| 
									
										
										
										
											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
										 |  |  |     ] [ | 
					
						
							|  |  |  |         drop #push | 
					
						
							|  |  |  |     ] 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 )
 | 
					
						
							|  |  |  |     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 )
 | 
					
						
							| 
									
										
										
										
											2008-11-11 19:46: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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-12 03:41:18 -04:00
										 |  |  | M: #alien-invoke unbox-tuples* dup in-d>> assert-not-unboxed ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: #alien-indirect unbox-tuples* dup in-d>> assert-not-unboxed ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 )
 | 
					
						
							|  |  |  |     allocations get escaping-allocations get assoc-diff assoc-empty?
 | 
					
						
							|  |  |  |     [ [ unbox-tuples* ] map-nodes ] unless ;
 |