@Test public void testImplies() { StructuredGraph graph = new StructuredGraph(AllowAssumptions.YES); EndNode trueEnd = graph.add(new EndNode()); EndNode falseEnd = graph.add(new EndNode()); AbstractBeginNode trueBegin = graph.add(new BeginNode()); trueBegin.setNext(trueEnd); AbstractBeginNode falseBegin = graph.add(new BeginNode()); falseBegin.setNext(falseEnd); IfNode ifNode = graph.add(new IfNode(null, trueBegin, falseBegin, 0.5)); graph.start().setNext(ifNode); AbstractMergeNode merge = graph.add(new MergeNode()); merge.addForwardEnd(trueEnd); merge.addForwardEnd(falseEnd); ReturnNode returnNode = graph.add(new ReturnNode(null)); merge.setNext(returnNode); dumpGraph(graph); ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true); List<Block> blocks = cfg.getBlocks(); // check number of blocks assertDeepEquals(4, blocks.size()); // check block - node assignment assertDeepEquals(blocks.get(0), cfg.blockFor(graph.start())); assertDeepEquals(blocks.get(0), cfg.blockFor(ifNode)); assertDeepEquals(blocks.get(1), cfg.blockFor(trueBegin)); assertDeepEquals(blocks.get(1), cfg.blockFor(trueEnd)); assertDeepEquals(blocks.get(2), cfg.blockFor(falseBegin)); assertDeepEquals(blocks.get(2), cfg.blockFor(falseEnd)); assertDeepEquals(blocks.get(3), cfg.blockFor(merge)); assertDeepEquals(blocks.get(3), cfg.blockFor(returnNode)); // check postOrder Iterator<Block> it = cfg.postOrder().iterator(); for (int i = blocks.size() - 1; i >= 0; i--) { assertTrue(it.hasNext()); Block b = it.next(); assertDeepEquals(blocks.get(i), b); } // check dominators assertDominator(blocks.get(0), null); assertDominator(blocks.get(1), blocks.get(0)); assertDominator(blocks.get(2), blocks.get(0)); assertDominator(blocks.get(3), blocks.get(0)); // check dominated assertDominatedSize(blocks.get(0), 3); assertDominatedSize(blocks.get(1), 0); assertDominatedSize(blocks.get(2), 0); assertDominatedSize(blocks.get(3), 0); // check postdominators assertPostdominator(blocks.get(0), blocks.get(3)); assertPostdominator(blocks.get(1), blocks.get(3)); assertPostdominator(blocks.get(2), blocks.get(3)); assertPostdominator(blocks.get(3), null); }
@SuppressWarnings("try") private AnchoringNode process( final Block b, final NodeBitMap activeGuards, final AnchoringNode startAnchor) { final LoweringToolImpl loweringTool = new LoweringToolImpl(context, startAnchor, activeGuards, b.getBeginNode()); // Lower the instructions of this block. List<Node> nodes = schedule.nodesFor(b); for (Node node : nodes) { if (node.isDeleted()) { // This case can happen when previous lowerings deleted nodes. continue; } // Cache the next node to be able to reconstruct the previous of the next node // after lowering. FixedNode nextNode = null; if (node instanceof FixedWithNextNode) { nextNode = ((FixedWithNextNode) node).next(); } else { nextNode = loweringTool.lastFixedNode().next(); } if (node instanceof Lowerable) { Collection<Node> unscheduledUsages = null; assert (unscheduledUsages = getUnscheduledUsages(node)) != null; Mark preLoweringMark = node.graph().getMark(); try (DebugCloseable s = node.graph().withNodeContext(node)) { ((Lowerable) node).lower(loweringTool); } if (loweringTool.guardAnchor.asNode().isDeleted()) { // TODO nextNode could be deleted but this is not currently supported assert nextNode.isAlive(); loweringTool.guardAnchor = AbstractBeginNode.prevBegin(nextNode); } assert checkPostNodeLowering(node, loweringTool, preLoweringMark, unscheduledUsages); } if (!nextNode.isAlive()) { // can happen when the rest of the block is killed by lowering // (e.g. by an unconditional deopt) break; } else { Node nextLastFixed = nextNode.predecessor(); if (!(nextLastFixed instanceof FixedWithNextNode)) { // insert begin node, to have a valid last fixed for next lowerable node. // This is about lowering a FixedWithNextNode to a control split while this // FixedWithNextNode is followed by some kind of BeginNode. // For example the when a FixedGuard followed by a loop exit is lowered to a // control-split + deopt. AbstractBeginNode begin = node.graph().add(new BeginNode()); nextLastFixed.replaceFirstSuccessor(nextNode, begin); begin.setNext(nextNode); nextLastFixed = begin; } loweringTool.setLastFixedNode((FixedWithNextNode) nextLastFixed); } } return loweringTool.getCurrentGuardAnchor(); }