| 
									
										
										
										
											2009-03-16 21:11:36 -04:00
										 |  |  | ! Copyright (C) 2008, 2009 Slava Pestov. | 
					
						
							| 
									
										
										
										
											2008-07-27 21:25:42 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2009-03-16 21:11:36 -04:00
										 |  |  | USING: accessors kernel arrays sequences math math.order | 
					
						
							| 
									
										
										
										
											2009-04-24 21:43:01 -04:00
										 |  |  | math.partial-dispatch generic generic.standard generic.single generic.math | 
					
						
							| 
									
										
										
										
											2008-08-31 20:17:04 -04:00
										 |  |  | classes.algebra classes.union sets quotations assocs combinators | 
					
						
							| 
									
										
										
										
											2009-08-17 23:29:05 -04:00
										 |  |  | combinators.short-circuit words namespaces continuations classes | 
					
						
							|  |  |  | fry hints locals | 
					
						
							| 
									
										
										
										
											2008-07-30 04:38:10 -04:00
										 |  |  | compiler.tree | 
					
						
							|  |  |  | compiler.tree.builder | 
					
						
							| 
									
										
										
										
											2008-09-12 06:17:27 -04:00
										 |  |  | compiler.tree.recursive | 
					
						
							| 
									
										
										
										
											2008-09-12 09:18:44 -04:00
										 |  |  | compiler.tree.combinators | 
					
						
							| 
									
										
										
										
											2008-07-30 04:38:10 -04:00
										 |  |  | compiler.tree.normalization | 
					
						
							|  |  |  | compiler.tree.propagation.info | 
					
						
							|  |  |  | compiler.tree.propagation.nodes ;
 | 
					
						
							| 
									
										
										
										
											2008-07-27 21:25:42 -04:00
										 |  |  | IN: compiler.tree.propagation.inlining | 
					
						
							| 
									
										
										
										
											2008-07-30 04:38:10 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | ! Splicing nodes | 
					
						
							| 
									
										
										
										
											2009-04-22 00:02:00 -04:00
										 |  |  | : splicing-call ( #call word -- nodes )
 | 
					
						
							| 
									
										
										
										
											2011-11-06 23:41:31 -05:00
										 |  |  |     [ [ in-d>> ] [ out-d>> ] bi ] dip <#call> 1array ;
 | 
					
						
							| 
									
										
										
										
											2008-07-30 04:38:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-09 17:29:21 -04:00
										 |  |  | : open-code-#call ( #call word/quot -- nodes/f )
 | 
					
						
							|  |  |  |     [ [ in-d>> ] [ out-d>> ] bi ] dip build-sub-tree ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-22 00:02:00 -04:00
										 |  |  | : splicing-body ( #call quot/word -- nodes/f )
 | 
					
						
							| 
									
										
										
										
											2009-08-09 17:29:21 -04:00
										 |  |  |     open-code-#call dup [ analyze-recursive normalize ] when ;
 | 
					
						
							| 
									
										
										
										
											2008-07-30 04:38:10 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | ! Dispatch elimination | 
					
						
							| 
									
										
										
										
											2009-04-20 19:44:45 -04:00
										 |  |  | : undo-inlining ( #call -- ? )
 | 
					
						
							|  |  |  |     f >>method f >>body f >>class drop f ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : propagate-body ( #call -- ? )
 | 
					
						
							|  |  |  |     body>> (propagate) t ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-22 00:02:00 -04:00
										 |  |  | GENERIC: splicing-nodes ( #call word/quot -- nodes/f )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: word splicing-nodes splicing-call ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: callable splicing-nodes splicing-body ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-12 19:08:38 -04:00
										 |  |  | : eliminate-dispatch ( #call class/f word/quot/f -- ? )
 | 
					
						
							| 
									
										
										
										
											2008-08-30 03:31:27 -04:00
										 |  |  |     dup [ | 
					
						
							|  |  |  |         [ >>class ] dip
 | 
					
						
							| 
									
										
										
										
											2009-04-20 19:44:45 -04:00
										 |  |  |         over method>> over = [ drop propagate-body ] [ | 
					
						
							|  |  |  |             2dup splicing-nodes dup [ | 
					
						
							|  |  |  |                 [ >>method ] [ >>body ] bi* propagate-body | 
					
						
							|  |  |  |             ] [ 2drop undo-inlining ] if
 | 
					
						
							| 
									
										
										
										
											2008-07-30 04:38:10 -04:00
										 |  |  |         ] if
 | 
					
						
							| 
									
										
										
										
											2009-04-20 19:44:45 -04:00
										 |  |  |     ] [ 2drop undo-inlining ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-07-30 04:38:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-30 03:31:27 -04:00
										 |  |  | : inlining-standard-method ( #call word -- class/f method/f )
 | 
					
						
							| 
									
										
										
										
											2010-06-24 12:35:21 -04:00
										 |  |  |     dup "methods" word-prop assoc-empty? [ 2drop f f ] [ | 
					
						
							|  |  |  |         2dup [ in-d>> length ] [ dispatch# ] bi* <= [ 2drop f f ] [ | 
					
						
							|  |  |  |             [ in-d>> <reversed> ] [ [ dispatch# ] keep ] bi*
 | 
					
						
							|  |  |  |             [ swap nth value-info class>> dup ] dip
 | 
					
						
							|  |  |  |             method-for-class | 
					
						
							|  |  |  |         ] if
 | 
					
						
							| 
									
										
										
										
											2008-12-08 20:14:18 -05:00
										 |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-07-30 04:38:10 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : inline-standard-method ( #call word -- ? )
 | 
					
						
							|  |  |  |     dupd inlining-standard-method eliminate-dispatch ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : normalize-math-class ( class -- class' )
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         null
 | 
					
						
							|  |  |  |         fixnum bignum integer
 | 
					
						
							|  |  |  |         ratio rational
 | 
					
						
							|  |  |  |         float real
 | 
					
						
							|  |  |  |         complex number
 | 
					
						
							|  |  |  |         object
 | 
					
						
							|  |  |  |     } [ class<= ] with find nip ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-30 03:31:27 -04:00
										 |  |  | : inlining-math-method ( #call word -- class/f quot/f )
 | 
					
						
							| 
									
										
										
										
											2008-07-30 04:38:10 -04:00
										 |  |  |     swap in-d>> | 
					
						
							|  |  |  |     first2 [ value-info class>> normalize-math-class ] bi@
 | 
					
						
							| 
									
										
										
										
											2008-08-30 03:31:27 -04:00
										 |  |  |     3dup math-both-known? | 
					
						
							|  |  |  |     [ math-method* ] [ 3drop f ] if
 | 
					
						
							|  |  |  |     number swap ;
 | 
					
						
							| 
									
										
										
										
											2008-07-30 04:38:10 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : inline-math-method ( #call word -- ? )
 | 
					
						
							|  |  |  |     dupd inlining-math-method eliminate-dispatch ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ! Method body inlining | 
					
						
							|  |  |  | SYMBOL: history | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-28 16:02:00 -04:00
										 |  |  | : already-inlined? ( obj -- ? ) history get member-eq? ;
 | 
					
						
							| 
									
										
										
										
											2009-08-02 00:34:14 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : add-to-history ( obj -- ) history [ swap suffix ] change ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-21 17:09:53 -04:00
										 |  |  | :: inline-word ( #call word -- ? )
 | 
					
						
							| 
									
										
										
										
											2009-08-02 00:34:14 -04:00
										 |  |  |     word already-inlined? [ f ] [ | 
					
						
							| 
									
										
										
										
											2009-04-22 00:02:00 -04:00
										 |  |  |         #call word splicing-body [ | 
					
						
							| 
									
										
										
										
											2009-09-07 18:45:03 -04:00
										 |  |  |             word add-to-history | 
					
						
							| 
									
										
										
										
											2010-05-05 16:52:54 -04:00
										 |  |  |             #call body<< | 
					
						
							| 
									
										
										
										
											2009-09-07 18:45:03 -04:00
										 |  |  |             #call propagate-body | 
					
						
							| 
									
										
										
										
											2009-04-20 19:44:45 -04:00
										 |  |  |         ] [ f ] if*
 | 
					
						
							| 
									
										
										
										
											2008-07-30 04:38:10 -04:00
										 |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-02 00:31:43 -04:00
										 |  |  | : always-inline-word? ( word -- ? )
 | 
					
						
							| 
									
										
										
										
											2009-10-28 16:02:00 -04:00
										 |  |  |     { curry compose } member-eq? ;
 | 
					
						
							| 
									
										
										
										
											2008-08-31 20:17:04 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-01 21:12:35 -05:00
										 |  |  | : never-inline-word? ( word -- ? )
 | 
					
						
							| 
									
										
										
										
											2009-08-17 23:29:05 -04:00
										 |  |  |     { [ deferred? ] [ "default" word-prop ] [ \ call eq? ] } 1|| ;
 | 
					
						
							| 
									
										
										
										
											2009-03-01 21:12:35 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-12 19:08:38 -04:00
										 |  |  | : custom-inlining? ( word -- ? )
 | 
					
						
							|  |  |  |     "custom-inlining" word-prop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : inline-custom ( #call word -- ? )
 | 
					
						
							| 
									
										
										
										
											2011-10-14 13:23:52 -04:00
										 |  |  |     [ dup ] [ custom-inlining? ] bi*
 | 
					
						
							| 
									
										
										
										
											2009-02-08 23:12:11 -05:00
										 |  |  |     call( #call -- word/quot/f ) | 
					
						
							|  |  |  |     object swap eliminate-dispatch ;
 | 
					
						
							| 
									
										
										
										
											2008-09-12 19:08:38 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-06 12:17:19 -05:00
										 |  |  | : (do-inlining) ( #call word -- ? )
 | 
					
						
							| 
									
										
										
										
											2008-11-03 21:59:48 -05:00
										 |  |  |     #! If the generic was defined in an outer compilation unit, | 
					
						
							|  |  |  |     #! then it doesn't have a definition yet; the definition | 
					
						
							|  |  |  |     #! is built at the end of the compilation unit. We do not | 
					
						
							|  |  |  |     #! attempt inlining at this stage since the stack discipline | 
					
						
							|  |  |  |     #! is not finalized yet, so dispatch# might return an out | 
					
						
							|  |  |  |     #! of bounds value. This case comes up if a parsing word | 
					
						
							|  |  |  |     #! calls the compiler at parse time (doing so is | 
					
						
							|  |  |  |     #! discouraged, but it should still work.) | 
					
						
							| 
									
										
										
										
											2008-12-06 12:17:19 -05:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-03-01 21:12:35 -05:00
										 |  |  |         { [ dup never-inline-word? ] [ 2drop f ] } | 
					
						
							| 
									
										
										
										
											2008-12-06 12:17:19 -05:00
										 |  |  |         { [ dup always-inline-word? ] [ inline-word ] } | 
					
						
							|  |  |  |         { [ dup standard-generic? ] [ inline-standard-method ] } | 
					
						
							|  |  |  |         { [ dup math-generic? ] [ inline-math-method ] } | 
					
						
							| 
									
										
										
										
											2009-08-17 23:29:05 -04:00
										 |  |  |         { [ dup inline? ] [ inline-word ] } | 
					
						
							| 
									
										
										
										
											2008-12-06 12:17:19 -05:00
										 |  |  |         [ 2drop f ] | 
					
						
							|  |  |  |     } cond ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : do-inlining ( #call word -- ? )
 | 
					
						
							|  |  |  |     #! Note the logic here: if there's a custom inlining hook, | 
					
						
							|  |  |  |     #! it is permitted to return f, which means that we try the | 
					
						
							|  |  |  |     #! normal inlining heuristic. | 
					
						
							| 
									
										
										
										
											2009-09-07 18:45:03 -04:00
										 |  |  |     [ | 
					
						
							|  |  |  |         dup custom-inlining? [ 2dup inline-custom ] [ f ] if
 | 
					
						
							|  |  |  |         [ 2drop t ] [ (do-inlining) ] if
 | 
					
						
							|  |  |  |     ] with-scope ;
 |