compiler.cfg: convert code into two-operand form before SSA destruction; SSA destruction now operates on a relaxed SSA form where multiple defs of the same vreg are allowed, but only within a single basic block. This makes linear scan's coalescing redundant, allowing it to be removed completely
							parent
							
								
									eb3bd1edea
								
							
						
					
					
						commit
						370f4c081d
					
				| 
						 | 
					@ -3,7 +3,6 @@
 | 
				
			||||||
USING: accessors assocs heaps kernel namespaces sequences fry math
 | 
					USING: accessors assocs heaps kernel namespaces sequences fry math
 | 
				
			||||||
math.order combinators arrays sorting compiler.utilities
 | 
					math.order combinators arrays sorting compiler.utilities
 | 
				
			||||||
compiler.cfg.linear-scan.live-intervals
 | 
					compiler.cfg.linear-scan.live-intervals
 | 
				
			||||||
compiler.cfg.linear-scan.allocation.coalescing
 | 
					 | 
				
			||||||
compiler.cfg.linear-scan.allocation.spilling
 | 
					compiler.cfg.linear-scan.allocation.spilling
 | 
				
			||||||
compiler.cfg.linear-scan.allocation.splitting
 | 
					compiler.cfg.linear-scan.allocation.splitting
 | 
				
			||||||
compiler.cfg.linear-scan.allocation.state ;
 | 
					compiler.cfg.linear-scan.allocation.state ;
 | 
				
			||||||
| 
						 | 
					@ -29,13 +28,11 @@ IN: compiler.cfg.linear-scan.allocation
 | 
				
			||||||
    second 0 = ; inline
 | 
					    second 0 = ; inline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: assign-register ( new -- )
 | 
					: assign-register ( new -- )
 | 
				
			||||||
    dup coalesce? [ coalesce ] [
 | 
					    dup register-status {
 | 
				
			||||||
        dup register-status {
 | 
					        { [ dup no-free-registers? ] [ drop assign-blocked-register ] }
 | 
				
			||||||
            { [ dup no-free-registers? ] [ drop assign-blocked-register ] }
 | 
					        { [ 2dup register-available? ] [ register-available ] }
 | 
				
			||||||
            { [ 2dup register-available? ] [ register-available ] }
 | 
					        [ drop assign-blocked-register ]
 | 
				
			||||||
            [ drop assign-blocked-register ]
 | 
					    } cond ;
 | 
				
			||||||
        } cond
 | 
					 | 
				
			||||||
    ] if ;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
: handle-interval ( live-interval -- )
 | 
					: handle-interval ( live-interval -- )
 | 
				
			||||||
    [
 | 
					    [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,35 +0,0 @@
 | 
				
			||||||
! Copyright (C) 2009 Slava Pestov.
 | 
					 | 
				
			||||||
! See http://factorcode.org/license.txt for BSD license.
 | 
					 | 
				
			||||||
USING: accessors kernel sequences namespaces assocs fry
 | 
					 | 
				
			||||||
combinators.short-circuit
 | 
					 | 
				
			||||||
compiler.cfg.linear-scan.live-intervals
 | 
					 | 
				
			||||||
compiler.cfg.linear-scan.allocation.state ;
 | 
					 | 
				
			||||||
IN: compiler.cfg.linear-scan.allocation.coalescing
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: active-interval ( vreg -- live-interval )
 | 
					 | 
				
			||||||
    dup [ dup active-intervals-for [ vreg>> = ] with find nip ] when ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: avoids-inactive-intervals? ( live-interval -- ? )
 | 
					 | 
				
			||||||
    dup vreg>> inactive-intervals-for
 | 
					 | 
				
			||||||
    [ intervals-intersect? not ] with all? ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: coalesce? ( live-interval -- ? )
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        [ copy-from>> active-interval ]
 | 
					 | 
				
			||||||
        [ [ start>> ] [ copy-from>> active-interval end>> ] bi = ]
 | 
					 | 
				
			||||||
        [ avoids-inactive-intervals? ]
 | 
					 | 
				
			||||||
    } 1&& ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: reuse-spill-slot ( old new -- )
 | 
					 | 
				
			||||||
    [ vreg>> spill-slots get at ] dip '[ _ vreg>> spill-slots get set-at ] when* ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: reuse-register ( old new -- )
 | 
					 | 
				
			||||||
    reg>> >>reg drop ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: (coalesce) ( old new -- )
 | 
					 | 
				
			||||||
    [ add-active ] [ [ delete-active ] [ add-handled ] bi ] bi* ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: coalesce ( live-interval -- )
 | 
					 | 
				
			||||||
    dup copy-from>> active-interval
 | 
					 | 
				
			||||||
    [ reuse-spill-slot ] [ reuse-register ] [ (coalesce) ] 2tri ;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
| 
						 | 
					@ -45,7 +45,7 @@ ERROR: splitting-atomic-interval ;
 | 
				
			||||||
    f >>spill-to ; inline
 | 
					    f >>spill-to ; inline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: split-after ( after -- after' )
 | 
					: split-after ( after -- after' )
 | 
				
			||||||
    f >>copy-from f >>reg f >>reload-from ; inline
 | 
					    f >>reg f >>reload-from ; inline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:: split-interval ( live-interval n -- before after )
 | 
					:: split-interval ( live-interval n -- before after )
 | 
				
			||||||
    live-interval n check-split
 | 
					    live-interval n check-split
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,9 +18,8 @@ IN: compiler.cfg.linear-scan.debugger
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: interval-picture ( interval -- str )
 | 
					: interval-picture ( interval -- str )
 | 
				
			||||||
    [ uses>> picture ]
 | 
					    [ uses>> picture ]
 | 
				
			||||||
    [ copy-from>> unparse ]
 | 
					 | 
				
			||||||
    [ vreg>> unparse ]
 | 
					    [ vreg>> unparse ]
 | 
				
			||||||
    tri 3array ;
 | 
					    bi 2array ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: live-intervals. ( seq -- )
 | 
					: live-intervals. ( seq -- )
 | 
				
			||||||
    [ interval-picture ] map simple-table. ;
 | 
					    [ interval-picture ] map simple-table. ;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -470,7 +470,6 @@ USING: math.private ;
 | 
				
			||||||
        clone dup [ start>> ] [ end>> ] bi <live-range> 1vector >>ranges
 | 
					        clone dup [ start>> ] [ end>> ] bi <live-range> 1vector >>ranges
 | 
				
			||||||
    ] map ;
 | 
					    ] map ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
! Coalescing interacted badly with splitting
 | 
					 | 
				
			||||||
[ ] [
 | 
					[ ] [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
| 
						 | 
					@ -478,7 +477,6 @@ USING: math.private ;
 | 
				
			||||||
            { start 14 }
 | 
					            { start 14 }
 | 
				
			||||||
            { end 17 }
 | 
					            { end 17 }
 | 
				
			||||||
            { uses V{ 14 15 16 17 } }
 | 
					            { uses V{ 14 15 16 17 } }
 | 
				
			||||||
            { copy-from V int-regs 67 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 67 }
 | 
					            { vreg V int-regs 67 }
 | 
				
			||||||
| 
						 | 
					@ -503,7 +501,6 @@ USING: math.private ;
 | 
				
			||||||
            { start 10 }
 | 
					            { start 10 }
 | 
				
			||||||
            { end 18 }
 | 
					            { end 18 }
 | 
				
			||||||
            { uses V{ 10 11 12 18 } }
 | 
					            { uses V{ 10 11 12 18 } }
 | 
				
			||||||
            { copy-from V int-regs 56 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 60 }
 | 
					            { vreg V int-regs 60 }
 | 
				
			||||||
| 
						 | 
					@ -559,7 +556,6 @@ USING: math.private ;
 | 
				
			||||||
            { start 44 }
 | 
					            { start 44 }
 | 
				
			||||||
            { end 56 }
 | 
					            { end 56 }
 | 
				
			||||||
            { uses V{ 44 45 45 46 56 } }
 | 
					            { uses V{ 44 45 45 46 56 } }
 | 
				
			||||||
            { copy-from V int-regs 3686445 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 3686198 }
 | 
					            { vreg V int-regs 3686198 }
 | 
				
			||||||
| 
						 | 
					@ -572,7 +568,6 @@ USING: math.private ;
 | 
				
			||||||
            { start 46 }
 | 
					            { start 46 }
 | 
				
			||||||
            { end 49 }
 | 
					            { end 49 }
 | 
				
			||||||
            { uses V{ 46 47 47 49 } }
 | 
					            { uses V{ 46 47 47 49 } }
 | 
				
			||||||
            { copy-from V int-regs 3686449 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 3686196 }
 | 
					            { vreg V int-regs 3686196 }
 | 
				
			||||||
| 
						 | 
					@ -603,7 +598,6 @@ USING: math.private ;
 | 
				
			||||||
            { start 49 }
 | 
					            { start 49 }
 | 
				
			||||||
            { end 52 }
 | 
					            { end 52 }
 | 
				
			||||||
            { uses V{ 49 50 50 52 } }
 | 
					            { uses V{ 49 50 50 52 } }
 | 
				
			||||||
            { copy-from V int-regs 3686454 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 3686461 }
 | 
					            { vreg V int-regs 3686461 }
 | 
				
			||||||
| 
						 | 
					@ -622,42 +616,36 @@ USING: math.private ;
 | 
				
			||||||
            { start 54 }
 | 
					            { start 54 }
 | 
				
			||||||
            { end 76 }
 | 
					            { end 76 }
 | 
				
			||||||
            { uses V{ 54 55 55 76 } }
 | 
					            { uses V{ 54 55 55 76 } }
 | 
				
			||||||
            { copy-from V int-regs 3686464 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 3686470 }
 | 
					            { vreg V int-regs 3686470 }
 | 
				
			||||||
            { start 58 }
 | 
					            { start 58 }
 | 
				
			||||||
            { end 60 }
 | 
					            { end 60 }
 | 
				
			||||||
            { uses V{ 58 59 59 60 } }
 | 
					            { uses V{ 58 59 59 60 } }
 | 
				
			||||||
            { copy-from V int-regs 3686469 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 3686469 }
 | 
					            { vreg V int-regs 3686469 }
 | 
				
			||||||
            { start 56 }
 | 
					            { start 56 }
 | 
				
			||||||
            { end 58 }
 | 
					            { end 58 }
 | 
				
			||||||
            { uses V{ 56 57 57 58 } }
 | 
					            { uses V{ 56 57 57 58 } }
 | 
				
			||||||
            { copy-from V int-regs 3686449 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 3686473 }
 | 
					            { vreg V int-regs 3686473 }
 | 
				
			||||||
            { start 60 }
 | 
					            { start 60 }
 | 
				
			||||||
            { end 62 }
 | 
					            { end 62 }
 | 
				
			||||||
            { uses V{ 60 61 61 62 } }
 | 
					            { uses V{ 60 61 61 62 } }
 | 
				
			||||||
            { copy-from V int-regs 3686470 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 3686479 }
 | 
					            { vreg V int-regs 3686479 }
 | 
				
			||||||
            { start 62 }
 | 
					            { start 62 }
 | 
				
			||||||
            { end 64 }
 | 
					            { end 64 }
 | 
				
			||||||
            { uses V{ 62 63 63 64 } }
 | 
					            { uses V{ 62 63 63 64 } }
 | 
				
			||||||
            { copy-from V int-regs 3686473 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 3686735 }
 | 
					            { vreg V int-regs 3686735 }
 | 
				
			||||||
            { start 78 }
 | 
					            { start 78 }
 | 
				
			||||||
            { end 96 }
 | 
					            { end 96 }
 | 
				
			||||||
            { uses V{ 78 79 79 96 } }
 | 
					            { uses V{ 78 79 79 96 } }
 | 
				
			||||||
            { copy-from V int-regs 3686372 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 3686482 }
 | 
					            { vreg V int-regs 3686482 }
 | 
				
			||||||
| 
						 | 
					@ -688,7 +676,6 @@ USING: math.private ;
 | 
				
			||||||
            { start 66 }
 | 
					            { start 66 }
 | 
				
			||||||
            { end 75 }
 | 
					            { end 75 }
 | 
				
			||||||
            { uses V{ 66 67 67 75 } }
 | 
					            { uses V{ 66 67 67 75 } }
 | 
				
			||||||
            { copy-from V int-regs 3686483 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 3687509 }
 | 
					            { vreg V int-regs 3687509 }
 | 
				
			||||||
| 
						 | 
					@ -719,7 +706,6 @@ USING: math.private ;
 | 
				
			||||||
            { start 69 }
 | 
					            { start 69 }
 | 
				
			||||||
            { end 74 }
 | 
					            { end 74 }
 | 
				
			||||||
            { uses V{ 69 70 70 74 } }
 | 
					            { uses V{ 69 70 70 74 } }
 | 
				
			||||||
            { copy-from V int-regs 3686491 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 3687778 }
 | 
					            { vreg V int-regs 3687778 }
 | 
				
			||||||
| 
						 | 
					@ -762,7 +748,6 @@ USING: math.private ;
 | 
				
			||||||
            { start 72 }
 | 
					            { start 72 }
 | 
				
			||||||
            { end 74 }
 | 
					            { end 74 }
 | 
				
			||||||
            { uses V{ 72 73 73 74 } }
 | 
					            { uses V{ 72 73 73 74 } }
 | 
				
			||||||
            { copy-from V int-regs 3686499 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 3687780 }
 | 
					            { vreg V int-regs 3687780 }
 | 
				
			||||||
| 
						 | 
					@ -877,7 +862,6 @@ USING: math.private ;
 | 
				
			||||||
            { start 27 }
 | 
					            { start 27 }
 | 
				
			||||||
            { end 30 }
 | 
					            { end 30 }
 | 
				
			||||||
            { uses V{ 27 28 28 30 } }
 | 
					            { uses V{ 27 28 28 30 } }
 | 
				
			||||||
            { copy-from V int-regs 3686300 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 3686306 }
 | 
					            { vreg V int-regs 3686306 }
 | 
				
			||||||
| 
						 | 
					@ -950,7 +934,6 @@ USING: math.private ;
 | 
				
			||||||
            { start 243 }
 | 
					            { start 243 }
 | 
				
			||||||
            { end 245 }
 | 
					            { end 245 }
 | 
				
			||||||
            { uses V{ 243 244 244 245 } }
 | 
					            { uses V{ 243 244 244 245 } }
 | 
				
			||||||
            { copy-from V int-regs 3687845 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 3687850 }
 | 
					            { vreg V int-regs 3687850 }
 | 
				
			||||||
| 
						 | 
					@ -1119,7 +1102,6 @@ USING: math.private ;
 | 
				
			||||||
            { start 141 }
 | 
					            { start 141 }
 | 
				
			||||||
            { end 143 }
 | 
					            { end 143 }
 | 
				
			||||||
            { uses V{ 141 142 142 143 } }
 | 
					            { uses V{ 141 142 142 143 } }
 | 
				
			||||||
            { copy-from V int-regs 3687377 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 3687381 }
 | 
					            { vreg V int-regs 3687381 }
 | 
				
			||||||
| 
						 | 
					@ -1174,7 +1156,6 @@ USING: math.private ;
 | 
				
			||||||
            { start 293 }
 | 
					            { start 293 }
 | 
				
			||||||
            { end 295 }
 | 
					            { end 295 }
 | 
				
			||||||
            { uses V{ 293 294 294 295 } }
 | 
					            { uses V{ 293 294 294 295 } }
 | 
				
			||||||
            { copy-from V int-regs 3687087 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 3687403 }
 | 
					            { vreg V int-regs 3687403 }
 | 
				
			||||||
| 
						 | 
					@ -1345,7 +1326,6 @@ USING: math.private ;
 | 
				
			||||||
            { start 78 }
 | 
					            { start 78 }
 | 
				
			||||||
            { end 96 }
 | 
					            { end 96 }
 | 
				
			||||||
            { uses V{ 78 79 96 } }
 | 
					            { uses V{ 78 79 96 } }
 | 
				
			||||||
            { copy-from V int-regs 6372 }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        T{ live-interval
 | 
					        T{ live-interval
 | 
				
			||||||
            { vreg V int-regs 6483 }
 | 
					            { vreg V int-regs 6483 }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,8 +13,7 @@ C: <live-range> live-range
 | 
				
			||||||
TUPLE: live-interval
 | 
					TUPLE: live-interval
 | 
				
			||||||
vreg
 | 
					vreg
 | 
				
			||||||
reg spill-to reload-from
 | 
					reg spill-to reload-from
 | 
				
			||||||
start end ranges uses
 | 
					start end ranges uses ;
 | 
				
			||||||
copy-from ;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
GENERIC: covers? ( insn# obj -- ? )
 | 
					GENERIC: covers? ( insn# obj -- ? )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -102,15 +101,6 @@ M: vreg-insn compute-live-intervals*
 | 
				
			||||||
    [ [ temp-vregs ] 2dip '[ [ _ ] dip _ handle-temp ] each ]
 | 
					    [ [ temp-vregs ] 2dip '[ [ _ ] dip _ handle-temp ] each ]
 | 
				
			||||||
    3tri ;
 | 
					    3tri ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: record-copy ( insn -- )
 | 
					 | 
				
			||||||
    [ dst>> live-intervals get at ] [ src>> ] bi >>copy-from drop ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
M: ##copy compute-live-intervals*
 | 
					 | 
				
			||||||
    [ call-next-method ] [ record-copy ] bi ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
M: ##copy-float compute-live-intervals*
 | 
					 | 
				
			||||||
    [ call-next-method ] [ record-copy ] bi ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: handle-live-out ( bb -- )
 | 
					: handle-live-out ( bb -- )
 | 
				
			||||||
    live-out keys
 | 
					    live-out keys
 | 
				
			||||||
    basic-block get [ block-from ] [ block-to ] bi
 | 
					    basic-block get [ block-from ] [ block-to ] bi
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,12 +1,11 @@
 | 
				
			||||||
! Copyright (C) 2009 Slava Pestov.
 | 
					! Copyright (C) 2009 Slava Pestov.
 | 
				
			||||||
! See http://factorcode.org/license.txt for BSD license.
 | 
					! See http://factorcode.org/license.txt for BSD license.
 | 
				
			||||||
USING: compiler.cfg.linearization compiler.cfg.two-operand
 | 
					USING: compiler.cfg.linearization compiler.cfg.gc-checks
 | 
				
			||||||
compiler.cfg.gc-checks compiler.cfg.linear-scan
 | 
					compiler.cfg.linear-scan compiler.cfg.build-stack-frame
 | 
				
			||||||
compiler.cfg.build-stack-frame compiler.cfg.rpo ;
 | 
					compiler.cfg.rpo ;
 | 
				
			||||||
IN: compiler.cfg.mr
 | 
					IN: compiler.cfg.mr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: build-mr ( cfg -- mr )
 | 
					: build-mr ( cfg -- mr )
 | 
				
			||||||
    convert-two-operand
 | 
					 | 
				
			||||||
    insert-gc-checks
 | 
					    insert-gc-checks
 | 
				
			||||||
    linear-scan
 | 
					    linear-scan
 | 
				
			||||||
    flatten-cfg
 | 
					    flatten-cfg
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,7 @@ compiler.cfg.value-numbering
 | 
				
			||||||
compiler.cfg.copy-prop
 | 
					compiler.cfg.copy-prop
 | 
				
			||||||
compiler.cfg.dce
 | 
					compiler.cfg.dce
 | 
				
			||||||
compiler.cfg.write-barrier
 | 
					compiler.cfg.write-barrier
 | 
				
			||||||
 | 
					compiler.cfg.two-operand
 | 
				
			||||||
compiler.cfg.ssa.destruction
 | 
					compiler.cfg.ssa.destruction
 | 
				
			||||||
compiler.cfg.empty-blocks
 | 
					compiler.cfg.empty-blocks
 | 
				
			||||||
compiler.cfg.predecessors
 | 
					compiler.cfg.predecessors
 | 
				
			||||||
| 
						 | 
					@ -42,6 +43,7 @@ SYMBOL: check-optimizer?
 | 
				
			||||||
        copy-propagation
 | 
					        copy-propagation
 | 
				
			||||||
        eliminate-dead-code
 | 
					        eliminate-dead-code
 | 
				
			||||||
        eliminate-write-barriers
 | 
					        eliminate-write-barriers
 | 
				
			||||||
 | 
					        convert-two-operand
 | 
				
			||||||
        destruct-ssa
 | 
					        destruct-ssa
 | 
				
			||||||
        delete-empty-blocks
 | 
					        delete-empty-blocks
 | 
				
			||||||
        ?check
 | 
					        ?check
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,9 +58,13 @@ SYMBOL: copies
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GENERIC: prepare-insn ( insn -- )
 | 
					GENERIC: prepare-insn ( insn -- )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
M: ##copy prepare-insn
 | 
					: prepare-copy ( insn -- )
 | 
				
			||||||
    [ dst>> ] [ src>> ] bi 2array copies get push ;
 | 
					    [ dst>> ] [ src>> ] bi 2array copies get push ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					M: ##copy prepare-insn prepare-copy ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					M: ##copy-float prepare-insn prepare-copy ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
M: ##phi prepare-insn
 | 
					M: ##phi prepare-insn
 | 
				
			||||||
    [ dst>> ] [ inputs>> values ] bi
 | 
					    [ dst>> ] [ inputs>> values ] bi
 | 
				
			||||||
    [ eliminate-copy ] with each ;
 | 
					    [ eliminate-copy ] with each ;
 | 
				
			||||||
| 
						 | 
					@ -81,8 +85,10 @@ M: insn prepare-insn drop ;
 | 
				
			||||||
        [ 2drop ] [ eliminate-copy ] if
 | 
					        [ 2drop ] [ eliminate-copy ] if
 | 
				
			||||||
    ] assoc-each ;
 | 
					    ] assoc-each ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					UNION: copy-insn ##copy ##copy-float ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: useless-copy? ( ##copy -- ? )
 | 
					: useless-copy? ( ##copy -- ? )
 | 
				
			||||||
    dup ##copy? [ [ dst>> ] [ src>> ] bi eq? ] [ drop f ] if ;
 | 
					    dup copy-insn? [ [ dst>> ] [ src>> ] bi eq? ] [ drop f ] if ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: perform-renaming ( cfg -- )
 | 
					: perform-renaming ( cfg -- )
 | 
				
			||||||
    leader-map get keys [ dup leader ] H{ } map>assoc renamings set
 | 
					    leader-map get keys [ dup leader ] H{ } map>assoc renamings set
 | 
				
			||||||
| 
						 | 
					@ -95,13 +101,11 @@ M: insn prepare-insn drop ;
 | 
				
			||||||
    ] each-basic-block ;
 | 
					    ] each-basic-block ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: destruct-ssa ( cfg -- cfg' )
 | 
					: destruct-ssa ( cfg -- cfg' )
 | 
				
			||||||
    dup cfg-has-phis? [
 | 
					    dup construct-cssa
 | 
				
			||||||
        dup construct-cssa
 | 
					    dup compute-defs
 | 
				
			||||||
        dup compute-defs
 | 
					    dup compute-dominance
 | 
				
			||||||
        dup compute-dominance
 | 
					    compute-ssa-live-sets
 | 
				
			||||||
        compute-ssa-live-sets
 | 
					    dup compute-live-ranges
 | 
				
			||||||
        dup compute-live-ranges
 | 
					    dup prepare-coalescing
 | 
				
			||||||
        dup prepare-coalescing
 | 
					    process-copies
 | 
				
			||||||
        process-copies
 | 
					    dup perform-renaming ;
 | 
				
			||||||
        dup perform-renaming
 | 
					 | 
				
			||||||
    ] when ;
 | 
					 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,11 @@ compiler.cfg.def-use compiler.cfg.dominance
 | 
				
			||||||
compiler.cfg.ssa.interference.live-ranges ;
 | 
					compiler.cfg.ssa.interference.live-ranges ;
 | 
				
			||||||
IN: compiler.cfg.ssa.interference
 | 
					IN: compiler.cfg.ssa.interference
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! Interference testing using SSA properties. Actually the only SSA property
 | 
				
			||||||
 | 
					! used here is that definitions dominate uses; because of this, the input
 | 
				
			||||||
 | 
					! is allowed to have multiple definitions of each vreg as long as they're
 | 
				
			||||||
 | 
					! all in the same basic block. This is needed because two-operand conversion
 | 
				
			||||||
 | 
					! runs before coalescing, which uses SSA interference testing.
 | 
				
			||||||
<PRIVATE
 | 
					<PRIVATE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:: kill-after-def? ( vreg1 vreg2 bb -- ? )
 | 
					:: kill-after-def? ( vreg1 vreg2 bb -- ? )
 | 
				
			||||||
| 
						 | 
					@ -47,9 +52,10 @@ PRIVATE>
 | 
				
			||||||
        [ 2drop 2drop f ]
 | 
					        [ 2drop 2drop f ]
 | 
				
			||||||
    } cond ;
 | 
					    } cond ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
! Debug this stuff later
 | 
					 | 
				
			||||||
<PRIVATE
 | 
					<PRIVATE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! Debug this stuff later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: quadratic-test? ( seq1 seq2 -- ? ) [ length ] bi@ + 10 < ;
 | 
					: quadratic-test? ( seq1 seq2 -- ? ) [ length ] bi@ + 10 < ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: quadratic-test ( seq1 seq2 -- ? )
 | 
					: quadratic-test ( seq1 seq2 -- ? )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,8 +11,13 @@ IN: compiler.cfg.ssa.interference.live-ranges
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SYMBOLS: local-def-indices local-kill-indices ;
 | 
					SYMBOLS: local-def-indices local-kill-indices ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: record-def ( n vregs -- )
 | 
					: record-def ( n vreg -- )
 | 
				
			||||||
    dup [ local-def-indices get set-at ] [ 2drop ] if ;
 | 
					    ! We allow multiple defs of a vreg as long as they're
 | 
				
			||||||
 | 
					    ! all in the same basic block
 | 
				
			||||||
 | 
					    dup [
 | 
				
			||||||
 | 
					        local-def-indices get 2dup key?
 | 
				
			||||||
 | 
					        [ 3drop ] [ set-at ] if
 | 
				
			||||||
 | 
					    ] [ 2drop ] if ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: record-uses ( n vregs -- )
 | 
					: record-uses ( n vregs -- )
 | 
				
			||||||
    local-kill-indices get '[ _ set-at ] with each ;
 | 
					    local-kill-indices get '[ _ set-at ] with each ;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,25 +14,3 @@ compiler.cfg.registers cpu.architecture namespaces tools.test ;
 | 
				
			||||||
        T{ ##sub f V int-regs 1 V int-regs 2 V int-regs 3 }
 | 
					        T{ ##sub f V int-regs 1 V int-regs 2 V int-regs 3 }
 | 
				
			||||||
    } (convert-two-operand)
 | 
					    } (convert-two-operand)
 | 
				
			||||||
] unit-test
 | 
					] unit-test
 | 
				
			||||||
 | 
					 | 
				
			||||||
[
 | 
					 | 
				
			||||||
    V{
 | 
					 | 
				
			||||||
        T{ ##sub f V int-regs 1 V int-regs 1 V int-regs 2 }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
] [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        T{ ##sub f V int-regs 1 V int-regs 1 V int-regs 2 }
 | 
					 | 
				
			||||||
    } (convert-two-operand)
 | 
					 | 
				
			||||||
] unit-test
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[
 | 
					 | 
				
			||||||
    V{
 | 
					 | 
				
			||||||
        T{ ##copy f V int-regs 4 V int-regs 1 }
 | 
					 | 
				
			||||||
        T{ ##copy f V int-regs 1 V int-regs 2 }
 | 
					 | 
				
			||||||
        T{ ##sub f V int-regs 1 V int-regs 1 V int-regs 4 }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
] [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        T{ ##sub f V int-regs 1 V int-regs 2 V int-regs 1 }
 | 
					 | 
				
			||||||
    } (convert-two-operand)
 | 
					 | 
				
			||||||
] unit-test
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,27 +5,17 @@ compiler.cfg.registers compiler.cfg.instructions
 | 
				
			||||||
compiler.cfg.rpo cpu.architecture ;
 | 
					compiler.cfg.rpo cpu.architecture ;
 | 
				
			||||||
IN: compiler.cfg.two-operand
 | 
					IN: compiler.cfg.two-operand
 | 
				
			||||||
 | 
					
 | 
				
			||||||
! This pass runs after SSA coalescing and normalizes instructions
 | 
					! This pass runs before SSA coalescing and normalizes instructions
 | 
				
			||||||
! to fit the x86 two-address scheme. Possibilities are:
 | 
					! to fit the x86 two-address scheme. Since the input is in SSA,
 | 
				
			||||||
 | 
					! it suffices to convert
 | 
				
			||||||
! 1) x = x op y
 | 
					!
 | 
				
			||||||
! 2) x = y op x
 | 
					! x = y op z
 | 
				
			||||||
! 3) x = y op z
 | 
					!
 | 
				
			||||||
 | 
					! to
 | 
				
			||||||
! In case 1, there is nothing to do.
 | 
					!
 | 
				
			||||||
 | 
					 | 
				
			||||||
! In case 2, we convert to
 | 
					 | 
				
			||||||
! z = y
 | 
					 | 
				
			||||||
! z = z op x
 | 
					 | 
				
			||||||
! x = z
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
! In case 3, we convert to
 | 
					 | 
				
			||||||
! x = y
 | 
					! x = y
 | 
				
			||||||
! x = x op z
 | 
					! x = x op z
 | 
				
			||||||
 | 
					!
 | 
				
			||||||
! In case 2 and case 3, linear scan coalescing will eliminate a
 | 
					 | 
				
			||||||
! copy if the value y is never used again.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
! We don't bother with ##add, ##add-imm, ##sub-imm or ##mul-imm
 | 
					! We don't bother with ##add, ##add-imm, ##sub-imm or ##mul-imm
 | 
				
			||||||
! since x86 has LEA and IMUL instructions which are effectively
 | 
					! since x86 has LEA and IMUL instructions which are effectively
 | 
				
			||||||
! three-operand addition and multiplication, respectively.
 | 
					! three-operand addition and multiplication, respectively.
 | 
				
			||||||
| 
						 | 
					@ -59,37 +49,15 @@ GENERIC: convert-two-operand* ( insn -- )
 | 
				
			||||||
        { double-float-regs [ ##copy-float ] }
 | 
					        { double-float-regs [ ##copy-float ] }
 | 
				
			||||||
    } case ; inline
 | 
					    } case ; inline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: case-1? ( insn -- ? ) [ dst>> ] [ src1>> ] bi = ; inline
 | 
					M: two-operand-insn convert-two-operand*
 | 
				
			||||||
 | 
					 | 
				
			||||||
: case-1 ( insn -- ) , ; inline
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: case-2? ( insn -- ? ) [ dst>> ] [ src2>> ] bi = ; inline
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: case-2 ( insn -- )
 | 
					 | 
				
			||||||
    dup dst>> reg-class>> next-vreg
 | 
					 | 
				
			||||||
    [ swap src2>> emit-copy ]
 | 
					 | 
				
			||||||
    [ drop [ src2>> ] [ src1>> ] bi emit-copy ]
 | 
					 | 
				
			||||||
    [ >>src2 dup dst>> >>src1 , ]
 | 
					 | 
				
			||||||
    2tri ; inline
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: case-3 ( insn -- )
 | 
					 | 
				
			||||||
    [ [ dst>> ] [ src1>> ] bi emit-copy ]
 | 
					    [ [ dst>> ] [ src1>> ] bi emit-copy ]
 | 
				
			||||||
    [ dup dst>> >>src1 , ]
 | 
					    [ dup dst>> >>src1 , ]
 | 
				
			||||||
    bi ; inline
 | 
					    bi ;
 | 
				
			||||||
 | 
					 | 
				
			||||||
M: two-operand-insn convert-two-operand*
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        { [ dup case-1? ] [ case-1 ] }
 | 
					 | 
				
			||||||
        { [ dup case-2? ] [ case-2 ] }
 | 
					 | 
				
			||||||
        [ case-3 ]
 | 
					 | 
				
			||||||
    } cond ; inline
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
M: ##not convert-two-operand*
 | 
					M: ##not convert-two-operand*
 | 
				
			||||||
    dup [ dst>> ] [ src>> ] bi = [
 | 
					    [ [ dst>> ] [ src>> ] bi emit-copy ]
 | 
				
			||||||
        [ [ dst>> ] [ src>> ] bi ##copy ]
 | 
					    [ dup dst>> >>src , ]
 | 
				
			||||||
        [ dup dst>> >>src ]
 | 
					    bi ;
 | 
				
			||||||
        bi
 | 
					 | 
				
			||||||
    ] unless , ;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
M: insn convert-two-operand* , ;
 | 
					M: insn convert-two-operand* , ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue