compiler.cfg.stack-analysis: fix another corner case with ##peek insertion, and fix changed-loc merging

db4
Slava Pestov 2009-06-28 22:52:28 -05:00
parent d4de1d38b9
commit 6e72cf9711
3 changed files with 61 additions and 14 deletions

View File

@ -37,25 +37,25 @@ IN: compiler.cfg.stack-analysis.merge
'[ _ untranslate-loc ] assoc-map-values ;
: collect-locs ( loc-maps states -- assoc )
! assoc maps locs to sequences of vregs
! assoc maps locs to sequences
[ untranslate-locs ] 2map
[ [ keys ] map concat prune ] keep
'[ dup _ [ at ] with map ] H{ } map>assoc ;
: insert-peek ( predecessor loc -- vreg )
'[ _ ^^peek ] add-instructions ;
: insert-peek ( predecessor loc state -- vreg )
'[ _ _ translate-loc ^^peek ] add-instructions ;
: merge-loc ( predecessors vregs loc -- vreg )
: merge-loc ( predecessors vregs loc state -- vreg )
! Insert a ##phi in the current block where the input
! is the vreg storing loc from each predecessor block
'[ [ ] [ _ insert-peek ] ?if ] 2map
'[ [ ] [ _ _ insert-peek ] ?if ] 2map
dup all-equal? [ first ] [ ^^phi ] if ;
:: merge-locs ( state predecessors states -- state )
states [ locs>vregs>> ] map states collect-locs
[| key value |
key
predecessors value key merge-loc
predecessors value key state merge-loc
] assoc-map
state translate-locs
state (>>locs>vregs)
@ -64,14 +64,17 @@ IN: compiler.cfg.stack-analysis.merge
: merge-actual-loc ( vregs -- vreg/f )
dup all-equal? [ first ] [ drop f ] if ;
: merge-actual-locs ( state states -- state )
[ [ actual-locs>vregs>> ] map ] keep collect-locs
:: merge-actual-locs ( state states -- state )
states [ actual-locs>vregs>> ] map states collect-locs
[ merge-actual-loc ] assoc-map [ nip ] assoc-filter
over translate-locs
>>actual-locs>vregs ;
state translate-locs
state (>>actual-locs>vregs)
state ;
: merge-changed-locs ( state states -- state )
[ changed-locs>> ] map assoc-combine >>changed-locs ;
[ [ changed-locs>> ] keep untranslate-locs ] map assoc-combine
over translate-locs
>>changed-locs ;
ERROR: cannot-merge-poisoned states ;

View File

@ -158,5 +158,49 @@ local-only? off
stack-analysis
drop
3 get instructions>> [ ##peek? ] find nip loc>>
] unit-test
! Missing ##replace
[ t ] [
[ 0 2over dup not [ [ /mod ] dip ] when ] test-stack-analysis
reverse-post-order last
instructions>> [ ##replace? ] filter [ loc>> ] map
{ D 0 D 1 D 2 } set=
] unit-test
! Inserted ##peeks reference the wrong stack location
[ t ] [
[ [ "B" ] 2dip dup [ [ /mod ] dip ] when ] test-stack-analysis
eliminate-dead-code reverse-post-order 3 swap nth
instructions>> [ ##peek? ] filter [ loc>> ] map
{ D 1 D 2 } set=
] unit-test
[ D 0 ] [
V{ T{ ##branch } } 0 test-bb
V{ T{ ##branch } } 1 test-bb
V{
T{ ##peek f V int-regs 1 D 0 }
T{ ##inc-d f 1 }
T{ ##branch }
} 2 test-bb
V{
T{ ##inc-d f 1 }
T{ ##branch }
} 3 test-bb
V{ T{ ##return } } 4 test-bb
test-diamond
cfg new 0 get >>entry
compute-predecessors
stack-analysis
drop
3 get instructions>> [ ##peek? ] find nip loc>>
] unit-test

View File

@ -18,10 +18,10 @@ IN: compiler.cfg.stack-analysis
[ 2drop t ] [ state get actual-locs>vregs>> at = ] if ;
: save-changed-locs ( state -- )
[ changed-locs>> ] [ locs>vregs>> ] bi '[
_ at swap 2dup redundant-replace?
[ changed-locs>> keys ] [ locs>vregs>> ] bi '[
dup _ at swap 2dup redundant-replace?
[ 2drop ] [ state get untranslate-loc ##replace ] if
] assoc-each ;
] each ;
ERROR: poisoned-state state ;