compiler.cfg.coalescing: Only run if CFG has ##phi nodes, fix interference for case where value is not used in a block and is not live-in, forgot to run liveness analysis first
							parent
							
								
									cb07256ff5
								
							
						
					
					
						commit
						a4cb242396
					
				| 
						 | 
					@ -7,6 +7,7 @@ compiler.cfg.def-use
 | 
				
			||||||
compiler.cfg.utilities
 | 
					compiler.cfg.utilities
 | 
				
			||||||
compiler.cfg.dominance
 | 
					compiler.cfg.dominance
 | 
				
			||||||
compiler.cfg.instructions
 | 
					compiler.cfg.instructions
 | 
				
			||||||
 | 
					compiler.cfg.liveness.ssa
 | 
				
			||||||
compiler.cfg.critical-edges
 | 
					compiler.cfg.critical-edges
 | 
				
			||||||
compiler.cfg.coalescing.state
 | 
					compiler.cfg.coalescing.state
 | 
				
			||||||
compiler.cfg.coalescing.forest
 | 
					compiler.cfg.coalescing.forest
 | 
				
			||||||
| 
						 | 
					@ -36,10 +37,7 @@ SYMBOL: seen
 | 
				
			||||||
    V{ } clone seen set
 | 
					    V{ } clone seen set
 | 
				
			||||||
    renaming-sets get [| dst assoc |
 | 
					    renaming-sets get [| dst assoc |
 | 
				
			||||||
        assoc [| src bb |
 | 
					        assoc [| src bb |
 | 
				
			||||||
            src seen get key?
 | 
					            dst assoc src bb visit-renaming
 | 
				
			||||||
            [ dst assoc src bb visit-renaming ]
 | 
					 | 
				
			||||||
            [ src seen get conjoin ]
 | 
					 | 
				
			||||||
            if
 | 
					 | 
				
			||||||
        ] assoc-each
 | 
					        ] assoc-each
 | 
				
			||||||
    ] assoc-each ;
 | 
					    ] assoc-each ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,14 +48,17 @@ SYMBOL: seen
 | 
				
			||||||
    [ [ remove-phis-from-block ] if-has-phis ] each-basic-block ;
 | 
					    [ [ remove-phis-from-block ] if-has-phis ] each-basic-block ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: coalesce ( cfg -- cfg' )
 | 
					: coalesce ( cfg -- cfg' )
 | 
				
			||||||
    init-coalescing
 | 
					    dup cfg-has-phis? [
 | 
				
			||||||
    dup split-critical-edges
 | 
					        init-coalescing
 | 
				
			||||||
    dup compute-def-use
 | 
					        compute-ssa-live-sets
 | 
				
			||||||
    dup compute-dominance
 | 
					        dup split-critical-edges
 | 
				
			||||||
    dup compute-dfs
 | 
					        dup compute-def-use
 | 
				
			||||||
    dup compute-live-ranges
 | 
					        dup compute-dominance
 | 
				
			||||||
    dup process-blocks
 | 
					        dup compute-dfs
 | 
				
			||||||
    break-interferences
 | 
					        dup compute-live-ranges
 | 
				
			||||||
    dup perform-renaming
 | 
					        dup process-blocks
 | 
				
			||||||
    insert-copies
 | 
					        break-interferences
 | 
				
			||||||
    dup remove-phis ;
 | 
					        dup perform-renaming
 | 
				
			||||||
 | 
					        insert-copies
 | 
				
			||||||
 | 
					        dup remove-phis
 | 
				
			||||||
 | 
					    ] when ;
 | 
				
			||||||
| 
						 | 
					@ -8,8 +8,12 @@ IN: compiler.cfg.coalescing.interference
 | 
				
			||||||
<PRIVATE
 | 
					<PRIVATE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: kill-after-def? ( vreg1 vreg2 bb -- ? )
 | 
					: kill-after-def? ( vreg1 vreg2 bb -- ? )
 | 
				
			||||||
    ! If first register is killed after second one is defined, they interfere
 | 
					    ! If first register is used after second one is defined, they interfere.
 | 
				
			||||||
    [ kill-index ] [ def-index ] bi-curry bi* >= ;
 | 
					    ! If they are used in the same instruction, no interference. If the
 | 
				
			||||||
 | 
					    ! instruction is a def-is-use-insn, then there will be a use at +1
 | 
				
			||||||
 | 
					    ! (instructions are 2 apart) and so outputs will interfere with
 | 
				
			||||||
 | 
					    ! inputs.
 | 
				
			||||||
 | 
					    [ kill-index ] [ def-index ] bi-curry bi* > ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: interferes-same-block? ( vreg1 vreg2 bb1 bb2 -- ? )
 | 
					: interferes-same-block? ( vreg1 vreg2 bb1 bb2 -- ? )
 | 
				
			||||||
    ! If both are defined in the same basic block, they interfere if their
 | 
					    ! If both are defined in the same basic block, they interfere if their
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
! 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: accessors assocs fry kernel namespaces sequences
 | 
					USING: accessors assocs fry kernel namespaces sequences math
 | 
				
			||||||
compiler.cfg.def-use compiler.cfg.instructions
 | 
					compiler.cfg.def-use compiler.cfg.instructions
 | 
				
			||||||
compiler.cfg.liveness compiler.cfg.rpo ;
 | 
					compiler.cfg.liveness compiler.cfg.rpo ;
 | 
				
			||||||
IN: compiler.cfg.coalescing.live-ranges
 | 
					IN: compiler.cfg.coalescing.live-ranges
 | 
				
			||||||
| 
						 | 
					@ -18,9 +18,15 @@ SYMBOLS: local-def-indices local-kill-indices ;
 | 
				
			||||||
    local-kill-indices get '[ _ set-at ] with each ;
 | 
					    local-kill-indices get '[ _ set-at ] with each ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: visit-insn ( insn n -- )
 | 
					: visit-insn ( insn n -- )
 | 
				
			||||||
 | 
					    ! Instructions are numbered 2 apart. If the instruction requires
 | 
				
			||||||
 | 
					    ! that outputs are in different registers than the inputs, then
 | 
				
			||||||
 | 
					    ! a use will be registered for every output immediately after
 | 
				
			||||||
 | 
					    ! this instruction and before the next one, ensuring that outputs
 | 
				
			||||||
 | 
					    ! interfere with inputs.
 | 
				
			||||||
 | 
					    2 *
 | 
				
			||||||
    [ swap defs-vregs record-defs ]
 | 
					    [ swap defs-vregs record-defs ]
 | 
				
			||||||
    [ swap uses-vregs record-uses ]
 | 
					    [ swap uses-vregs record-uses ]
 | 
				
			||||||
    [ over def-is-use-insn? [ swap defs-vregs record-uses ] [ 2drop ] if ]
 | 
					    [ over def-is-use-insn? [ 1 + swap defs-vregs record-uses ] [ 2drop ] if ]
 | 
				
			||||||
    2tri ;
 | 
					    2tri ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SYMBOLS: def-indices kill-indices ;
 | 
					SYMBOLS: def-indices kill-indices ;
 | 
				
			||||||
| 
						 | 
					@ -28,15 +34,27 @@ SYMBOLS: def-indices kill-indices ;
 | 
				
			||||||
: compute-local-live-ranges ( bb -- )
 | 
					: compute-local-live-ranges ( bb -- )
 | 
				
			||||||
    H{ } clone local-def-indices set
 | 
					    H{ } clone local-def-indices set
 | 
				
			||||||
    H{ } clone local-kill-indices set
 | 
					    H{ } clone local-kill-indices set
 | 
				
			||||||
    instructions>> [ visit-insn ] each-index ;
 | 
					    [ instructions>> [ visit-insn ] each-index ]
 | 
				
			||||||
 | 
					    [ [ local-def-indices get ] dip def-indices get set-at ]
 | 
				
			||||||
 | 
					    [ [ local-kill-indices get ] dip kill-indices get set-at ]
 | 
				
			||||||
 | 
					    tri ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PRIVATE>
 | 
					PRIVATE>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: compute-live-ranges ( cfg -- )
 | 
					: compute-live-ranges ( cfg -- )
 | 
				
			||||||
 | 
					    H{ } clone def-indices set
 | 
				
			||||||
 | 
					    H{ } clone kill-indices set
 | 
				
			||||||
    [ compute-local-live-ranges ] each-basic-block ;
 | 
					    [ compute-local-live-ranges ] each-basic-block ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: def-index ( vreg bb -- n )
 | 
					: def-index ( vreg bb -- n )
 | 
				
			||||||
    def-indices get at at ;
 | 
					    def-indices get at at ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ERROR: bad-kill-index vreg bb ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: kill-index ( vreg bb -- n )
 | 
					: kill-index ( vreg bb -- n )
 | 
				
			||||||
    2dup live-out key? [ 2drop 1/0. ] [ kill-indices get at at ] if ;
 | 
					    2dup live-out key? [ 2drop 1/0. ] [
 | 
				
			||||||
 | 
					        2dup kill-indices get at at* [ 2nip ] [
 | 
				
			||||||
 | 
					            drop 2dup live-in key?
 | 
				
			||||||
 | 
					            [ bad-kill-index ] [ 2drop -1/0. ] if
 | 
				
			||||||
 | 
					        ] if
 | 
				
			||||||
 | 
					    ] if ;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,5 +48,8 @@ SYMBOL: visited
 | 
				
			||||||
: has-phis? ( bb -- ? )
 | 
					: has-phis? ( bb -- ? )
 | 
				
			||||||
    instructions>> first ##phi? ;
 | 
					    instructions>> first ##phi? ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: cfg-has-phis? ( cfg -- )
 | 
				
			||||||
 | 
					    post-order [ has-phis? ] any? ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: if-has-phis ( bb quot: ( bb -- ) -- )
 | 
					: if-has-phis ( bb quot: ( bb -- ) -- )
 | 
				
			||||||
    [ dup has-phis? ] dip [ drop ] if ; inline
 | 
					    [ dup has-phis? ] dip [ drop ] if ; inline
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue