| 
									
										
										
										
											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. | 
					
						
							| 
									
										
										
										
											2008-12-06 12:17:19 -05:00
										 |  |  | USING: kernel accessors sequences combinators fry | 
					
						
							| 
									
										
										
										
											2008-08-28 23:28:34 -04:00
										 |  |  | classes.algebra namespaces assocs words math math.private | 
					
						
							| 
									
										
										
										
											2008-08-29 01:26:47 -04:00
										 |  |  | math.partial-dispatch math.intervals classes classes.tuple | 
					
						
							| 
									
										
										
										
											2009-11-08 21:34:46 -05:00
										 |  |  | classes.tuple.private layouts definitions stack-checker.dependencies | 
					
						
							| 
									
										
										
										
											2008-09-02 23:59:49 -04:00
										 |  |  | stack-checker.branches | 
					
						
							| 
									
										
										
										
											2008-12-06 12:17:19 -05:00
										 |  |  | compiler.utilities | 
					
						
							| 
									
										
										
										
											2008-09-02 23:59:49 -04:00
										 |  |  | compiler.tree | 
					
						
							| 
									
										
										
										
											2008-07-30 04:38:10 -04:00
										 |  |  | compiler.tree.combinators | 
					
						
							|  |  |  | compiler.tree.propagation.info | 
					
						
							|  |  |  | compiler.tree.propagation.branches ;
 | 
					
						
							| 
									
										
										
										
											2008-07-27 21:25:42 -04:00
										 |  |  | IN: compiler.tree.cleanup | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-30 04:38:10 -04:00
										 |  |  | ! A phase run after propagation to finish the job, so to speak. | 
					
						
							|  |  |  | ! Codifies speculative inlining decisions, deletes branches | 
					
						
							|  |  |  | ! marked as never taken, and flattens local recursive blocks | 
					
						
							| 
									
										
										
										
											2008-08-19 18:11:33 -04:00
										 |  |  | ! that do not call themselves. | 
					
						
							| 
									
										
										
										
											2008-08-15 00:35:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | GENERIC: delete-node ( node -- )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: #call-recursive delete-node | 
					
						
							| 
									
										
										
										
											2009-10-28 01:44:05 -04:00
										 |  |  |     dup label>> calls>> [ node>> eq? not ] with filter! 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
										 |  |  | 
 | 
					
						
							|  |  |  | GENERIC: cleanup* ( node -- node/nodes )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : cleanup ( nodes -- nodes' )
 | 
					
						
							|  |  |  |     #! We don't recurse into children here, instead the methods | 
					
						
							|  |  |  |     #! do it since the logic is a bit more involved | 
					
						
							| 
									
										
										
										
											2008-12-06 12:17:19 -05:00
										 |  |  |     [ cleanup* ] 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 16:37:40 -04:00
										 |  |  |     #! Replace a #call having a known result with a #drop of its | 
					
						
							|  |  |  |     #! inputs followed by #push nodes for the outputs. | 
					
						
							| 
									
										
										
										
											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 )
 | 
					
						
							| 
									
										
										
										
											2010-01-29 03:40:09 -05:00
										 |  |  |     [ record-inlining ] [ body>> cleanup ] 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
										 |  |  |     { | 
					
						
							|  |  |  |         { [ dup word>> \ fixnum-shift eq? ] [ [ (remove-overflow-check?) ] [ small-shift? ] bi and ] } | 
					
						
							|  |  |  |         { [ dup word>> no-overflow-variant ] [ (remove-overflow-check?) ] } | 
					
						
							|  |  |  |         [ drop f ] | 
					
						
							|  |  |  |     } cond ;
 | 
					
						
							| 
									
										
										
										
											2008-07-30 16:37:40 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : remove-overflow-check ( #call -- #call )
 | 
					
						
							| 
									
										
										
										
											2008-11-03 01:03:15 -05:00
										 |  |  |     [ no-overflow-variant ] change-word cleanup* ;
 | 
					
						
							| 
									
										
										
										
											2008-07-30 16:37:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-30 04:38:10 -04:00
										 |  |  | M: #call cleanup* | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         { [ 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 )
 | 
					
						
							|  |  |  |     #! If only one branch is live we don't need to branch at | 
					
						
							|  |  |  |     #! all; just drop the condition value. | 
					
						
							| 
									
										
										
										
											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 -- )
 | 
					
						
							|  |  |  |     [ [ cleanup ] map ] change-children drop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: #branch cleanup* | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         [ 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 ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-30 04:38:10 -04:00
										 |  |  | M: #phi cleanup* | 
					
						
							|  |  |  |     #! 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 )
 | 
					
						
							|  |  |  |     #! convert #enter-recursive and #return-recursive into | 
					
						
							|  |  |  |     #! #copy nodes. | 
					
						
							|  |  |  |     child>> | 
					
						
							|  |  |  |     unclip >copy prefix
 | 
					
						
							|  |  |  |     unclip-last >copy suffix ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: #recursive cleanup* | 
					
						
							|  |  |  |     #! Inline bodies of #recursive blocks with no calls left. | 
					
						
							|  |  |  |     [ cleanup ] change-child | 
					
						
							|  |  |  |     dup label>> calls>> empty? [ flatten-recursive ] when ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-28 00:49:26 -04:00
										 |  |  | M: #alien-callback cleanup* | 
					
						
							|  |  |  |     [ cleanup ] change-child ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-30 04:38:10 -04:00
										 |  |  | M: node cleanup* ;
 |