void (@NotNull Instruction prevInstruction, @NotNull Instruction nextInstruction, int @NotNull [] loopNumber, @NotNull MultiMap<Instruction, DfaMemoryState> processedStates, @NotNull MultiMap<Instruction, DfaMemoryState> incomingStates, @NotNull List<? extends DfaInstructionState> inFlightStates, DfaInstructionState @NotNull [] afterStates, @NotNull StateQueue queue) { if (loopNumber[prevInstruction.getIndex()] == 0 || inSameLoop(prevInstruction, nextInstruction, loopNumber)) { return; } // stepped out of loop. destroy all memory states from the loop, we don't need them anymore // but do not touch yet states being handled right now for (DfaInstructionState state : inFlightStates) { Instruction instruction = state.getInstruction(); if (inSameLoop(prevInstruction, instruction, loopNumber)) { return; } } for (DfaInstructionState state : afterStates) { Instruction instruction = state.getInstruction(); if (inSameLoop(prevInstruction, instruction, loopNumber)) { return; } } // and still in queue if (!queue.processAll(state -> { Instruction instruction = state.getInstruction(); return !inSameLoop(prevInstruction, instruction, loopNumber); })) return; // now remove obsolete memory states final Set<Instruction> mayRemoveStatesFor = new HashSet<>(); for (Instruction instruction : myInstructions) { if (inSameLoop(prevInstruction, instruction, loopNumber) && !instruction.isLinear()) { mayRemoveStatesFor.add(instruction); } } for (Instruction instruction : mayRemoveStatesFor) { processedStates.remove(instruction); incomingStates.remove(instruction); } }