question: Deque < Block > schedule ( Block entry ) { Deque < Block > code = dfs ( entry ) ; Deque < Block > scheduled = new ArrayDeque < Block > ( ) ; SetMap < Block , Edge > pred = preds ( code ) ; Map < Block , Block > idom = idoms ( code , pred ) ; EdgeMap < Block > loops = findLoops ( code , idom , pred ) ; if ( ! loops . isEmpty ( ) ) verboseStatus ( "LOOPS " + loops ) ; for ( Block b : code ) { if ( ! scheduled . contains ( b ) ) scheduled . add ( b ) ; if ( loops . containsKey ( b ) ) schedule_loop ( b , loops , scheduled ) ; } Deque < Block > branch_analysis = new ArrayDeque < Block > ( ) ; branch_analysis . addAll ( scheduled ) ; Set < Block > already_seen = new HashSet < Block > ( ) ; while ( branch_analysis . size ( ) > 1 ) { Block b = branch_analysis . removeFirst ( ) ; Expr last = b . last ( ) ; Block next = branch_analysis . peekFirst ( ) ; if ( isBranch ( last ) && last . succ [ 0 ] . to != next && last . succ [ 1 ] . to == next ) invert ( last ) ; already_seen . add ( b ) ; b . is_backwards_branch_target = false ; for ( Edge s : b . succ ( ) ) { s . to . is_backwards_branch_target |= s . is_backwards_branch = already_seen . contains ( s . to ) ; } } if ( verbose_mode ) for ( Block b : code ) if ( b . is_backwards_branch_target ) verboseStatus ( ".. backwards branch target:" + b ) ; return scheduled ; }
target:  layout blocks.  Normal forward flow is laid out in reverse postorder. Loops are handled specially to keep blocks in the loop body close to each other.  loop exit blocks are postponed until after the loop.