compiler.cfg: if a block has an instruction that kills values it must be the only instruction in the block
							parent
							
								
									0a95ddd105
								
							
						
					
					
						commit
						fdef772d67
					
				| 
						 | 
					@ -8,20 +8,14 @@ IN: compiler.cfg.block-joining
 | 
				
			||||||
! Joining blocks that are not calls and are connected by a single CFG edge.
 | 
					! Joining blocks that are not calls and are connected by a single CFG edge.
 | 
				
			||||||
! Predecessors must be recomputed after this. Also this pass does not
 | 
					! Predecessors must be recomputed after this. Also this pass does not
 | 
				
			||||||
! update ##phi nodes and should therefore only run before stack analysis.
 | 
					! update ##phi nodes and should therefore only run before stack analysis.
 | 
				
			||||||
 | 
					 | 
				
			||||||
: kill-vreg-block? ( bb -- ? )
 | 
					 | 
				
			||||||
    instructions>> {
 | 
					 | 
				
			||||||
        [ length 2 >= ]
 | 
					 | 
				
			||||||
        [ penultimate kill-vreg-insn? ]
 | 
					 | 
				
			||||||
    } 1&& ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: predecessor ( bb -- pred )
 | 
					: predecessor ( bb -- pred )
 | 
				
			||||||
    predecessors>> first ; inline
 | 
					    predecessors>> first ; inline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: join-block? ( bb -- ? )
 | 
					: join-block? ( bb -- ? )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        [ kill-block? not ]
 | 
				
			||||||
        [ predecessors>> length 1 = ]
 | 
					        [ predecessors>> length 1 = ]
 | 
				
			||||||
        [ predecessor kill-vreg-block? not ]
 | 
					        [ predecessor kill-block? not ]
 | 
				
			||||||
        [ predecessor successors>> length 1 = ]
 | 
					        [ predecessor successors>> length 1 = ]
 | 
				
			||||||
        [ [ predecessor ] keep back-edge? not ]
 | 
					        [ [ predecessor ] keep back-edge? not ]
 | 
				
			||||||
    } 1&& ;
 | 
					    } 1&& ;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,10 +13,16 @@ SYMBOL: spill-counts
 | 
				
			||||||
GENERIC: compute-stack-frame* ( insn -- )
 | 
					GENERIC: compute-stack-frame* ( insn -- )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: request-stack-frame ( stack-frame -- )
 | 
					: request-stack-frame ( stack-frame -- )
 | 
				
			||||||
 | 
					    frame-required? on
 | 
				
			||||||
    stack-frame [ max-stack-frame ] change ;
 | 
					    stack-frame [ max-stack-frame ] change ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
M: ##stack-frame compute-stack-frame*
 | 
					M: ##alien-invoke compute-stack-frame*
 | 
				
			||||||
    frame-required? on
 | 
					    stack-frame>> request-stack-frame ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					M: ##alien-indirect compute-stack-frame*
 | 
				
			||||||
 | 
					    stack-frame>> request-stack-frame ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					M: ##alien-callback compute-stack-frame*
 | 
				
			||||||
    stack-frame>> request-stack-frame ;
 | 
					    stack-frame>> request-stack-frame ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
M: ##call compute-stack-frame*
 | 
					M: ##call compute-stack-frame*
 | 
				
			||||||
| 
						 | 
					@ -45,8 +51,6 @@ M: insn compute-stack-frame*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GENERIC: insert-pro/epilogues* ( insn -- )
 | 
					GENERIC: insert-pro/epilogues* ( insn -- )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
M: ##stack-frame insert-pro/epilogues* drop ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
M: ##prologue insert-pro/epilogues*
 | 
					M: ##prologue insert-pro/epilogues*
 | 
				
			||||||
    drop frame-required? get [ stack-frame get _prologue ] when ;
 | 
					    drop frame-required? get [ stack-frame get _prologue ] when ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,12 +1,13 @@
 | 
				
			||||||
IN: compiler.cfg.builder.tests
 | 
					IN: compiler.cfg.builder.tests
 | 
				
			||||||
USING: tools.test kernel sequences
 | 
					USING: tools.test kernel sequences words sequences.private fry
 | 
				
			||||||
words sequences.private fry prettyprint alien alien.accessors
 | 
					prettyprint alien alien.accessors math.private compiler.tree.builder
 | 
				
			||||||
math.private compiler.tree.builder compiler.tree.optimizer
 | 
					compiler.tree.optimizer compiler.cfg.builder compiler.cfg.debugger
 | 
				
			||||||
compiler.cfg.builder compiler.cfg.debugger arrays locals byte-arrays
 | 
					compiler.cfg.predecessors compiler.cfg.checker arrays locals
 | 
				
			||||||
kernel.private math ;
 | 
					byte-arrays kernel.private math slots.private ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
! Just ensure that various CFGs build correctly.
 | 
					! Just ensure that various CFGs build correctly.
 | 
				
			||||||
: unit-test-cfg ( quot -- ) '[ _ test-cfg drop ] [ ] swap unit-test ;
 | 
					: unit-test-cfg ( quot -- )
 | 
				
			||||||
 | 
					    '[ _ test-cfg [ compute-predecessors check-cfg ] each ] [ ] swap unit-test ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    [ ]
 | 
					    [ ]
 | 
				
			||||||
| 
						 | 
					@ -49,6 +50,8 @@ kernel.private math ;
 | 
				
			||||||
    [ "int" f "malloc" { "int" } alien-invoke ]
 | 
					    [ "int" f "malloc" { "int" } alien-invoke ]
 | 
				
			||||||
    [ "int" { "int" } "cdecl" alien-indirect ]
 | 
					    [ "int" { "int" } "cdecl" alien-indirect ]
 | 
				
			||||||
    [ "int" { "int" } "cdecl" [ ] alien-callback ]
 | 
					    [ "int" { "int" } "cdecl" [ ] alien-callback ]
 | 
				
			||||||
 | 
					    [ swap - + * ]
 | 
				
			||||||
 | 
					    [ swap slot ]
 | 
				
			||||||
} [
 | 
					} [
 | 
				
			||||||
    unit-test-cfg
 | 
					    unit-test-cfg
 | 
				
			||||||
] each
 | 
					] each
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,10 +63,15 @@ GENERIC: emit-node ( node -- )
 | 
				
			||||||
    basic-block get successors>> push
 | 
					    basic-block get successors>> push
 | 
				
			||||||
    basic-block off ;
 | 
					    basic-block off ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: emit-trivial-block ( quot -- )
 | 
				
			||||||
 | 
					    basic-block get instructions>> empty? [ ##branch begin-basic-block ] unless
 | 
				
			||||||
 | 
					    call
 | 
				
			||||||
 | 
					    ##branch begin-basic-block ; inline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: emit-call ( word height -- )
 | 
					: emit-call ( word height -- )
 | 
				
			||||||
    over loops get key?
 | 
					    over loops get key?
 | 
				
			||||||
    [ drop loops get at emit-loop-call ]
 | 
					    [ drop loops get at emit-loop-call ]
 | 
				
			||||||
    [ ##call ##branch begin-basic-block ]
 | 
					    [ [ ##call ] emit-trivial-block ]
 | 
				
			||||||
    if ;
 | 
					    if ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
! #recursive
 | 
					! #recursive
 | 
				
			||||||
| 
						 | 
					@ -157,7 +162,7 @@ M: #shuffle emit-node
 | 
				
			||||||
 | 
					
 | 
				
			||||||
! #return
 | 
					! #return
 | 
				
			||||||
M: #return emit-node
 | 
					M: #return emit-node
 | 
				
			||||||
    drop ##epilogue ##return ;
 | 
					    drop ##branch begin-basic-block ##epilogue ##return ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
M: #return-recursive emit-node
 | 
					M: #return-recursive emit-node
 | 
				
			||||||
    label>> id>> loops get key?
 | 
					    label>> id>> loops get key?
 | 
				
			||||||
| 
						 | 
					@ -181,12 +186,10 @@ M: #terminate emit-node drop ##no-tco basic-block off ;
 | 
				
			||||||
        [ return>> return-size >>return ]
 | 
					        [ return>> return-size >>return ]
 | 
				
			||||||
        [ alien-parameters parameter-sizes drop >>params ] bi ;
 | 
					        [ alien-parameters parameter-sizes drop >>params ] bi ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: alien-stack-frame ( params -- )
 | 
					 | 
				
			||||||
    <alien-stack-frame> ##stack-frame ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: emit-alien-node ( node quot -- )
 | 
					: emit-alien-node ( node quot -- )
 | 
				
			||||||
    [ params>> ] dip [ drop alien-stack-frame ] [ call ] 2bi
 | 
					    [
 | 
				
			||||||
    ##branch begin-basic-block ; inline
 | 
					        [ params>> dup <alien-stack-frame> ] dip call
 | 
				
			||||||
 | 
					    ] emit-trivial-block ; inline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
M: #alien-invoke emit-node
 | 
					M: #alien-invoke emit-node
 | 
				
			||||||
    [ ##alien-invoke ] emit-alien-node ;
 | 
					    [ ##alien-invoke ] emit-alien-node ;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,34 +1,51 @@
 | 
				
			||||||
! 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: kernel compiler.cfg.instructions compiler.cfg.rpo
 | 
					USING: kernel combinators.short-circuit accessors math sequences sets
 | 
				
			||||||
compiler.cfg.def-use compiler.cfg.linearization compiler.cfg.liveness
 | 
					assocs compiler.cfg.instructions compiler.cfg.rpo compiler.cfg.def-use
 | 
				
			||||||
combinators.short-circuit accessors math sequences sets assocs ;
 | 
					compiler.cfg.linearization compiler.cfg.liveness
 | 
				
			||||||
 | 
					compiler.cfg.utilities ;
 | 
				
			||||||
IN: compiler.cfg.checker
 | 
					IN: compiler.cfg.checker
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ERROR: last-insn-not-a-jump insn ;
 | 
					ERROR: bad-kill-block bb ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: check-kill-block ( bb -- )
 | 
				
			||||||
 | 
					    dup instructions>> first2
 | 
				
			||||||
 | 
					    swap ##epilogue? [ [ ##return? ] [ ##callback-return? ] bi or ] [ ##branch? ] if
 | 
				
			||||||
 | 
					    [ drop ] [ bad-kill-block ] if ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ERROR: last-insn-not-a-jump bb ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: check-last-instruction ( bb -- )
 | 
					: check-last-instruction ( bb -- )
 | 
				
			||||||
    last dup {
 | 
					    dup instructions>> last {
 | 
				
			||||||
        [ ##branch? ]
 | 
					        [ ##branch? ]
 | 
				
			||||||
        [ ##dispatch? ]
 | 
					        [ ##dispatch? ]
 | 
				
			||||||
        [ ##conditional-branch? ]
 | 
					        [ ##conditional-branch? ]
 | 
				
			||||||
        [ ##compare-imm-branch? ]
 | 
					        [ ##compare-imm-branch? ]
 | 
				
			||||||
        [ ##return? ]
 | 
					 | 
				
			||||||
        [ ##callback-return? ]
 | 
					 | 
				
			||||||
        [ ##jump? ]
 | 
					 | 
				
			||||||
        [ ##fixnum-add? ]
 | 
					        [ ##fixnum-add? ]
 | 
				
			||||||
        [ ##fixnum-sub? ]
 | 
					        [ ##fixnum-sub? ]
 | 
				
			||||||
        [ ##fixnum-mul? ]
 | 
					        [ ##fixnum-mul? ]
 | 
				
			||||||
        [ ##no-tco? ]
 | 
					        [ ##no-tco? ]
 | 
				
			||||||
    } 1|| [ drop ] [ last-insn-not-a-jump ] if ;
 | 
					    } 1|| [ drop ] [ last-insn-not-a-jump ] if ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ERROR: bad-loop-entry ;
 | 
					ERROR: bad-loop-entry bb ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: check-loop-entry ( bb -- )
 | 
					: check-loop-entry ( bb -- )
 | 
				
			||||||
    dup length 2 >= [
 | 
					    dup instructions>> dup length 2 >= [
 | 
				
			||||||
        2 head* [ ##loop-entry? ] any?
 | 
					        2 head* [ ##loop-entry? ] any?
 | 
				
			||||||
        [ bad-loop-entry ] when
 | 
					        [ bad-loop-entry ] [ drop ] if
 | 
				
			||||||
    ] [ drop ] if ;
 | 
					    ] [ 2drop ] if ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ERROR: bad-kill-insn bb ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: check-kill-instructions ( bb -- )
 | 
				
			||||||
 | 
					    dup instructions>> [ kill-vreg-insn? ] any?
 | 
				
			||||||
 | 
					    [ bad-kill-insn ] [ drop ] if ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: check-normal-block ( bb -- )
 | 
				
			||||||
 | 
					    [ check-loop-entry ]
 | 
				
			||||||
 | 
					    [ check-last-instruction ]
 | 
				
			||||||
 | 
					    [ check-kill-instructions ]
 | 
				
			||||||
 | 
					    tri ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ERROR: bad-successors ;
 | 
					ERROR: bad-successors ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,10 +54,9 @@ ERROR: bad-successors ;
 | 
				
			||||||
    [ bad-successors ] unless ;
 | 
					    [ bad-successors ] unless ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: check-basic-block ( bb -- )
 | 
					: check-basic-block ( bb -- )
 | 
				
			||||||
    [ instructions>> check-last-instruction ]
 | 
					    [ dup kill-block? [ check-kill-block ] [ check-normal-block ] if ]
 | 
				
			||||||
    [ instructions>> check-loop-entry ]
 | 
					 | 
				
			||||||
    [ check-successors ]
 | 
					    [ check-successors ]
 | 
				
			||||||
    tri ;
 | 
					    bi ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ERROR: bad-live-in ;
 | 
					ERROR: bad-live-in ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,7 @@ IN: compiler.cfg.dcn.tests
 | 
				
			||||||
USING: tools.test kernel accessors namespaces assocs
 | 
					USING: tools.test kernel accessors namespaces assocs
 | 
				
			||||||
cpu.architecture vectors sequences
 | 
					cpu.architecture vectors sequences
 | 
				
			||||||
compiler.cfg
 | 
					compiler.cfg
 | 
				
			||||||
 | 
					compiler.cfg.utilities
 | 
				
			||||||
compiler.cfg.debugger
 | 
					compiler.cfg.debugger
 | 
				
			||||||
compiler.cfg.registers
 | 
					compiler.cfg.registers
 | 
				
			||||||
compiler.cfg.predecessors
 | 
					compiler.cfg.predecessors
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@ GENERIC: uses-vregs ( insn -- seq )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
M: ##flushable defs-vregs dst>> 1array ;
 | 
					M: ##flushable defs-vregs dst>> 1array ;
 | 
				
			||||||
M: ##fixnum-overflow 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: insn defs-vregs drop f ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
M: ##write-barrier temp-vregs [ card#>> ] [ table>> ] bi 2array ;
 | 
					M: ##write-barrier temp-vregs [ card#>> ] [ table>> ] bi 2array ;
 | 
				
			||||||
| 
						 | 
					@ -47,18 +48,3 @@ M: _conditional-branch uses-vregs [ src1>> ] [ src2>> ] bi 2array ;
 | 
				
			||||||
M: _compare-imm-branch uses-vregs src1>> 1array ;
 | 
					M: _compare-imm-branch uses-vregs src1>> 1array ;
 | 
				
			||||||
M: _dispatch uses-vregs src>> 1array ;
 | 
					M: _dispatch uses-vregs src>> 1array ;
 | 
				
			||||||
M: insn uses-vregs drop f ;
 | 
					M: insn uses-vregs drop f ;
 | 
				
			||||||
 | 
					 | 
				
			||||||
! Instructions that use vregs
 | 
					 | 
				
			||||||
UNION: vreg-insn
 | 
					 | 
				
			||||||
##flushable
 | 
					 | 
				
			||||||
##write-barrier
 | 
					 | 
				
			||||||
##dispatch
 | 
					 | 
				
			||||||
##effect
 | 
					 | 
				
			||||||
##fixnum-overflow
 | 
					 | 
				
			||||||
##conditional-branch
 | 
					 | 
				
			||||||
##compare-imm-branch
 | 
					 | 
				
			||||||
##phi
 | 
					 | 
				
			||||||
##gc
 | 
					 | 
				
			||||||
_conditional-branch
 | 
					 | 
				
			||||||
_compare-imm-branch
 | 
					 | 
				
			||||||
_dispatch ;
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,7 +52,6 @@ INSN: ##inc-d { n integer } ;
 | 
				
			||||||
INSN: ##inc-r { n integer } ;
 | 
					INSN: ##inc-r { n integer } ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
! Subroutine calls
 | 
					! Subroutine calls
 | 
				
			||||||
INSN: ##stack-frame stack-frame ;
 | 
					 | 
				
			||||||
INSN: ##call word { height integer } ;
 | 
					INSN: ##call word { height integer } ;
 | 
				
			||||||
INSN: ##jump word ;
 | 
					INSN: ##jump word ;
 | 
				
			||||||
INSN: ##return ;
 | 
					INSN: ##return ;
 | 
				
			||||||
| 
						 | 
					@ -160,9 +159,9 @@ INSN: ##write-barrier < ##effect card# table ;
 | 
				
			||||||
INSN: ##alien-global < ##flushable symbol library ;
 | 
					INSN: ##alien-global < ##flushable symbol library ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
! FFI
 | 
					! FFI
 | 
				
			||||||
INSN: ##alien-invoke params ;
 | 
					INSN: ##alien-invoke params stack-frame ;
 | 
				
			||||||
INSN: ##alien-indirect params ;
 | 
					INSN: ##alien-indirect params stack-frame ;
 | 
				
			||||||
INSN: ##alien-callback params ;
 | 
					INSN: ##alien-callback params stack-frame ;
 | 
				
			||||||
INSN: ##callback-return params ;
 | 
					INSN: ##callback-return params ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
! Instructions used by CFG IR only.
 | 
					! Instructions used by CFG IR only.
 | 
				
			||||||
| 
						 | 
					@ -230,16 +229,23 @@ INSN: _reload dst class n ;
 | 
				
			||||||
INSN: _copy dst src class ;
 | 
					INSN: _copy dst src class ;
 | 
				
			||||||
INSN: _spill-counts counts ;
 | 
					INSN: _spill-counts counts ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
! Instructions that poison the stack state
 | 
					! Instructions that use vregs
 | 
				
			||||||
UNION: poison-insn
 | 
					UNION: vreg-insn
 | 
				
			||||||
    ##jump
 | 
					    ##flushable
 | 
				
			||||||
    ##return
 | 
					    ##write-barrier
 | 
				
			||||||
    ##callback-return ;
 | 
					    ##dispatch
 | 
				
			||||||
 | 
					    ##effect
 | 
				
			||||||
 | 
					    ##fixnum-overflow
 | 
				
			||||||
 | 
					    ##conditional-branch
 | 
				
			||||||
 | 
					    ##compare-imm-branch
 | 
				
			||||||
 | 
					    ##phi
 | 
				
			||||||
 | 
					    ##gc
 | 
				
			||||||
 | 
					    _conditional-branch
 | 
				
			||||||
 | 
					    _compare-imm-branch
 | 
				
			||||||
 | 
					    _dispatch ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
! Instructions that kill all live vregs
 | 
					! Instructions that kill all live vregs
 | 
				
			||||||
UNION: kill-vreg-insn
 | 
					UNION: kill-vreg-insn
 | 
				
			||||||
    poison-insn
 | 
					 | 
				
			||||||
    ##stack-frame
 | 
					 | 
				
			||||||
    ##call
 | 
					    ##call
 | 
				
			||||||
    ##prologue
 | 
					    ##prologue
 | 
				
			||||||
    ##epilogue
 | 
					    ##epilogue
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,19 +26,14 @@ SYMBOL: global-optimization?
 | 
				
			||||||
        [ 2drop ] [ state get untranslate-loc ##replace ] if
 | 
					        [ 2drop ] [ state get untranslate-loc ##replace ] if
 | 
				
			||||||
    ] each ;
 | 
					    ] each ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ERROR: poisoned-state state ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: sync-state ( -- )
 | 
					: sync-state ( -- )
 | 
				
			||||||
    state get {
 | 
					    state get {
 | 
				
			||||||
        [ dup poisoned?>> [ poisoned-state ] [ drop ] if ]
 | 
					 | 
				
			||||||
        [ ds-height>> save-ds-height ]
 | 
					        [ ds-height>> save-ds-height ]
 | 
				
			||||||
        [ rs-height>> save-rs-height ]
 | 
					        [ rs-height>> save-rs-height ]
 | 
				
			||||||
        [ save-changed-locs ]
 | 
					        [ save-changed-locs ]
 | 
				
			||||||
        [ clear-state ]
 | 
					        [ clear-state ]
 | 
				
			||||||
    } cleave ;
 | 
					    } cleave ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: poison-state ( -- ) state get t >>poisoned? drop ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
! Abstract interpretation
 | 
					! Abstract interpretation
 | 
				
			||||||
GENERIC: visit ( insn -- )
 | 
					GENERIC: visit ( insn -- )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,7 +82,11 @@ M: ##replace visit
 | 
				
			||||||
M: ##copy visit
 | 
					M: ##copy visit
 | 
				
			||||||
    [ call-next-method ] [ record-copy ] bi ;
 | 
					    [ call-next-method ] [ record-copy ] bi ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
M: poison-insn visit call-next-method poison-state ;
 | 
					M: ##jump visit sync-state , ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					M: ##return visit sync-state , ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					M: ##callback-return visit sync-state , ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
M: kill-vreg-insn visit sync-state , ;
 | 
					M: kill-vreg-insn visit sync-state , ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,11 +33,16 @@ IN: compiler.cfg.utilities
 | 
				
			||||||
    building off
 | 
					    building off
 | 
				
			||||||
    basic-block off ;
 | 
					    basic-block off ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: emit-trivial-block ( quot -- )
 | 
				
			||||||
 | 
					    basic-block get instructions>> empty? [ ##branch begin-basic-block ] unless
 | 
				
			||||||
 | 
					    call
 | 
				
			||||||
 | 
					    ##branch begin-basic-block ; inline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: call-height ( #call -- n )
 | 
					: call-height ( #call -- n )
 | 
				
			||||||
    [ out-d>> length ] [ in-d>> length ] bi - ;
 | 
					    [ out-d>> length ] [ in-d>> length ] bi - ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: emit-primitive ( node -- )
 | 
					: emit-primitive ( node -- )
 | 
				
			||||||
    [ word>> ] [ call-height ] bi ##call ##branch begin-basic-block ;
 | 
					    [ [ word>> ] [ call-height ] bi ##call ] emit-trivial-block ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: with-branch ( quot -- final-bb )
 | 
					: with-branch ( quot -- final-bb )
 | 
				
			||||||
    [
 | 
					    [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue