keys.add(key);
}
Map<BlockNode, List<Object>> blocksMap = new LinkedHashMap<BlockNode, List<Object>>(len);
for (Map.Entry<Integer, List<Object>> entry : casesMap.entrySet()) {
BlockNode c = getBlockByOffset(entry.getKey(), block.getSuccessors());
assert c != null;
blocksMap.put(c, entry.getValue());
}
BitSet succ = BlockUtils.blocksToBitSet(mth, block.getSuccessors());
BitSet domsOn = BlockUtils.blocksToBitSet(mth, block.getDominatesOn());
domsOn.xor(succ); // filter 'out' block
BlockNode defCase = getBlockByOffset(insn.getDefaultCaseOffset(), block.getSuccessors());
if (defCase != null) {
blocksMap.remove(defCase);
}
int outCount = domsOn.cardinality();
if (outCount > 1) {
// remove exception handlers
BlockUtils.cleanBitSet(mth, domsOn);
outCount = domsOn.cardinality();
}
if (outCount > 1) {
// filter successors of other blocks
List<BlockNode> blocks = mth.getBasicBlocks();
for (int i = domsOn.nextSetBit(0); i >= 0; i = domsOn.nextSetBit(i + 1)) {
BlockNode b = blocks.get(i);
for (BlockNode s : b.getCleanSuccessors()) {
domsOn.clear(s.getId());
}
}
outCount = domsOn.cardinality();
}
BlockNode out = null;
if (outCount == 1) {
out = mth.getBasicBlocks().get(domsOn.nextSetBit(0));
} else if (outCount == 0) {
// one or several case blocks are empty,
// run expensive algorithm for find 'out' block
for (BlockNode maybeOut : block.getSuccessors()) {
boolean allReached = true;
for (BlockNode s : block.getSuccessors()) {
if (!isPathExists(s, maybeOut)) {
allReached = false;
break;
}
}
if (allReached) {
out = maybeOut;
break;
}
}
}
stack.push(sw);
if (out != null) {
stack.addExit(out);
}
if (!stack.containsExit(defCase)) {
sw.setDefaultCase(makeRegion(defCase, stack));
}
for (Entry<BlockNode, List<Object>> entry : blocksMap.entrySet()) {
BlockNode c = entry.getKey();
if (stack.containsExit(c)) {
// empty case block
sw.addCase(entry.getValue(), new Region(stack.peekRegion()));
} else {
sw.addCase(entry.getValue(), makeRegion(c, stack));