compiler.cfg: Minor optimization. Instructions can now only ever produce a single value; this eliminates 1array constructions and some iterations
							parent
							
								
									7d3b6892d5
								
							
						
					
					
						commit
						d913d7331f
					
				| 
						 | 
				
			
			@ -59,7 +59,7 @@ ERROR: undefined-values uses defs ;
 | 
			
		|||
    ! Check that every used register has a definition
 | 
			
		||||
    instructions>>
 | 
			
		||||
    [ [ uses-vregs ] map concat ]
 | 
			
		||||
    [ [ [ defs-vregs ] [ temp-vregs ] bi append ] map concat ] bi
 | 
			
		||||
    [ [ [ temp-vregs ] [ defs-vreg ] bi [ suffix ] when* ] map concat ] bi
 | 
			
		||||
    2dup subset? [ 2drop ] [ undefined-values ] if ;
 | 
			
		||||
 | 
			
		||||
: check-cfg ( cfg -- )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,14 +4,14 @@ USING: accessors arrays kernel assocs sequences namespaces fry
 | 
			
		|||
sets compiler.cfg.rpo compiler.cfg.instructions ;
 | 
			
		||||
IN: compiler.cfg.def-use
 | 
			
		||||
 | 
			
		||||
GENERIC: defs-vregs ( insn -- seq )
 | 
			
		||||
GENERIC: defs-vreg ( insn -- vreg/f )
 | 
			
		||||
GENERIC: temp-vregs ( insn -- seq )
 | 
			
		||||
GENERIC: uses-vregs ( insn -- seq )
 | 
			
		||||
 | 
			
		||||
M: ##flushable defs-vregs dst>> 1array ;
 | 
			
		||||
M: ##fixnum-overflow defs-vregs dst>> 1array ;
 | 
			
		||||
M: _fixnum-overflow defs-vregs dst>> 1array ;
 | 
			
		||||
M: insn defs-vregs drop f ;
 | 
			
		||||
M: ##flushable defs-vreg dst>> ;
 | 
			
		||||
M: ##fixnum-overflow defs-vreg dst>> ;
 | 
			
		||||
M: _fixnum-overflow defs-vreg dst>> ;
 | 
			
		||||
M: insn defs-vreg drop f ;
 | 
			
		||||
 | 
			
		||||
M: ##write-barrier temp-vregs [ card#>> ] [ table>> ] bi 2array ;
 | 
			
		||||
M: ##unary/temp temp-vregs temp>> 1array ;
 | 
			
		||||
| 
						 | 
				
			
			@ -50,55 +50,48 @@ M: _compare-imm-branch uses-vregs src1>> 1array ;
 | 
			
		|||
M: _dispatch uses-vregs src>> 1array ;
 | 
			
		||||
M: insn uses-vregs drop f ;
 | 
			
		||||
 | 
			
		||||
! Computing def-use chains. We don't assume a program is in SSA form,
 | 
			
		||||
! since SSA construction itself needs def-use information. defs-1
 | 
			
		||||
! is only useful if the program is SSA.
 | 
			
		||||
SYMBOLS: defs defs-1 insns uses ;
 | 
			
		||||
! Computing def-use chains.
 | 
			
		||||
 | 
			
		||||
: def-of ( vreg -- node ) defs-1 get at ;
 | 
			
		||||
: defs-of ( vreg -- nodes ) defs get at ;
 | 
			
		||||
SYMBOLS: defs insns uses ;
 | 
			
		||||
 | 
			
		||||
: def-of ( vreg -- node ) defs get at ;
 | 
			
		||||
: uses-of ( vreg -- nodes ) uses get at ;
 | 
			
		||||
: insn-of ( vreg -- insn ) insns get at ;
 | 
			
		||||
 | 
			
		||||
<PRIVATE
 | 
			
		||||
: set-def-of ( obj insn assoc -- )
 | 
			
		||||
    swap defs-vreg dup [ swap set-at ] [ 3drop ] if ;
 | 
			
		||||
 | 
			
		||||
: finish-defs ( -- )
 | 
			
		||||
    defs [ [ keys ] assoc-map ] change ;
 | 
			
		||||
 | 
			
		||||
: finish-uses ( -- )
 | 
			
		||||
    uses [ [ keys ] assoc-map ] change ;
 | 
			
		||||
 | 
			
		||||
: (compute-def-use) ( cfg quot -- assoc )
 | 
			
		||||
: compute-defs ( cfg -- )
 | 
			
		||||
    H{ } clone [
 | 
			
		||||
        '[
 | 
			
		||||
            dup instructions>> [
 | 
			
		||||
                @ [
 | 
			
		||||
                    _ conjoin-at
 | 
			
		||||
                ] with each
 | 
			
		||||
                _ set-def-of
 | 
			
		||||
            ] with each
 | 
			
		||||
        ] each-basic-block
 | 
			
		||||
    ] keep
 | 
			
		||||
    [ keys ] assoc-map ; inline
 | 
			
		||||
 | 
			
		||||
PRIVATE>
 | 
			
		||||
 | 
			
		||||
: compute-defs ( cfg -- )
 | 
			
		||||
    [ defs-vregs ] (compute-def-use)
 | 
			
		||||
    [ defs set ] [ [ first ] assoc-map defs-1 set ] bi ;
 | 
			
		||||
 | 
			
		||||
: compute-uses ( cfg -- )
 | 
			
		||||
    [ uses-vregs ] (compute-def-use) uses set ;
 | 
			
		||||
    defs set ;
 | 
			
		||||
 | 
			
		||||
: compute-insns ( cfg -- )
 | 
			
		||||
    H{ } clone [
 | 
			
		||||
        '[
 | 
			
		||||
            instructions>> [
 | 
			
		||||
                dup defs-vregs [
 | 
			
		||||
                    _ set-at
 | 
			
		||||
                ] with each
 | 
			
		||||
                dup _ set-def-of
 | 
			
		||||
            ] each
 | 
			
		||||
        ] each-basic-block
 | 
			
		||||
    ] keep insns set ;
 | 
			
		||||
 | 
			
		||||
: compute-uses ( cfg -- )
 | 
			
		||||
    H{ } clone [
 | 
			
		||||
        '[
 | 
			
		||||
            dup instructions>> [
 | 
			
		||||
                uses-vregs [
 | 
			
		||||
                    _ conjoin-at
 | 
			
		||||
                ] with each
 | 
			
		||||
            ] with each
 | 
			
		||||
        ] each-basic-block
 | 
			
		||||
    ] keep
 | 
			
		||||
    [ keys ] assoc-map
 | 
			
		||||
    uses set ;
 | 
			
		||||
 | 
			
		||||
: compute-def-use ( cfg -- )
 | 
			
		||||
    [ compute-defs ] [ compute-uses ] [ compute-insns ] tri ;
 | 
			
		||||
| 
						 | 
				
			
			@ -86,7 +86,9 @@ GENERIC: assign-registers-in-insn ( insn -- )
 | 
			
		|||
    [ [ vreg>> ] [ reg>> ] bi ] H{ } map>assoc ;
 | 
			
		||||
 | 
			
		||||
: all-vregs ( insn -- vregs )
 | 
			
		||||
    [ defs-vregs ] [ temp-vregs ] [ uses-vregs ] tri 3append ;
 | 
			
		||||
    [ [ temp-vregs ] [ uses-vregs ] bi append ]
 | 
			
		||||
    [ defs-vreg ] bi
 | 
			
		||||
    [ suffix ] when* ;
 | 
			
		||||
 | 
			
		||||
SYMBOL: check-assignment?
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -98,7 +98,7 @@ M: insn compute-live-intervals* drop ;
 | 
			
		|||
M: vreg-insn compute-live-intervals*
 | 
			
		||||
    dup insn#>>
 | 
			
		||||
    live-intervals get
 | 
			
		||||
    [ [ defs-vregs ] 2dip '[ [ _ ] dip _ handle-output ] each ]
 | 
			
		||||
    [ [ defs-vreg ] 2dip '[ [ _ ] dip _ handle-output ] when* ]
 | 
			
		||||
    [ [ uses-vregs ] 2dip '[ [ _ ] dip _ handle-input ] each ]
 | 
			
		||||
    [ [ temp-vregs ] 2dip '[ [ _ ] dip _ handle-temp ] each ]
 | 
			
		||||
    3tri ;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,7 @@ BACKWARD-ANALYSIS: live
 | 
			
		|||
GENERIC: insn-liveness ( live-set insn -- )
 | 
			
		||||
 | 
			
		||||
: kill-defs ( live-set insn -- live-set )
 | 
			
		||||
    defs-vregs [ over delete-at ] each ;
 | 
			
		||||
    defs-vreg [ over delete-at ] when* ;
 | 
			
		||||
 | 
			
		||||
: gen-uses ( live-set insn -- live-set )
 | 
			
		||||
    dup ##phi? [ drop ] [ uses-vregs [ over conjoin ] each ] if ;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,27 @@ IN: compiler.cfg.ssa.construction
 | 
			
		|||
 | 
			
		||||
<PRIVATE
 | 
			
		||||
 | 
			
		||||
! Maps vregs to sets of basic blocks
 | 
			
		||||
SYMBOL: defs
 | 
			
		||||
 | 
			
		||||
! Set of vregs defined in more than one basic block
 | 
			
		||||
SYMBOL: defs-multi
 | 
			
		||||
 | 
			
		||||
: compute-insn-defs ( bb insn -- )
 | 
			
		||||
    defs-vreg dup [
 | 
			
		||||
        defs get [ conjoin-at ] [ drop ] [ at assoc-size 1 > ] 2tri
 | 
			
		||||
        [ defs-multi get conjoin ] [ drop ] if
 | 
			
		||||
    ] [ 2drop ] if ;
 | 
			
		||||
 | 
			
		||||
: compute-defs ( cfg -- )
 | 
			
		||||
    H{ } clone defs set
 | 
			
		||||
    H{ } clone defs-multi set
 | 
			
		||||
    [
 | 
			
		||||
        dup instructions>> [
 | 
			
		||||
            compute-insn-defs
 | 
			
		||||
        ] with each
 | 
			
		||||
    ] each-basic-block ;
 | 
			
		||||
 | 
			
		||||
! Maps basic blocks to sequences of vregs
 | 
			
		||||
SYMBOL: inserting-phi-nodes
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -36,15 +57,11 @@ SYMBOL: inserting-phi-nodes
 | 
			
		|||
    ] [ 2drop ] if ;
 | 
			
		||||
 | 
			
		||||
: compute-phi-nodes-for ( vreg bbs -- )
 | 
			
		||||
    dup length 2 >= [
 | 
			
		||||
        [
 | 
			
		||||
            insert-phi-node-later
 | 
			
		||||
        ] with merge-set-each
 | 
			
		||||
    ] [ 2drop ] if ;
 | 
			
		||||
    keys [ insert-phi-node-later ] with merge-set-each ;
 | 
			
		||||
 | 
			
		||||
: compute-phi-nodes ( -- )
 | 
			
		||||
    H{ } clone inserting-phi-nodes set
 | 
			
		||||
    defs get [ compute-phi-nodes-for ] assoc-each ;
 | 
			
		||||
    defs-multi get defs get '[ _ at compute-phi-nodes-for ] assoc-each ;
 | 
			
		||||
 | 
			
		||||
: insert-phi-nodes-in ( phis bb -- )
 | 
			
		||||
    [ append ] change-instructions drop ;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@ TUPLE: dom-forest-node vreg bb children ;
 | 
			
		|||
<PRIVATE
 | 
			
		||||
 | 
			
		||||
: sort-vregs-by-bb ( vregs -- alist )
 | 
			
		||||
    defs-1 get
 | 
			
		||||
    defs get
 | 
			
		||||
    '[ dup _ at ] { } map>assoc
 | 
			
		||||
    [ [ second pre-of ] compare ] sort ;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
! Copyright (C) 2009 Slava Pestov.
 | 
			
		||||
! See http://factorcode.org/license.txt for BSD license.
 | 
			
		||||
USING: accessors assocs fry kernel namespaces sequences math
 | 
			
		||||
compiler.cfg.def-use compiler.cfg.instructions
 | 
			
		||||
arrays compiler.cfg.def-use compiler.cfg.instructions
 | 
			
		||||
compiler.cfg.liveness compiler.cfg.rpo ;
 | 
			
		||||
IN: compiler.cfg.ssa.destruction.live-ranges
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -11,8 +11,8 @@ IN: compiler.cfg.ssa.destruction.live-ranges
 | 
			
		|||
 | 
			
		||||
SYMBOLS: local-def-indices local-kill-indices ;
 | 
			
		||||
 | 
			
		||||
: record-defs ( n vregs -- )
 | 
			
		||||
    local-def-indices get '[ _ set-at ] with each ;
 | 
			
		||||
: record-def ( n vregs -- )
 | 
			
		||||
    dup [ local-def-indices get set-at ] [ 2drop ] if ;
 | 
			
		||||
 | 
			
		||||
: record-uses ( n vregs -- )
 | 
			
		||||
    local-kill-indices get '[ _ set-at ] with each ;
 | 
			
		||||
| 
						 | 
				
			
			@ -24,9 +24,9 @@ SYMBOLS: local-def-indices local-kill-indices ;
 | 
			
		|||
    ! this instruction and before the next one, ensuring that outputs
 | 
			
		||||
    ! interfere with inputs.
 | 
			
		||||
    2 *
 | 
			
		||||
    [ swap defs-vregs record-defs ]
 | 
			
		||||
    [ swap defs-vreg record-def ]
 | 
			
		||||
    [ swap uses-vregs record-uses ]
 | 
			
		||||
    [ over def-is-use-insn? [ 1 + swap defs-vregs record-uses ] [ 2drop ] if ]
 | 
			
		||||
    [ over def-is-use-insn? [ 1 + swap defs-vreg 1array record-uses ] [ 2drop ] if ]
 | 
			
		||||
    2tri ;
 | 
			
		||||
 | 
			
		||||
SYMBOLS: def-indices kill-indices ;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue