private void computeDominance(final ControlFlowGraph cfg) {
final ControlFlowNode entryPoint = cfg.getEntryPoint();
entryPoint.setImmediateDominator(entryPoint);
final BooleanBox changed = new BooleanBox(true);
while (changed.get()) {
changed.set(false);
cfg.resetVisited();
entryPoint.traversePreOrder(
new Function<ControlFlowNode, Iterable<ControlFlowNode>>() {
@Override
public final Iterable<ControlFlowNode> apply(final ControlFlowNode input) {
return input.getSuccessors();
}
},
new Block<ControlFlowNode>() {
@Override
public final void accept(final ControlFlowNode b) {
if (b == entryPoint) {
return;
}
ControlFlowNode newImmediateDominator = null;
for (final ControlFlowNode p : b.getPredecessors()) {
if (p.isVisited() && p != b) {
newImmediateDominator = p;
break;
}
}
if (newImmediateDominator == null) {
throw new IllegalStateException("Could not compute new immediate dominator!");
}
for (final ControlFlowNode p : b.getPredecessors()) {
if (p != b && p.getImmediateDominator() != null) {
newImmediateDominator = ControlFlowGraph.findCommonDominator(p, newImmediateDominator);
}
}
if (b.getImmediateDominator() != newImmediateDominator) {
b.setImmediateDominator(newImmediateDominator);
changed.set(true);
}
}
}
);
for (final ControlFlowNode node : _nodes) {
if (node.getUserData() instanceof ExceptionTableEntry) {
node.traversePreOrder(
new Function<ControlFlowNode, Iterable<ControlFlowNode>>() {
@Override
public final Iterable<ControlFlowNode> apply(final ControlFlowNode input) {
return input.getSuccessors();
}
},
new Block<ControlFlowNode>() {
@Override
public final void accept(final ControlFlowNode b) {
if (b == node) {
return;
}
ControlFlowNode newImmediateDominator = null;
for (final ControlFlowNode p : b.getPredecessors()) {
if (p.isVisited() && p != b) {
newImmediateDominator = p;
break;
}
}
if (newImmediateDominator == null) {
throw new IllegalStateException("Could not compute new immediate dominator!");
}
for (final ControlFlowNode p : b.getPredecessors()) {
if (p != b && p.getImmediateDominator() != null) {
newImmediateDominator = ControlFlowGraph.findCommonDominator(p, newImmediateDominator);
}
}
if (b.getImmediateDominator() != newImmediateDominator) {
b.setImmediateDominator(newImmediateDominator);
changed.set(true);
}
}
}
);
}