compiler.cfg.linear-scan: fix bad interaction between split position calculation and register-clobbering instructions
							parent
							
								
									80d0ed0110
								
							
						
					
					
						commit
						b776a92546
					
				| 
						 | 
				
			
			@ -48,52 +48,33 @@ IN: compiler.cfg.linear-scan.allocation
 | 
			
		|||
    2dup spill-at-sync-point?
 | 
			
		||||
    [ swap n>> spill f ] [ 2drop t ] if ;
 | 
			
		||||
 | 
			
		||||
: handle-interval ( live-interval -- )
 | 
			
		||||
GENERIC: handle ( obj -- )
 | 
			
		||||
 | 
			
		||||
M: live-interval handle
 | 
			
		||||
    [ start>> deactivate-intervals ]
 | 
			
		||||
    [ start>> activate-intervals ]
 | 
			
		||||
    [ assign-register ]
 | 
			
		||||
    tri ;
 | 
			
		||||
 | 
			
		||||
: (handle-sync-point) ( sync-point -- )
 | 
			
		||||
: handle-sync-point ( sync-point -- )
 | 
			
		||||
    active-intervals get values
 | 
			
		||||
    [ [ spill-at-sync-point ] with filter! drop ] with each ;
 | 
			
		||||
 | 
			
		||||
: handle-sync-point ( sync-point -- )
 | 
			
		||||
M: sync-point handle ( sync-point -- )
 | 
			
		||||
    [ n>> deactivate-intervals ]
 | 
			
		||||
    [ (handle-sync-point) ]
 | 
			
		||||
    [ handle-sync-point ]
 | 
			
		||||
    [ n>> activate-intervals ]
 | 
			
		||||
    tri ;
 | 
			
		||||
 | 
			
		||||
: smallest-heap ( heap1 heap2 -- heap )
 | 
			
		||||
    [ [ heap-peek nip ] bi@ <= ] most ;
 | 
			
		||||
 | 
			
		||||
:: (allocate-registers-step) ( unhandled-intervals unhandled-sync-points -- )
 | 
			
		||||
    {
 | 
			
		||||
        {
 | 
			
		||||
            [ unhandled-intervals heap-empty? ]
 | 
			
		||||
            [ unhandled-sync-points heap-pop drop handle-sync-point ]
 | 
			
		||||
        }
 | 
			
		||||
        {
 | 
			
		||||
            [ unhandled-sync-points heap-empty? ]
 | 
			
		||||
            [ unhandled-intervals heap-pop drop handle-interval ]
 | 
			
		||||
        }
 | 
			
		||||
        [
 | 
			
		||||
            unhandled-intervals heap-peek :> ( i ik )
 | 
			
		||||
            unhandled-sync-points heap-peek :> ( s sk )
 | 
			
		||||
            {
 | 
			
		||||
                {
 | 
			
		||||
                    [ ik sk < ]
 | 
			
		||||
                    [ unhandled-intervals heap-pop* i handle-interval ]
 | 
			
		||||
                }
 | 
			
		||||
                {
 | 
			
		||||
                    [ ik sk > ]
 | 
			
		||||
                    [ unhandled-sync-points heap-pop* s handle-sync-point ]
 | 
			
		||||
                }
 | 
			
		||||
                [
 | 
			
		||||
                    unhandled-intervals heap-pop*
 | 
			
		||||
                    i handle-interval
 | 
			
		||||
                    s (handle-sync-point)
 | 
			
		||||
                ]
 | 
			
		||||
            } cond
 | 
			
		||||
        ]
 | 
			
		||||
    } cond ;
 | 
			
		||||
        { [ unhandled-intervals heap-empty? ] [ unhandled-sync-points ] }
 | 
			
		||||
        { [ unhandled-sync-points heap-empty? ] [ unhandled-intervals ] }
 | 
			
		||||
        [ unhandled-sync-points unhandled-intervals smallest-heap ]
 | 
			
		||||
    } cond heap-pop drop handle ;
 | 
			
		||||
 | 
			
		||||
: (allocate-registers) ( unhandled-intervals unhandled-sync-points -- )
 | 
			
		||||
    2dup [ heap-empty? ] both? [ 2drop ] [
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,12 +79,13 @@ ERROR: bad-live-ranges interval ;
 | 
			
		|||
: split-for-spill ( live-interval n -- before after )
 | 
			
		||||
    split-interval [ spill-before ] [ spill-after ] bi* ;
 | 
			
		||||
 | 
			
		||||
: find-use-position ( live-interval new -- n )
 | 
			
		||||
    [ uses>> ] [ start>> '[ n>> _ >= ] ] bi* find nip
 | 
			
		||||
: find-next-use ( live-interval new -- n )
 | 
			
		||||
    [ uses>> ] [ start>> ] bi*
 | 
			
		||||
    '[ [ spill-slot?>> not ] [ n>> ] bi _ >= and ] find nip
 | 
			
		||||
    [ n>> ] [ 1/0. ] if* ;
 | 
			
		||||
 | 
			
		||||
: find-use-positions ( live-intervals new assoc -- )
 | 
			
		||||
    '[ [ _ find-use-position ] [ reg>> ] bi _ add-use-position ] each ;
 | 
			
		||||
    '[ [ _ find-next-use ] [ reg>> ] bi _ add-use-position ] each ;
 | 
			
		||||
 | 
			
		||||
: active-positions ( new assoc -- )
 | 
			
		||||
    [ [ active-intervals-for ] keep ] dip
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,7 @@ TUPLE: live-range from to ;
 | 
			
		|||
 | 
			
		||||
C: <live-range> live-range
 | 
			
		||||
 | 
			
		||||
TUPLE: vreg-use n def-rep use-rep ;
 | 
			
		||||
TUPLE: vreg-use n def-rep use-rep spill-slot? ;
 | 
			
		||||
 | 
			
		||||
: <vreg-use> ( n -- vreg-use ) vreg-use new swap >>n ;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -36,8 +36,10 @@ reg-class ;
 | 
			
		|||
: last-use? ( insn# uses -- use/f )
 | 
			
		||||
    [ drop f ] [ last [ n>> = ] keep and ] if-empty ;
 | 
			
		||||
 | 
			
		||||
: (add-use) ( insn# live-interval -- use )
 | 
			
		||||
    uses>> 2dup last-use? dup [ 2nip ] [ drop new-use ] if ;
 | 
			
		||||
:: (add-use) ( insn# live-interval spill-slot? -- use )
 | 
			
		||||
    live-interval uses>> :> uses
 | 
			
		||||
    insn# uses last-use? [ insn# uses new-use ] unless*
 | 
			
		||||
    spill-slot? [ t >>spill-slot? ] when ;
 | 
			
		||||
 | 
			
		||||
GENERIC: covers? ( insn# obj -- ? )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -105,28 +107,42 @@ GENERIC: compute-live-intervals* ( insn -- )
 | 
			
		|||
 | 
			
		||||
M: insn compute-live-intervals* drop ;
 | 
			
		||||
 | 
			
		||||
:: record-def ( vreg n -- )
 | 
			
		||||
:: record-def ( vreg n spill-slot? -- )
 | 
			
		||||
    vreg live-interval :> live-interval
 | 
			
		||||
 | 
			
		||||
    n live-interval shorten-range
 | 
			
		||||
    n live-interval (add-use) vreg rep-of >>def-rep drop ;
 | 
			
		||||
    n live-interval spill-slot? (add-use) vreg rep-of >>def-rep drop ;
 | 
			
		||||
 | 
			
		||||
:: record-use ( vreg n -- )
 | 
			
		||||
:: record-use ( vreg n spill-slot? -- )
 | 
			
		||||
    vreg live-interval :> live-interval
 | 
			
		||||
 | 
			
		||||
    from get n live-interval add-range
 | 
			
		||||
    n live-interval (add-use) vreg rep-of >>use-rep drop ;
 | 
			
		||||
    n live-interval spill-slot? (add-use) vreg rep-of >>use-rep drop ;
 | 
			
		||||
 | 
			
		||||
:: record-temp ( vreg n -- )
 | 
			
		||||
    vreg live-interval :> live-interval
 | 
			
		||||
 | 
			
		||||
    n n live-interval add-range
 | 
			
		||||
    n live-interval (add-use) vreg rep-of >>def-rep drop ;
 | 
			
		||||
    n live-interval f (add-use) vreg rep-of >>def-rep drop ;
 | 
			
		||||
 | 
			
		||||
M: vreg-insn compute-live-intervals* ( insn -- )
 | 
			
		||||
    dup insn#>>
 | 
			
		||||
    [ [ defs-vregs ] dip '[ _ record-def ] each ]
 | 
			
		||||
    [ [ uses-vregs ] dip '[ _ record-use ] each ]
 | 
			
		||||
    [ [ defs-vregs ] dip '[ _ f record-def ] each ]
 | 
			
		||||
    [ [ uses-vregs ] dip '[ _ f record-use ] each ]
 | 
			
		||||
    [ [ temp-vregs ] dip '[ _ record-temp ] each ]
 | 
			
		||||
    2tri ;
 | 
			
		||||
 | 
			
		||||
M: clobber-insn compute-live-intervals* ( insn -- )
 | 
			
		||||
    dup insn#>>
 | 
			
		||||
    [ [ defs-vregs ] dip '[ _ f record-def ] each ]
 | 
			
		||||
    [ [ uses-vregs ] dip '[ _ t record-use ] each ]
 | 
			
		||||
    [ [ temp-vregs ] dip '[ _ record-temp ] each ]
 | 
			
		||||
    2tri ;
 | 
			
		||||
 | 
			
		||||
M: hairy-clobber-insn compute-live-intervals* ( insn -- )
 | 
			
		||||
    dup insn#>>
 | 
			
		||||
    [ [ defs-vregs ] dip '[ _ t record-def ] each ]
 | 
			
		||||
    [ [ uses-vregs ] dip '[ _ t record-use ] each ]
 | 
			
		||||
    [ [ temp-vregs ] dip '[ _ record-temp ] each ]
 | 
			
		||||
    2tri ;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue