| 
									
										
										
										
											2010-05-02 18:48:41 -04:00
										 |  |  | ! Copyright (C) 2009, 2010 Slava Pestov. | 
					
						
							| 
									
										
										
										
											2008-09-11 03:05:22 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2010-05-02 18:48:41 -04:00
										 |  |  | USING: accessors arrays assocs deques dlists hashtables kernel | 
					
						
							|  |  |  | make sorting namespaces sequences combinators | 
					
						
							|  |  |  | combinators.short-circuit fry math compiler.cfg.rpo | 
					
						
							|  |  |  | compiler.cfg.utilities compiler.cfg.loop-detection | 
					
						
							|  |  |  | compiler.cfg.predecessors sets hash-sets ;
 | 
					
						
							|  |  |  | FROM: namespaces => set ;
 | 
					
						
							| 
									
										
										
										
											2008-09-11 03:05:22 -04:00
										 |  |  | IN: compiler.cfg.linearization | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-02 18:48:41 -04:00
										 |  |  | ! This is RPO except loops are rotated and unlikely blocks go | 
					
						
							|  |  |  | ! at the end. Based on SBCL's src/compiler/control.lisp | 
					
						
							| 
									
										
										
										
											2009-07-22 07:05:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-02 18:48:41 -04:00
										 |  |  | <PRIVATE
 | 
					
						
							| 
									
										
										
										
											2010-04-22 04:21:23 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-02 18:48:41 -04:00
										 |  |  | SYMBOLS: work-list loop-heads visited ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : visited? ( bb -- ? ) visited get in? ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : add-to-work-list ( bb -- )
 | 
					
						
							|  |  |  |     dup visited? [ drop ] [ | 
					
						
							|  |  |  |         work-list get push-back | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : init-linearization-order ( cfg -- )
 | 
					
						
							|  |  |  |     <dlist> work-list set
 | 
					
						
							|  |  |  |     HS{ } clone visited set
 | 
					
						
							|  |  |  |     entry>> add-to-work-list ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : (find-alternate-loop-head) ( bb -- bb' )
 | 
					
						
							|  |  |  |     dup { | 
					
						
							|  |  |  |         [ predecessor visited? not ] | 
					
						
							|  |  |  |         [ predecessors>> length 1 = ] | 
					
						
							|  |  |  |         [ predecessor successors>> length 1 = ] | 
					
						
							|  |  |  |         [ [ number>> ] [ predecessor number>> ] bi > ] | 
					
						
							|  |  |  |     } 1&& [ predecessor (find-alternate-loop-head) ] when ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : find-back-edge ( bb -- pred )
 | 
					
						
							|  |  |  |     [ predecessors>> ] keep '[ _ back-edge? ] find nip ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : find-alternate-loop-head ( bb -- bb' )
 | 
					
						
							|  |  |  |     dup find-back-edge dup visited? [ drop ] [ | 
					
						
							|  |  |  |         nip (find-alternate-loop-head) | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : predecessors-ready? ( bb -- ? )
 | 
					
						
							|  |  |  |     [ predecessors>> ] keep '[ | 
					
						
							|  |  |  |         _ 2dup back-edge? | 
					
						
							|  |  |  |         [ 2drop t ] [ drop visited? ] if
 | 
					
						
							|  |  |  |     ] all? ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : process-successor ( bb -- )
 | 
					
						
							|  |  |  |     dup predecessors-ready? [ | 
					
						
							|  |  |  |         dup loop-entry? [ find-alternate-loop-head ] when
 | 
					
						
							|  |  |  |         add-to-work-list | 
					
						
							|  |  |  |     ] [ drop ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : sorted-successors ( bb -- seq )
 | 
					
						
							|  |  |  |     successors>> <reversed> [ loop-nesting-at ] sort-with ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : process-block ( bb -- )
 | 
					
						
							|  |  |  |     dup visited? [ drop ] [ | 
					
						
							|  |  |  |         [ , ] | 
					
						
							|  |  |  |         [ visited get adjoin ] | 
					
						
							|  |  |  |         [ sorted-successors [ process-successor ] each ] | 
					
						
							|  |  |  |         tri
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : (linearization-order) ( cfg -- bbs )
 | 
					
						
							|  |  |  |     init-linearization-order | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [ work-list get [ process-block ] slurp-deque ] { } make | 
					
						
							| 
									
										
										
										
											2010-07-27 23:58:41 -04:00
										 |  |  |     ! [ unlikely?>> not ] partition append | 
					
						
							|  |  |  |     ;
 | 
					
						
							| 
									
										
										
										
											2010-04-22 04:21:23 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-02 18:48:41 -04:00
										 |  |  | PRIVATE>
 | 
					
						
							| 
									
										
										
										
											2009-07-16 19:29:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-02 18:48:41 -04:00
										 |  |  | : linearization-order ( cfg -- bbs )
 | 
					
						
							|  |  |  |     needs-post-order needs-loops needs-predecessors | 
					
						
							| 
									
										
										
										
											2010-04-27 10:51:00 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-02 18:48:41 -04:00
										 |  |  |     dup linear-order>> [ ] [ | 
					
						
							|  |  |  |         dup (linearization-order) | 
					
						
							|  |  |  |         >>linear-order linear-order>> | 
					
						
							|  |  |  |     ] ?if ;
 | 
					
						
							| 
									
										
										
										
											2008-09-11 03:05:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-02 18:48:41 -04:00
										 |  |  | SYMBOL: numbers | 
					
						
							| 
									
										
										
										
											2008-09-11 03:05:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-02 18:48:41 -04:00
										 |  |  | : block-number ( bb -- n ) numbers get at ;
 | 
					
						
							| 
									
										
										
										
											2010-04-27 10:51:00 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-02 18:48:41 -04:00
										 |  |  | : number-blocks ( bbs -- )
 | 
					
						
							|  |  |  |     [ 2array ] map-index >hashtable numbers set ;
 |