@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());
        }
      }
    }
Beispiel #3
0
 @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);
   }
 }
Beispiel #4
0
 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();
 }
Beispiel #5
0
 @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);
    }
  }
Beispiel #7
0
  @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);
  }