CFG checker now checks consistency of successors and predecessors lists; fix long-standing bug in useless-blocks optimization

db4
Slava Pestov 2009-05-28 02:49:51 -05:00
parent 1fa465d77f
commit ecece1d08b
3 changed files with 46 additions and 16 deletions

View File

@ -1,8 +1,8 @@
! 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 compiler.cfg.def-use USING: kernel compiler.cfg.instructions compiler.cfg.rpo
compiler.cfg.linearization combinators.short-circuit accessors math compiler.cfg.def-use compiler.cfg.linearization compiler.cfg.liveness
sequences sets ; combinators.short-circuit accessors math sequences sets assocs ;
IN: compiler.cfg.checker IN: compiler.cfg.checker
ERROR: last-insn-not-a-jump insn ; ERROR: last-insn-not-a-jump insn ;
@ -27,11 +27,25 @@ ERROR: bad-loop-entry ;
[ bad-loop-entry ] when [ bad-loop-entry ] when
] [ drop ] if ; ] [ drop ] if ;
ERROR: bad-successors ;
: check-successors ( bb -- )
dup successors>> [ predecessors>> memq? ] with all?
[ bad-successors ] unless ;
: check-basic-block ( bb -- ) : check-basic-block ( bb -- )
[ check-last-instruction ] [ check-loop-entry ] bi ; [ instructions>> check-last-instruction ]
[ instructions>> check-loop-entry ]
[ check-successors ]
tri ;
ERROR: bad-live-in ;
: check-rpo ( rpo -- ) : check-rpo ( rpo -- )
[ instructions>> check-basic-block ] each ; [ compute-liveness ]
[ first live-in assoc-empty? [ bad-live-in ] unless ]
[ [ check-basic-block ] each ]
tri ;
ERROR: undefined-values uses defs ; ERROR: undefined-values uses defs ;

View File

@ -0,0 +1,11 @@
IN: compiler.cfg.useless-blocks.tests
USING: fry kernel sequences compiler.cfg.useless-blocks compiler.cfg.checker
compiler.cfg.debugger compiler.cfg.predecessors tools.test ;
{
[ [ drop 1 ] when ]
[ [ drop 1 ] unless ]
} [
[ [ ] ] dip
'[ _ test-cfg first dup compute-predecessors dup delete-useless-blocks check-cfg ] unit-test
] each

View File

@ -1,10 +1,12 @@
! Copyright (C) 2008, 2009 Slava Pestov. ! Copyright (C) 2008, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel accessors sequences combinators classes vectors USING: kernel accessors sequences combinators combinators.short-circuit
compiler.cfg compiler.cfg.instructions compiler.cfg.rpo ; classes vectors compiler.cfg compiler.cfg.instructions compiler.cfg.rpo ;
IN: compiler.cfg.useless-blocks IN: compiler.cfg.useless-blocks
: update-predecessor-for-delete ( bb -- ) : update-predecessor-for-delete ( bb -- )
! We have to replace occurrences of bb with bb's successor
! in bb's predecessor's list of successors.
dup predecessors>> first [ dup predecessors>> first [
[ [
2dup eq? [ drop successors>> first ] [ nip ] if 2dup eq? [ drop successors>> first ] [ nip ] if
@ -12,9 +14,13 @@ IN: compiler.cfg.useless-blocks
] change-successors drop ; ] change-successors drop ;
: update-successor-for-delete ( bb -- ) : update-successor-for-delete ( bb -- )
[ predecessors>> first ] ! We have to replace occurrences of bb with bb's predecessor
[ successors>> first predecessors>> ] ! in bb's sucessor's list of predecessors.
bi set-first ; dup successors>> first [
[
2dup eq? [ drop predecessors>> first ] [ nip ] if
] with map
] change-predecessors drop ;
: delete-basic-block ( bb -- ) : delete-basic-block ( bb -- )
[ update-predecessor-for-delete ] [ update-predecessor-for-delete ]
@ -23,12 +29,11 @@ IN: compiler.cfg.useless-blocks
: delete-basic-block? ( bb -- ? ) : delete-basic-block? ( bb -- ? )
{ {
{ [ dup instructions>> length 1 = not ] [ f ] } [ instructions>> length 1 = ]
{ [ dup predecessors>> length 1 = not ] [ f ] } [ predecessors>> length 1 = ]
{ [ dup successors>> length 1 = not ] [ f ] } [ successors>> length 1 = ]
{ [ dup instructions>> first ##branch? not ] [ f ] } [ instructions>> first ##branch? ]
[ t ] } 1&& ;
} cond nip ;
: delete-useless-blocks ( cfg -- ) : delete-useless-blocks ( cfg -- )
[ [