2009-08-08 01:24:46 -04:00
|
|
|
! Copyright (C) 2009 Slava Pestov.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2015-04-21 16:45:38 -04:00
|
|
|
USING: accessors assocs combinators.short-circuit compiler.cfg
|
|
|
|
compiler.cfg.predecessors compiler.cfg.utilities deques dlists fry kernel
|
|
|
|
namespaces sequences sets ;
|
2009-08-08 01:24:46 -04:00
|
|
|
IN: compiler.cfg.loop-detection
|
|
|
|
|
|
|
|
TUPLE: natural-loop header index ends blocks ;
|
|
|
|
|
|
|
|
SYMBOL: loops
|
|
|
|
|
2009-08-13 21:26:44 -04:00
|
|
|
<PRIVATE
|
|
|
|
|
2009-08-08 01:24:46 -04:00
|
|
|
: <natural-loop> ( header index -- loop )
|
2013-03-10 13:06:48 -04:00
|
|
|
HS{ } clone HS{ } clone natural-loop boa ;
|
2009-08-08 01:24:46 -04:00
|
|
|
|
|
|
|
: lookup-header ( header -- loop )
|
2013-03-10 13:06:48 -04:00
|
|
|
loops get dup '[ _ assoc-size <natural-loop> ] cache ;
|
2009-08-08 01:24:46 -04:00
|
|
|
|
|
|
|
SYMBOLS: visited active ;
|
|
|
|
|
|
|
|
: record-back-edge ( from to -- )
|
2013-03-08 15:38:50 -05:00
|
|
|
lookup-header ends>> adjoin ;
|
2009-08-08 01:24:46 -04:00
|
|
|
|
|
|
|
DEFER: find-loop-headers
|
|
|
|
|
2013-03-08 15:38:50 -05:00
|
|
|
: visit-edge ( from to active -- )
|
|
|
|
dupd in?
|
2009-08-08 01:24:46 -04:00
|
|
|
[ record-back-edge ]
|
|
|
|
[ nip find-loop-headers ]
|
|
|
|
if ;
|
|
|
|
|
|
|
|
: find-loop-headers ( bb -- )
|
2013-03-10 20:21:27 -04:00
|
|
|
dup visited get ?adjoin [
|
|
|
|
active get
|
|
|
|
[ adjoin ]
|
|
|
|
[ [ dup successors>> ] dip '[ _ visit-edge ] with each ]
|
|
|
|
[ delete ]
|
|
|
|
2tri
|
|
|
|
] [ drop ] if ;
|
2009-08-08 01:24:46 -04:00
|
|
|
|
2015-04-21 16:45:38 -04:00
|
|
|
: process-loop-block ( bb loop -- bbs )
|
|
|
|
dupd { [ blocks>> ?adjoin ] [ header>> eq? not ] } 2&&
|
|
|
|
swap predecessors>> { } ? ;
|
2009-08-08 01:24:46 -04:00
|
|
|
|
|
|
|
: process-loop-ends ( loop -- )
|
2015-04-21 16:45:38 -04:00
|
|
|
dup ends>> members <dlist> [ push-all-front ] keep
|
|
|
|
swap '[ _ process-loop-block ] slurp/replenish-deque ;
|
2009-08-08 01:24:46 -04:00
|
|
|
|
|
|
|
: process-loop-headers ( -- )
|
|
|
|
loops get values [ process-loop-ends ] each ;
|
|
|
|
|
|
|
|
SYMBOL: loop-nesting
|
|
|
|
|
|
|
|
: compute-loop-nesting ( -- )
|
|
|
|
loops get H{ } clone [
|
2013-03-10 13:06:48 -04:00
|
|
|
[ values ] dip '[ blocks>> members [ _ inc-at ] each ] each
|
2009-08-08 01:24:46 -04:00
|
|
|
] keep loop-nesting set ;
|
|
|
|
|
|
|
|
: detect-loops ( cfg -- cfg' )
|
|
|
|
H{ } clone loops set
|
2013-03-08 14:04:47 -05:00
|
|
|
HS{ } clone visited set
|
|
|
|
HS{ } clone active set
|
2009-08-08 01:24:46 -04:00
|
|
|
H{ } clone loop-nesting set
|
2014-12-10 12:24:12 -05:00
|
|
|
[ needs-predecessors ]
|
|
|
|
[ entry>> find-loop-headers process-loop-headers compute-loop-nesting ]
|
|
|
|
[ ] tri ;
|
2009-08-08 21:02:56 -04:00
|
|
|
|
|
|
|
PRIVATE>
|
|
|
|
|
|
|
|
: loop-nesting-at ( bb -- n ) loop-nesting get at 0 or ;
|
|
|
|
|
2010-04-24 20:05:52 -04:00
|
|
|
: current-loop-nesting ( -- n ) basic-block get loop-nesting-at ;
|
|
|
|
|
2014-12-11 15:48:43 -05:00
|
|
|
: needs-loops ( cfg -- )
|
2014-12-10 12:24:12 -05:00
|
|
|
dup needs-predecessors
|
2014-12-11 15:48:43 -05:00
|
|
|
dup loops-valid?>> [ detect-loops t >>loops-valid? ] unless
|
|
|
|
drop ;
|