@Override public void lower(LoweringTool tool) { if (graph().getGuardsStage().areFrameStatesAtDeopts()) { ForeignCallDescriptor desc = HotSpotHostForeignCallsProvider.lookupCheckcastArraycopyDescriptor(isUninit()); StructuredGraph graph = graph(); ValueNode srcAddr = computeBase(getSource(), getSourcePosition()); ValueNode destAddr = computeBase(getDestination(), getDestinationPosition()); ValueNode len = getLength(); if (len.stamp().getStackKind() != runtime.getTarget().wordJavaKind) { len = IntegerConvertNode.convert( len, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph()); } ForeignCallNode call = graph.add( new ForeignCallNode( runtime.getHostBackend().getForeignCalls(), desc, srcAddr, destAddr, len, superCheckOffset, destElemKlass)); call.setStateAfter(stateAfter()); graph.replaceFixedWithFixed(this, call); } }
/** * Instantiate the snippet template and fix up the FrameState of any Invokes of System.arraycopy * and propagate the captured bci in the ArrayCopySlowPathNode. * * @param args * @param arraycopy */ private void instantiate(Arguments args, BasicArrayCopyNode arraycopy) { StructuredGraph graph = arraycopy.graph(); SnippetTemplate template = template(args); Map<Node, Node> replacements = template.instantiate( providers.getMetaAccess(), arraycopy, SnippetTemplate.DEFAULT_REPLACER, args); for (Node originalNode : replacements.keySet()) { if (originalNode instanceof Invoke) { Invoke invoke = (Invoke) replacements.get(originalNode); assert invoke.asNode().graph() == graph; CallTargetNode call = invoke.callTarget(); if (!call.targetMethod().equals(originalArraycopy)) { throw new GraalError("unexpected invoke %s in snippet", call.targetMethod()); } // Here we need to fix the bci of the invoke InvokeNode newInvoke = graph.add(new InvokeNode(invoke.callTarget(), arraycopy.getBci())); if (arraycopy.stateDuring() != null) { newInvoke.setStateDuring(arraycopy.stateDuring()); } else { assert arraycopy.stateAfter() != null; newInvoke.setStateAfter(arraycopy.stateAfter()); } graph.replaceFixedWithFixed((InvokeNode) invoke.asNode(), newInvoke); } else if (originalNode instanceof ArrayCopySlowPathNode) { ArrayCopySlowPathNode slowPath = (ArrayCopySlowPathNode) replacements.get(originalNode); assert arraycopy.stateAfter() != null; slowPath.setStateAfter(arraycopy.stateAfter()); slowPath.setBci(arraycopy.getBci()); } } }
@Override protected void replaceProfile(StructuredGraph graph, JavaTypeProfile profile) { CheckCastNode ccn = graph.getNodes(CheckCastNode.class).first(); if (ccn != null) { CheckCastNode ccnNew = graph.add(new CheckCastNode(ccn.type(), ccn.object(), profile, false)); graph.replaceFixedWithFixed(ccn, ccnNew); } }
public EdgesTest() { node = new TestNode(); i1 = ConstantNode.forInt(1, graph); i2 = ConstantNode.forDouble(1.0d, graph); i3 = ConstantNode.forInt(4, graph); i4 = ConstantNode.forInt(14, graph); node.itail = new NodeInputList<>(node, new ValueNode[] {i3, i4}); node.i1 = i1; node.i2 = i2; graph.add(node); inputs = node.getNodeClass().getInputEdges(); }
@Override public GuardingNode createGuard( FixedNode before, LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, JavaConstant speculation, boolean negated) { if (OptEliminateGuards.getValue()) { for (Node usage : condition.usages()) { if (!activeGuards.isNew(usage) && activeGuards.isMarked(usage) && ((GuardNode) usage).isNegated() == negated) { return (GuardNode) usage; } } } StructuredGraph graph = before.graph(); if (!condition.graph().getGuardsStage().allowsFloatingGuards()) { FixedGuardNode fixedGuard = graph.add(new FixedGuardNode(condition, deoptReason, action, speculation, negated)); graph.addBeforeFixed(before, fixedGuard); DummyGuardHandle handle = graph.add(new DummyGuardHandle(fixedGuard)); fixedGuard.lower(this); GuardingNode result = handle.getGuard(); handle.safeDelete(); return result; } else { GuardNode newGuard = graph.unique( new GuardNode(condition, guardAnchor, deoptReason, action, negated, speculation)); if (OptEliminateGuards.getValue()) { activeGuards.markAndGrow(newGuard); } return newGuard; } }
private void visitDeoptBegin( AbstractBeginNode deoptBegin, DeoptimizationAction deoptAction, DeoptimizationReason deoptReason, JavaConstant speculation, StructuredGraph graph) { if (deoptBegin.predecessor() instanceof AbstractBeginNode) { /* Walk up chains of LoopExitNodes to the "real" BeginNode that leads to deoptimization. */ visitDeoptBegin( (AbstractBeginNode) deoptBegin.predecessor(), deoptAction, deoptReason, speculation, graph); return; } if (deoptBegin instanceof AbstractMergeNode) { AbstractMergeNode mergeNode = (AbstractMergeNode) deoptBegin; Debug.log("Visiting %s", mergeNode); FixedNode next = mergeNode.next(); while (mergeNode.isAlive()) { AbstractEndNode end = mergeNode.forwardEnds().first(); AbstractBeginNode newBeginNode = findBeginNode(end); visitDeoptBegin(newBeginNode, deoptAction, deoptReason, speculation, graph); } assert next.isAlive(); AbstractBeginNode newBeginNode = findBeginNode(next); visitDeoptBegin(newBeginNode, deoptAction, deoptReason, speculation, graph); return; } else if (deoptBegin.predecessor() instanceof IfNode) { IfNode ifNode = (IfNode) deoptBegin.predecessor(); AbstractBeginNode otherBegin = ifNode.trueSuccessor(); LogicNode conditionNode = ifNode.condition(); FixedGuardNode guard = graph.add( new FixedGuardNode( conditionNode, deoptReason, deoptAction, speculation, deoptBegin == ifNode.trueSuccessor())); FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor(); AbstractBeginNode survivingSuccessor; if (deoptBegin == ifNode.trueSuccessor()) { survivingSuccessor = ifNode.falseSuccessor(); } else { survivingSuccessor = ifNode.trueSuccessor(); } graph.removeSplitPropagate(ifNode, survivingSuccessor); Node newGuard = guard; if (survivingSuccessor instanceof LoopExitNode) { newGuard = ProxyNode.forGuard(guard, (LoopExitNode) survivingSuccessor, graph); } survivingSuccessor.replaceAtUsages(InputType.Guard, newGuard); Debug.log( "Converting deopt on %-5s branch of %s to guard for remaining branch %s.", deoptBegin == ifNode.trueSuccessor() ? "true" : "false", ifNode, otherBegin); FixedNode next = pred.next(); pred.setNext(guard); guard.setNext(next); survivingSuccessor.simplify(simplifierTool); return; } // We could not convert the control split - at least cut off control flow after the split. FixedWithNextNode deoptPred = deoptBegin; FixedNode next = deoptPred.next(); if (!(next instanceof DeoptimizeNode)) { DeoptimizeNode newDeoptNode = graph.add(new DeoptimizeNode(deoptAction, deoptReason, speculation)); deoptPred.setNext(newDeoptNode); assert deoptPred == newDeoptNode.predecessor(); GraphUtil.killCFG(next); } }
@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); }