void (ControlFlowGraph graph, Area area) { BasicBlock start = area.start; BasicBlock next = area.next; if (start == next) { return; } if (next == null) { // dummy exit block next = graph.getLast(); } // collecting common exception ranges of predecessors and successors Set<BasicBlock> setCommonExceptionHandlers = new HashSet<>(next.getSuccessorExceptions()); for (BasicBlock predecessor : start.getPredecessors()) { setCommonExceptionHandlers.retainAll(predecessor.getSuccessorExceptions()); } boolean isOutsideRange = false; Set<BasicBlock> setPredecessors = new HashSet<>(start.getPredecessors()); // replace start with next for (BasicBlock predecessor : setPredecessors) { predecessor.replaceSuccessor(start, next); } Set<BasicBlock> setBlocks = area.sample; Set<ExceptionRangeCFG> setCommonRemovedExceptionRanges = null; // remove all the blocks in between for (BasicBlock block : setBlocks) { // artificial basic blocks (those resulting from splitting) may belong to more than one area if (graph.getBlocks().containsKey(block.id)) { if (!new HashSet<>(block.getSuccessorExceptions()).containsAll(setCommonExceptionHandlers)) { isOutsideRange = true; } Set<ExceptionRangeCFG> setRemovedExceptionRanges = new HashSet<>(); for (BasicBlock handler : block.getSuccessorExceptions()) { setRemovedExceptionRanges.add(graph.getExceptionRange(handler, block)); } if (setCommonRemovedExceptionRanges == null) { setCommonRemovedExceptionRanges = setRemovedExceptionRanges; } else { setCommonRemovedExceptionRanges.retainAll(setRemovedExceptionRanges); } // shift extern edges on split blocks if (block.getSeq().isEmpty() && block.getSuccessors().size() == 1) { BasicBlock successor = block.getSuccessors().get(0); for (BasicBlock predecessor : new ArrayList<>(block.getPredecessors())) { if (!setBlocks.contains(predecessor)) { predecessor.replaceSuccessor(block, successor); } } if (graph.getFirst() == block) { graph.setFirst(successor); } } graph.removeBlock(block); } } if (isOutsideRange) { // new empty block BasicBlock emptyBlock = new BasicBlock(++graph.last_id); graph.getBlocks().addWithKey(emptyBlock, emptyBlock.id); // add to ranges if necessary for (ExceptionRangeCFG range : setCommonRemovedExceptionRanges) { emptyBlock.addSuccessorException(range.getHandler()); range.getProtectedRange().add(emptyBlock); } // insert between predecessors and next emptyBlock.addSuccessor(next); for (BasicBlock predecessor : setPredecessors) { predecessor.replaceSuccessor(next, emptyBlock); } } }