compiler.cfg.branch-splitting was totally broken

db4
Slava Pestov 2011-02-27 16:43:26 -08:00
parent 609d6f9166
commit 5a3c5c7749
2 changed files with 42 additions and 17 deletions

View File

@ -1,19 +1,20 @@
! Copyright (C) 2009, 2010 Doug Coleman, Slava Pestov. ! Copyright (C) 2009, 2011 Doug Coleman, Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors combinators combinators.short-circuit kernel USING: arrays accessors assocs combinators combinators.short-circuit
locals math math.order sequences assocs namespaces vectors fry dlists deques kernel locals math math.order sequences
arrays splitting compiler.cfg.def-use compiler.cfg sets vectors fry splitting compiler.cfg.def-use compiler.cfg
compiler.cfg.rpo compiler.cfg.predecessors compiler.cfg.renaming compiler.cfg.rpo compiler.cfg.predecessors compiler.cfg.renaming
compiler.cfg.instructions compiler.cfg.utilities ; compiler.cfg.instructions compiler.cfg.utilities ;
FROM: namespaces => get set ;
IN: compiler.cfg.branch-splitting IN: compiler.cfg.branch-splitting
: clone-instructions ( insns -- insns' ) : clone-instructions ( insns -- insns' )
[ clone dup rename-insn-temps ] map ; [ clone dup rename-insn-temps ] map ;
: clone-basic-block ( bb -- bb' ) : clone-basic-block ( bb -- bb' )
! The new block temporarily gets the same RPO number as the old one, ! The new block temporarily gets the same RPO number as the
! until the next time RPO is computed. This is just to make ! old one, until the next time RPO is computed. This is just
! 'back-edge?' work. ! to make 'back-edge?' work.
<basic-block> <basic-block>
swap swap
{ {
@ -25,18 +26,21 @@ IN: compiler.cfg.branch-splitting
: new-blocks ( bb -- copies ) : new-blocks ( bb -- copies )
dup predecessors>> [ dup predecessors>> [
[ clone-basic-block ] dip [ clone-basic-block ] [ 1vector ] bi*
1vector >>predecessors >>predecessors
] with map ; ] with map ;
: update-predecessor-successors ( copies old-bb -- ) : update-predecessor-successors ( copies old-bb -- )
[ predecessors>> swap ] keep [ predecessors>> swap ] keep
'[ [ _ ] 2dip update-predecessors ] 2each ; '[ [ _ ] dip update-successors ] 2each ;
:: update-successor-predecessor ( copies old-bb succ -- ) :: update-successor-predecessor ( copies old-bb succ -- )
succ succ predecessors>> dup >array :> ( preds preds' )
[ { old-bb } split copies join V{ } like ] change-predecessors preds delete-all
drop ; preds' [
dup old-bb eq?
[ drop copies preds push-all ] [ preds push ] if
] each ;
: update-successor-predecessors ( copies old-bb -- ) : update-successor-predecessors ( copies old-bb -- )
dup successors>> dup successors>>
@ -77,11 +81,29 @@ UNION: irrelevant ##peek ##replace ##inc-d ##inc-r ;
] if ] if
] if ; ] if ;
SYMBOL: worklist
SYMBOL: visited
: add-to-worklist ( bb -- )
dup visited get in? [ drop ] [
[ visited get adjoin ]
[ worklist get push-front ] bi
] if ;
: init-worklist ( cfg -- )
<dlist> worklist set
HS{ } clone visited set
entry>> add-to-worklist ;
: split-branches ( cfg -- cfg' ) : split-branches ( cfg -- cfg' )
needs-predecessors needs-predecessors
dup init-worklist
! For back-edge?
dup post-order drop
dup [ worklist get [
dup split-branch? [ split-branch ] [ drop ] if dup split-branch? [ dup split-branch ] when
] each-basic-block successors>> [ add-to-worklist ] each
] slurp-deque
cfg-changed ; cfg-changed ;

View File

@ -221,3 +221,6 @@ IN: compiler.cfg.builder.tests
! Regression. Make sure everything is inlined correctly ! Regression. Make sure everything is inlined correctly
[ f ] [ M\ hashtable set-at [ { [ ##call? ] [ word>> \ set-slot eq? ] } 1&& ] contains-insn? ] unit-test [ f ] [ M\ hashtable set-at [ { [ ##call? ] [ word>> \ set-slot eq? ] } 1&& ] contains-insn? ] unit-test
! Regression. Make sure branch splitting works.
[ 2 ] [ [ 1 2 ? ] [ ##return? ] count-insns ] unit-test