public List<E> performDFA() throws DFALimitExceededException {
    final ArrayList<E> info = new ArrayList<>(myFlow.length);
    if (LOG.isDebugEnabled()) {
      LOG.debug("Performing DFA\n" + "Instance: " + myDfa + " Semilattice: " + mySemilattice + "\nCon");
    }

// initializing dfa
    final E initial = myDfa.initial();
    final int length = myFlow.length;
    for (int i = 0; i < length; i++) {
      info.add(i, initial);
    }

// Count limit for loops
    final int limit = getIterationLimit();
    final long startTime = System.nanoTime();
    DFSTBuilder<Instruction> dfsTBuilder = new DFSTBuilder<>(ControlFlowUtil.createGraph(myFlow));

    int[] instructionNumToNNumber = new int[myFlow.length];
    for (int i = 0; i < myFlow.length; ++i) {
      instructionNumToNNumber[dfsTBuilder.getNodeByNNumber(i).num()] = i;
    }
    final int[] lastUpdate = new int[length];
    int count = 0;

    List<Instruction> instructionsWithBackEdges = new ArrayList<>();
    for (Collection<Instruction> component :  dfsTBuilder.getComponents()) {
      List<Instruction> sortedInstructions = new ArrayList<>(component);
      // component returns its instructions using getNodeByTNumber
      // unfortunately its ordering is not suitable for dataflow goals because
      // it does not start order in a SCC from entry nodes
      // so We should resort nodes in a SCC by NNumber
      sortedInstructions.sort(Comparator.comparingInt(it -> instructionNumToNNumber[it.num()]));
      instructionsWithBackEdges.clear();
      for (Instruction instruction : sortedInstructions) {
        applyTransferFunction(info, instruction);
        if (instruction.allPred().stream().anyMatch(predecessor ->
          instructionNumToNNumber[predecessor.num()] > instructionNumToNNumber[instruction.num()])) {
          instructionsWithBackEdges.add(instruction);
        }
      }

      int iteration = 0;
      while (true) {
        ++iteration;
        final int currentIteration = iteration;
        boolean anyUpdates = false;
        for (Instruction instruction : instructionsWithBackEdges) {
          if (applyTransferFunction(info, instruction)) {
            lastUpdate[instruction.num()] = currentIteration;
            anyUpdates = true;
            count++;
          }
        }
        if (!anyUpdates) {
          break;
        }
        for (Instruction instruction : sortedInstructions) {
          if (instruction.allPred().stream().anyMatch(it -> lastUpdate[it.num()] == currentIteration)
              && applyTransferFunction(info, instruction)) {
            lastUpdate[instruction.num()] = currentIteration;
            count++;
          }
        }

        if (count > limit ||  (System.nanoTime() - startTime) > TIME_LIMIT) {
          if (LOG.isDebugEnabled()) {
            LOG.debug("Iteration count exceeded on worklist");
          }
          throw new DFALimitExceededException("Iteration count exceeded on worklist");
        }
      }
    }
    if (LOG.isDebugEnabled()) {
      LOG.debug("Done in: " + (System.nanoTime() - startTime) / 10e6 + "ms. Ratio: " + count / length);
    }
    return info;
  }
public List<E> performDFA()