| 
									
										
										
										
											2008-09-15 03:59:24 -04:00
										 |  |  | ! Copyright (C) 2008 Slava Pestov. | 
					
						
							|  |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							|  |  |  | USING: accessors kernel math assocs namespaces sequences heaps | 
					
						
							| 
									
										
										
										
											2008-09-17 20:31:35 -04:00
										 |  |  | fry make combinators | 
					
						
							| 
									
										
										
										
											2008-10-07 21:00:38 -04:00
										 |  |  | cpu.architecture | 
					
						
							| 
									
										
										
										
											2008-10-20 02:56:28 -04:00
										 |  |  | compiler.cfg.def-use | 
					
						
							| 
									
										
										
										
											2008-09-15 03:59:24 -04:00
										 |  |  | compiler.cfg.registers | 
					
						
							|  |  |  | compiler.cfg.instructions | 
					
						
							|  |  |  | compiler.cfg.linear-scan.live-intervals ;
 | 
					
						
							| 
									
										
										
										
											2008-09-15 05:22:12 -04:00
										 |  |  | IN: compiler.cfg.linear-scan.assignment | 
					
						
							| 
									
										
										
										
											2008-09-15 03:59:24 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | ! A vector of live intervals. There is linear searching involved | 
					
						
							|  |  |  | ! but since we never have too many machine registers (around 30 | 
					
						
							|  |  |  | ! at most) and we probably won't have that many live at any one | 
					
						
							|  |  |  | ! time anyway, it is not a problem to check each element. | 
					
						
							|  |  |  | SYMBOL: active-intervals | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : add-active ( live-interval -- )
 | 
					
						
							|  |  |  |     active-intervals get push ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : lookup-register ( vreg -- reg )
 | 
					
						
							|  |  |  |     active-intervals get [ vreg>> = ] with find nip reg>> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ! Minheap of live intervals which still need a register allocation | 
					
						
							|  |  |  | SYMBOL: unhandled-intervals | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : add-unhandled ( live-interval -- )
 | 
					
						
							|  |  |  |     dup split-before>> [ | 
					
						
							|  |  |  |         [ split-before>> ] [ split-after>> ] bi
 | 
					
						
							|  |  |  |         [ add-unhandled ] bi@
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         dup start>> unhandled-intervals get heap-push | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : init-unhandled ( live-intervals -- )
 | 
					
						
							|  |  |  |     [ add-unhandled ] each ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : insert-spill ( live-interval -- )
 | 
					
						
							| 
									
										
										
										
											2008-10-19 02:10:21 -04:00
										 |  |  |     [ reg>> ] [ vreg>> reg-class>> ] [ spill-to>> ] tri
 | 
					
						
							|  |  |  |     dup [ _spill ] [ 3drop ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-09-15 03:59:24 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : expire-old-intervals ( n -- )
 | 
					
						
							|  |  |  |     active-intervals get
 | 
					
						
							|  |  |  |     swap '[ end>> _ = ] partition
 | 
					
						
							|  |  |  |     active-intervals set
 | 
					
						
							|  |  |  |     [ insert-spill ] each ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : insert-reload ( live-interval -- )
 | 
					
						
							| 
									
										
										
										
											2008-10-19 02:10:21 -04:00
										 |  |  |     [ reg>> ] [ vreg>> reg-class>> ] [ reload-from>> ] tri
 | 
					
						
							|  |  |  |     dup [ _reload ] [ 3drop ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-09-15 03:59:24 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : activate-new-intervals ( n -- )
 | 
					
						
							|  |  |  |     #! Any live intervals which start on the current instruction | 
					
						
							|  |  |  |     #! are added to the active set. | 
					
						
							|  |  |  |     unhandled-intervals get dup heap-empty? [ 2drop ] [ | 
					
						
							|  |  |  |         2dup heap-peek drop start>> = [ | 
					
						
							|  |  |  |             heap-pop drop [ add-active ] [ insert-reload ] bi
 | 
					
						
							|  |  |  |             activate-new-intervals | 
					
						
							|  |  |  |         ] [ 2drop ] if
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-02 04:58:32 -05:00
										 |  |  | GENERIC: (assign-registers) ( insn -- )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: vreg-insn (assign-registers) | 
					
						
							| 
									
										
										
										
											2008-09-15 05:22:12 -04:00
										 |  |  |     dup
 | 
					
						
							|  |  |  |     [ defs-vregs ] [ uses-vregs ] bi append
 | 
					
						
							|  |  |  |     active-intervals get swap '[ vreg>> _ member? ] filter
 | 
					
						
							|  |  |  |     [ [ vreg>> ] [ reg>> ] bi ] { } map>assoc
 | 
					
						
							|  |  |  |     >>regs drop ;
 | 
					
						
							| 
									
										
										
										
											2008-09-15 03:59:24 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-02 04:58:32 -05:00
										 |  |  | M: insn (assign-registers) drop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-15 05:22:12 -04:00
										 |  |  | : init-assignment ( live-intervals -- )
 | 
					
						
							|  |  |  |     V{ } clone active-intervals set
 | 
					
						
							|  |  |  |     <min-heap> unhandled-intervals set
 | 
					
						
							|  |  |  |     init-unhandled ;
 | 
					
						
							| 
									
										
										
										
											2008-09-15 03:59:24 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-15 05:22:12 -04:00
										 |  |  | : assign-registers ( insns live-intervals -- insns' )
 | 
					
						
							| 
									
										
										
										
											2008-09-15 03:59:24 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-09-15 05:22:12 -04:00
										 |  |  |         init-assignment | 
					
						
							| 
									
										
										
										
											2008-09-15 03:59:24 -04:00
										 |  |  |         [ | 
					
						
							|  |  |  |             [ activate-new-intervals ] | 
					
						
							| 
									
										
										
										
											2008-09-15 05:22:12 -04:00
										 |  |  |             [ drop [ (assign-registers) ] [ , ] bi ] | 
					
						
							| 
									
										
										
										
											2008-09-15 03:59:24 -04:00
										 |  |  |             [ expire-old-intervals ] | 
					
						
							|  |  |  |             tri
 | 
					
						
							|  |  |  |         ] each-index
 | 
					
						
							|  |  |  |     ] { } make ;
 |