public <T>SearchResult<T> graphSearch(GraphSearch<T> gs){
  clearChanged();
  for (  BasicBlock bb : blocks) {
    bb.state=gs.markStart(bb.expr,bb == entry);
    if (bb.state != null)     bb.changed=true;
  }
  exit.state=fail.state=implicit.state=null;
  boolean changed=true;
  while (changed) {
    changed=false;
    for (    BasicBlock bb : blocks) {
      if (bb.changed) {
        bb.changed=false;
        @SuppressWarnings("unchecked") T state=(T)bb.state;
        if (bb.passTarget != null) {
          changed|=updateState(gs,bb.passTarget,gs.transfer(state,bb.expr,EdgeType.PASS,bb.passTarget.expr));
        }
 else         if (bb.trueTarget != null) {
          changed|=updateState(gs,bb.trueTarget,gs.transfer(state,bb.expr,EdgeType.TRUE,bb.trueTarget.expr));
          changed|=updateState(gs,bb.falseTarget,gs.transfer(state,bb.expr,EdgeType.FALSE,bb.falseTarget.expr));
        }
        if (bb.failTargets != null) {
          for (          BasicBlock target : bb.failTargets)           changed|=updateState(gs,target,gs.transfer(state,bb.expr,EdgeType.FAIL,target.expr));
        }
      }
    }
    if (forwardTill == blocks.size())     break;
  }
  return new SearchResult<>(gs);
}

public < T > SearchResult < T > graphSearch ( GraphSearch < T > gs ) { clearChanged ( ) ; for ( BasicBlock bb : blocks ) { bb . state = gs . markStart ( bb . expr , bb == entry ) ; if ( bb . state != null ) bb . changed = true ; } exit . state = fail . state = implicit . state = null ; boolean changed = true ; while ( changed ) { changed = false ; for ( BasicBlock bb : blocks ) { if ( bb . changed ) { bb . changed = false ; @ SuppressWarnings ( "unchecked" ) T state = ( T ) bb . state ; if ( bb . passTarget != null ) { changed |= updateState ( gs , bb . passTarget , gs . transfer ( state , bb . expr , EdgeType . PASS , bb . passTarget . expr ) ) ; } else if ( bb . trueTarget != null ) { changed |= updateState ( gs , bb . trueTarget , gs . transfer ( state , bb . expr , EdgeType . TRUE , bb . trueTarget . expr ) ) ; changed |= updateState ( gs , bb . falseTarget , gs . transfer ( state , bb . expr , EdgeType . FALSE , bb . falseTarget . expr ) ) ; } if ( bb . failTargets != null ) { for ( BasicBlock target : bb . failTargets ) changed |= updateState ( gs , target , gs . transfer ( state , bb . expr , EdgeType . FAIL , target . expr ) ) ; } } } if ( forwardTill == blocks . size ( ) ) break ; } return new SearchResult < > ( gs ) ; }
result works only until new graph - search is performed . must not be called during dfa run on the same cfg .
