private ControlFlowGraph build() { calculateIncomingJumps(); createNodes(); createRegularControlFlow(); createExceptionalControlFlow(); return new ControlFlowGraph(_nodes.toArray(new ControlFlowNode[_nodes.size()])); }
public final void findConditions(final Block block) { final List<Node> body = block.getBody(); if (body.isEmpty() || block.getEntryGoto() == null) { return; } final ControlFlowGraph graph = buildGraph(body, (Label) block.getEntryGoto().getOperand()); graph.computeDominance(); graph.computeDominanceFrontier(); final Set<ControlFlowNode> cfNodes = new LinkedHashSet<>(); final List<ControlFlowNode> graphNodes = graph.getNodes(); for (int i = 3; i < graphNodes.size(); i++) { cfNodes.add(graphNodes.get(i)); } final List<Node> newBody = findConditions(cfNodes, graph.getEntryPoint()); block.getBody().clear(); block.getBody().addAll(newBody); }
private static String escapeGraphViz(final String text) { return escapeGraphViz(text, false); }
public final void computeDominanceFrontier() { resetVisited(); getEntryPoint().traversePostOrder( new Function<ControlFlowNode, Iterable<ControlFlowNode>>() { @Override public final Iterable<ControlFlowNode> apply(final ControlFlowNode input) { return input.getDominatorTreeChildren(); } }, new Block<ControlFlowNode>() { @Override public void accept(final ControlFlowNode n) { final Set<ControlFlowNode> dominanceFrontier = n.getDominanceFrontier(); dominanceFrontier.clear(); for (final ControlFlowNode s : n.getSuccessors()) { if (s.getImmediateDominator() != n) { dominanceFrontier.add(s); } } for (final ControlFlowNode child : n.getDominatorTreeChildren()) { for (final ControlFlowNode p : child.getDominanceFrontier()) { if (p.getImmediateDominator() != n) { dominanceFrontier.add(p); } } } } } ); }
public ControlFlowGraph(final ControlFlowNode... nodes) { _nodes = ArrayUtilities.asUnmodifiableList(VerifyArgument.noNullElements(nodes, "nodes")); assert nodes.length >= 3; assert getEntryPoint().getNodeType() == ControlFlowNodeType.EntryPoint; assert getRegularExit().getNodeType() == ControlFlowNodeType.RegularExit; assert getExceptionalExit().getNodeType() == ControlFlowNodeType.ExceptionalExit; }
_cfg.computeDominance(); _cfg.computeDominanceFrontier(); _nodeMap = createNodeMap(_cfg);
builder.createEdge(cfg.getEntryPoint(), handlerStartNode, JumpType.Normal); cfg.computeDominance(); cfg.computeDominanceFrontier();
private static ControlFlowNode findHandlerNode(final ControlFlowGraph cfg, final ExceptionHandler handler) { final List<ControlFlowNode> nodes = cfg.getNodes(); for (int i = nodes.size() - 1; i >= 0; i--) { final ControlFlowNode node = nodes.get(i); if (node.getExceptionHandler() == handler) { return node; } } return null; }
private static ControlFlowNode findInnermostExceptionHandlerNode( final ControlFlowGraph cfg, final int offsetInTryBlock, final boolean finallyOnly) { ExceptionHandler result = null; ControlFlowNode resultNode = null; final List<ControlFlowNode> nodes = cfg.getNodes(); for (int i = nodes.size() - 1; i >= 0; i--) { final ControlFlowNode node = nodes.get(i); final ExceptionHandler handler = node.getExceptionHandler(); if (handler == null) { break; } if (finallyOnly && handler.isCatch()) { continue; } final InstructionBlock tryBlock = handler.getTryBlock(); if (tryBlock.getFirstInstruction().getOffset() <= offsetInTryBlock && offsetInTryBlock < tryBlock.getLastInstruction().getEndOffset() && (result == null || tryBlock.getFirstInstruction().getOffset() > result.getTryBlock().getFirstInstruction().getOffset())) { result = handler; resultNode = node; } } return resultNode != null ? resultNode : cfg.getExceptionalExit(); }
output.writeLine("\"%s\" [", nodeName(node)); output.indent(); escapeGraphViz(node.toString()) ); output.writeLine("\"%s\" [", nodeName(endFinallyNode)); output.indent(); escapeGraphViz(endFinallyNode.toString()) ); final ControlFlowNode to = edge.getTarget(); output.writeLine("\"%s\" -> \"%s\" [", nodeName(from), nodeName(to)); output.indent();
for (final ControlFlowNode exit : cfg.getRegularExit().getPredecessors()) { if (exit.getNodeType() == ControlFlowNodeType.Normal && tryBlock.contains(exit.getEnd())) { for (final ControlFlowNode exit : cfg.getExceptionalExit().getPredecessors()) { if (exit.getNodeType() == ControlFlowNodeType.Normal && tryBlock.contains(exit.getEnd())) {
private static boolean shouldIncludeExceptionalExit(final ControlFlowGraph cfg, final ControlFlowNode head, final ControlFlowNode node) { if (node.getNodeType() != ControlFlowNodeType.Normal) { return false; } if (!node.getDominanceFrontier().contains(cfg.getExceptionalExit()) && !node.dominates(cfg.getExceptionalExit())) { final ControlFlowNode innermostHandlerNode = findInnermostExceptionHandlerNode(cfg, node.getStart().getOffset()); if (innermostHandlerNode == null || !node.getDominanceFrontier().contains(innermostHandlerNode)) { return false; } } if (node.getStart().getNext() != node.getEnd()) { return false; } if (head.getStart().getOpCode().isStore() && node.getStart().getOpCode().isLoad() && node.getEnd().getOpCode() == OpCode.ATHROW) { return InstructionHelper.getLoadOrStoreSlot(head.getStart()) == InstructionHelper.getLoadOrStoreSlot(node.getStart()); } return false; }
public final void computeDominance() { computeDominance(new BooleanBox()); }
@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 = findCommonDominator(p, newImmediateDominator); } } if (b.getImmediateDominator() != newImmediateDominator) { b.setImmediateDominator(newImmediateDominator); changed.set(true); } } }
_cfg.computeDominance(); _cfg.computeDominanceFrontier(); _nodeMap = createNodeMap(_cfg);
public ControlFlowGraph(final ControlFlowNode... nodes) { _nodes = ArrayUtilities.asUnmodifiableList(VerifyArgument.noNullElements(nodes, "nodes")); assert nodes.length >= 3; assert getEntryPoint().getNodeType() == ControlFlowNodeType.EntryPoint; assert getRegularExit().getNodeType() == ControlFlowNodeType.RegularExit; assert getExceptionalExit().getNodeType() == ControlFlowNodeType.ExceptionalExit; }
builder.createEdge(cfg.getEntryPoint(), handlerStartNode, JumpType.Normal); cfg.computeDominance(); cfg.computeDominanceFrontier();
public final void computeDominanceFrontier() { resetVisited(); getEntryPoint().traversePostOrder( new Function<ControlFlowNode, Iterable<ControlFlowNode>>() { @Override public final Iterable<ControlFlowNode> apply(final ControlFlowNode input) { return input.getDominatorTreeChildren(); } }, new Block<ControlFlowNode>() { @Override public void accept(final ControlFlowNode n) { final Set<ControlFlowNode> dominanceFrontier = n.getDominanceFrontier(); dominanceFrontier.clear(); for (final ControlFlowNode s : n.getSuccessors()) { if (s.getImmediateDominator() != n) { dominanceFrontier.add(s); } } for (final ControlFlowNode child : n.getDominatorTreeChildren()) { for (final ControlFlowNode p : child.getDominanceFrontier()) { if (p.getImmediateDominator() != n) { dominanceFrontier.add(p); } } } } } ); }
private static ControlFlowNode findHandlerNode(final ControlFlowGraph cfg, final ExceptionHandler handler) { final List<ControlFlowNode> nodes = cfg.getNodes(); for (int i = nodes.size() - 1; i >= 0; i--) { final ControlFlowNode node = nodes.get(i); if (node.getExceptionHandler() == handler) { return node; } } return null; }
private static ControlFlowNode findInnermostExceptionHandlerNode( final ControlFlowGraph cfg, final int offsetInTryBlock, final boolean finallyOnly) { ExceptionHandler result = null; ControlFlowNode resultNode = null; final List<ControlFlowNode> nodes = cfg.getNodes(); for (int i = nodes.size() - 1; i >= 0; i--) { final ControlFlowNode node = nodes.get(i); final ExceptionHandler handler = node.getExceptionHandler(); if (handler == null) { break; } if (finallyOnly && handler.isCatch()) { continue; } final InstructionBlock tryBlock = handler.getTryBlock(); if (tryBlock.getFirstInstruction().getOffset() <= offsetInTryBlock && offsetInTryBlock < tryBlock.getLastInstruction().getEndOffset() && (result == null || tryBlock.getFirstInstruction().getOffset() > result.getTryBlock().getFirstInstruction().getOffset())) { result = handler; resultNode = node; } } return resultNode != null ? resultNode : cfg.getExceptionalExit(); }