@Test
  public void testBlockSchedule() {
    ScheduleResult schedule =
        getFinalSchedule("testBlockScheduleSnippet", TestMode.WITHOUT_FRAMESTATES);
    StructuredGraph graph = schedule.getCFG().graph;
    NodeIterable<WriteNode> writeNodes = graph.getNodes().filter(WriteNode.class);

    assertDeepEquals(1, schedule.getCFG().getBlocks().size());
    assertDeepEquals(8, writeNodes.count());
    assertDeepEquals(1, graph.getNodes().filter(FloatingReadNode.class).count());

    FloatingReadNode read = graph.getNodes().filter(FloatingReadNode.class).first();

    WriteNode[] writes = new WriteNode[8];
    int i = 0;
    for (WriteNode n : writeNodes) {
      writes[i] = n;
      i++;
    }
    assertOrderedAfterSchedule(schedule, writes[4], read);
    assertOrderedAfterSchedule(schedule, read, writes[5]);
    for (int j = 0; j < 7; j++) {
      assertOrderedAfterSchedule(schedule, writes[j], writes[j + 1]);
    }
  }
 @Test
 public void testLoop9() {
   ScheduleResult schedule = getFinalSchedule("testLoop9Snippet", TestMode.WITHOUT_FRAMESTATES);
   StructuredGraph graph = schedule.getCFG().getStartBlock().getBeginNode().graph();
   assertThat(graph.getNodes(ReturnNode.TYPE), hasCount(1));
   ReturnNode ret = graph.getNodes(ReturnNode.TYPE).first();
   assertThat(ret.result(), instanceOf(FloatingReadNode.class));
   Block readBlock = schedule.getNodeToBlockMap().get(ret.result());
   Assert.assertEquals(0, readBlock.getLoopDepth());
 }
 @Test
 public void testArrayCopy() {
   ScheduleResult schedule =
       getFinalSchedule("testArrayCopySnippet", TestMode.INLINED_WITHOUT_FRAMESTATES);
   StructuredGraph graph = schedule.getCFG().getStartBlock().getBeginNode().graph();
   assertDeepEquals(1, graph.getNodes(ReturnNode.TYPE).count());
   ReturnNode ret = graph.getNodes(ReturnNode.TYPE).first();
   assertTrue(
       ret.result() + " should be a FloatingReadNode", ret.result() instanceof FloatingReadNode);
   assertDeepEquals(schedule.getCFG().blockFor(ret), schedule.getCFG().blockFor(ret.result()));
   assertReadWithinAllReturnBlocks(schedule, true);
 }
Example #4
0
 private StructuredGraph parseAndProcess(String snippet) {
   StructuredGraph graph = parse(snippet);
   LocalNode local = graph.getNodes(LocalNode.class).first();
   ConstantNode constant = ConstantNode.forInt(0, graph);
   for (Node n : local.usages().filter(isNotA(FrameState.class)).snapshot()) {
     n.replaceFirstInput(local, constant);
   }
   Map<Invoke, Double> hints = new HashMap<>();
   for (Invoke invoke : graph.getInvokes()) {
     hints.put(invoke, 1000d);
   }
   Assumptions assumptions = new Assumptions(false);
   new InliningPhase(
           runtime(),
           hints,
           replacements,
           assumptions,
           null,
           getDefaultPhasePlan(),
           OptimisticOptimizations.ALL)
       .apply(graph);
   new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph);
   new DeadCodeEliminationPhase().apply(graph);
   return graph;
 }
Example #5
0
 @Test
 public void test2() {
   StructuredGraph graph = parseAndProcess("test2Snippet");
   NodeIterable<MonitorExitNode> monitors = graph.getNodes(MonitorExitNode.class);
   Assert.assertEquals(1, monitors.count());
   Assert.assertEquals(monitors.first().stateAfter().bci, 3);
 }
Example #6
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);
   }
 }
  private void assertReadWithinAllReturnBlocks(ScheduleResult schedule, boolean withinReturnBlock) {
    StructuredGraph graph = schedule.getCFG().graph;
    assertTrue(graph.getNodes(ReturnNode.TYPE).isNotEmpty());

    int withRead = 0;
    int returnBlocks = 0;
    for (ReturnNode returnNode : graph.getNodes(ReturnNode.TYPE)) {
      Block block = schedule.getCFG().getNodeToBlock().get(returnNode);
      for (Node node : schedule.getBlockToNodesMap().get(block)) {
        if (node instanceof FloatingReadNode) {
          withRead++;
          break;
        }
      }
      returnBlocks++;
    }
    assertDeepEquals(withRead == returnBlocks, withinReturnBlock);
  }
  @Override
  protected void run(final StructuredGraph graph, PhaseContext context) {
    assert graph.hasValueProxies() : "ConvertDeoptimizeToGuardPhase always creates proxies";
    if (graph.getNodes(DeoptimizeNode.TYPE).isEmpty()) {
      return;
    }
    for (DeoptimizeNode d : graph.getNodes(DeoptimizeNode.TYPE)) {
      assert d.isAlive();
      visitDeoptBegin(
          AbstractBeginNode.prevBegin(d), d.action(), d.reason(), d.getSpeculation(), graph);
    }

    if (context != null) {
      for (FixedGuardNode fixedGuard : graph.getNodes(FixedGuardNode.TYPE)) {
        trySplitFixedGuard(fixedGuard, context);
      }
    }

    new DeadCodeEliminationPhase(Optional).apply(graph);
  }
 @Test
 public void testSimple() {
   for (TestMode mode : TestMode.values()) {
     ScheduleResult schedule = getFinalSchedule("testSimpleSnippet", mode);
     StructuredGraph graph = schedule.getCFG().graph;
     assertReadAndWriteInSameBlock(schedule, true);
     assertOrderedAfterSchedule(
         schedule,
         graph.getNodes().filter(FloatingReadNode.class).first(),
         graph.getNodes().filter(WriteNode.class).first());
   }
 }
 @Override
 protected boolean checkLowTierGraph(StructuredGraph graph) {
   for (ConstantNode constantNode : graph.getNodes().filter(ConstantNode.class)) {
     assert constantNode.asJavaConstant() == null
             || constantNode.asJavaConstant().getJavaKind() != JavaKind.Object
             || constantNode.asJavaConstant().isDefaultForKind()
         : "Found unexpected object constant "
             + constantNode
             + ", this should have been removed by the LoadJavaMirrorWithKlassPhase.";
   }
   return true;
 }
 @Override
 protected boolean checkMidTierGraph(StructuredGraph graph) {
   int count = 0;
   for (IsNullNode isNull : graph.getNodes().filter(IsNullNode.class).snapshot()) {
     ValueNode value = isNull.getValue();
     if (value instanceof CompressionNode) {
       count++;
       isNull.replaceFirstInput(value, ((CompressionNode) value).getValue());
     }
   }
   Assert.assertEquals("graph should contain exactly one IsNullNode", 1, count);
   return super.checkMidTierGraph(graph);
 }
Example #12
0
 @Test
 public void testValueProxyInputs() {
   StructuredGraph graph = parseEager("testValueProxyInputsSnippet", AllowAssumptions.YES);
   for (FrameState fs : graph.getNodes().filter(FrameState.class).snapshot()) {
     fs.replaceAtUsages(null);
     GraphUtil.killWithUnusedFloatingInputs(fs);
   }
   SchedulePhase schedulePhase = new SchedulePhase(SchedulingStrategy.LATEST);
   schedulePhase.apply(graph);
   ScheduleResult schedule = graph.getLastSchedule();
   NodeMap<Block> nodeToBlock = schedule.getCFG().getNodeToBlock();
   assertTrue(graph.getNodes().filter(LoopExitNode.class).count() == 1);
   LoopExitNode loopExit = graph.getNodes().filter(LoopExitNode.class).first();
   List<Node> list = schedule.nodesFor(nodeToBlock.get(loopExit));
   for (BinaryArithmeticNode<?> node : graph.getNodes().filter(BinaryArithmeticNode.class)) {
     if (!(node instanceof AddNode)) {
       assertTrue(node.toString(), nodeToBlock.get(node) == nodeToBlock.get(loopExit));
       assertTrue(
           list.indexOf(node) + " < " + list.indexOf(loopExit) + ", " + node + ", " + loopExit,
           list.indexOf(node) < list.indexOf(loopExit));
     }
   }
 }
  @SuppressWarnings("try")
  private ScheduleResult getFinalSchedule(
      final String snippet, final TestMode mode, final SchedulingStrategy schedulingStrategy) {
    final StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
    try (Scope d = Debug.scope("FloatingReadTest", graph)) {
      try (OverrideScope s =
          OptionValue.override(
              OptScheduleOutOfLoops,
              schedulingStrategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS,
              OptImplicitNullChecks,
              false)) {
        HighTierContext context = getDefaultHighTierContext();
        CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
        canonicalizer.apply(graph, context);
        if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) {
          new InliningPhase(canonicalizer).apply(graph, context);
        }
        new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER)
            .apply(graph, context);
        if (mode == TestMode.WITHOUT_FRAMESTATES || mode == TestMode.INLINED_WITHOUT_FRAMESTATES) {
          graph.clearAllStateAfter();
        }
        Debug.dump(graph, "after removal of framestates");

        new FloatingReadPhase().apply(graph);
        new RemoveValueProxyPhase().apply(graph);

        MidTierContext midContext =
            new MidTierContext(
                getProviders(),
                getTargetProvider(),
                OptimisticOptimizations.ALL,
                graph.getProfilingInfo());
        new GuardLoweringPhase().apply(graph, midContext);
        new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER)
            .apply(graph, midContext);
        new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.LOW_TIER)
            .apply(graph, midContext);

        SchedulePhase schedule = new SchedulePhase(schedulingStrategy);
        schedule.apply(graph);
        assertDeepEquals(1, graph.getNodes().filter(StartNode.class).count());
        return graph.getLastSchedule();
      }
    } catch (Throwable e) {
      throw Debug.handle(e);
    }
  }
  private static void deleteNodes(NodeFlood flood, StructuredGraph graph) {
    BiConsumer<Node, Node> consumer =
        (n, input) -> {
          if (input.isAlive() && flood.isMarked(input)) {
            input.removeUsage(n);
          }
        };

    for (Node node : graph.getNodes()) {
      if (!flood.isMarked(node)) {
        node.markDeleted();
        node.acceptInputs(consumer);
        metricNodesRemoved.increment();
      }
    }
  }
Example #15
0
  private void testMethod(Method method, Object receiver, Object... args) {
    try {
      // Invoke the method to ensure it has a type profile
      for (int i = 0; i < 5000; i++) {
        method.invoke(receiver, args);
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

    ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method);
    StructuredGraph g = parseProfiled(javaMethod, AllowAssumptions.NO);
    HighTierContext context = getDefaultHighTierContext();
    new InliningPhase(new InlineMethodSubstitutionsPolicy(), new CanonicalizerPhase())
        .apply(g, context);
    new CanonicalizerPhase().apply(g, context);
    Assert.assertTrue(g.getNodes().filter(CheckCastNode.class).isEmpty());
  }
 private static Stream<Class<?>> nodeClassStream(StructuredGraph graph) {
   return StreamSupport.stream(graph.getNodes().spliterator(), false).map(node -> node.getClass());
 }
 private static void assertReadAndWriteInSameBlock(ScheduleResult schedule, boolean inSame) {
   StructuredGraph graph = schedule.getCFG().graph;
   FloatingReadNode read = graph.getNodes().filter(FloatingReadNode.class).first();
   WriteNode write = graph.getNodes().filter(WriteNode.class).first();
   assertTrue(!(inSame ^ schedule.getCFG().blockFor(read) == schedule.getCFG().blockFor(write)));
 }
Example #18
0
    private void scheduleEarliestIterative(
        BlockMap<List<Node>> blockToNodes,
        NodeMap<Block> nodeToBlock,
        NodeBitMap visited,
        StructuredGraph graph,
        boolean immutableGraph) {

      BitSet floatingReads = new BitSet(cfg.getBlocks().length);

      // Add begin nodes as the first entry and set the block for phi nodes.
      for (Block b : cfg.getBlocks()) {
        AbstractBeginNode beginNode = b.getBeginNode();
        ArrayList<Node> nodes = new ArrayList<>();
        nodeToBlock.set(beginNode, b);
        nodes.add(beginNode);
        blockToNodes.put(b, nodes);

        if (beginNode instanceof AbstractMergeNode) {
          AbstractMergeNode mergeNode = (AbstractMergeNode) beginNode;
          for (PhiNode phi : mergeNode.phis()) {
            nodeToBlock.set(phi, b);
          }
        } else if (beginNode instanceof LoopExitNode) {
          LoopExitNode loopExitNode = (LoopExitNode) beginNode;
          for (ProxyNode proxy : loopExitNode.proxies()) {
            nodeToBlock.set(proxy, b);
          }
        }
      }

      NodeStack stack = new NodeStack();

      // Start analysis with control flow ends.
      Block[] reversePostOrder = cfg.reversePostOrder();
      for (int j = reversePostOrder.length - 1; j >= 0; --j) {
        Block b = reversePostOrder[j];
        FixedNode endNode = b.getEndNode();
        if (isFixedEnd(endNode)) {
          stack.push(endNode);
          nodeToBlock.set(endNode, b);
        }
      }

      processStack(cfg, blockToNodes, nodeToBlock, visited, floatingReads, stack);

      // Visit back input edges of loop phis.
      boolean changed;
      boolean unmarkedPhi;
      do {
        changed = false;
        unmarkedPhi = false;
        for (LoopBeginNode loopBegin : graph.getNodes(LoopBeginNode.TYPE)) {
          for (PhiNode phi : loopBegin.phis()) {
            if (visited.isMarked(phi)) {
              for (int i = 0; i < loopBegin.getLoopEndCount(); ++i) {
                Node node = phi.valueAt(i + loopBegin.forwardEndCount());
                if (node != null && !visited.isMarked(node)) {
                  changed = true;
                  stack.push(node);
                  processStack(cfg, blockToNodes, nodeToBlock, visited, floatingReads, stack);
                }
              }
            } else {
              unmarkedPhi = true;
            }
          }
        }

        /*
         * the processing of one loop phi could have marked a previously checked loop phi,
         * therefore this needs to be iterative.
         */
      } while (unmarkedPhi && changed);

      // Check for dead nodes.
      if (!immutableGraph && visited.getCounter() < graph.getNodeCount()) {
        for (Node n : graph.getNodes()) {
          if (!visited.isMarked(n)) {
            n.clearInputs();
            n.markDeleted();
          }
        }
      }

      // Add end nodes as the last nodes in each block.
      for (Block b : cfg.getBlocks()) {
        FixedNode endNode = b.getEndNode();
        if (isFixedEnd(endNode)) {
          if (endNode != b.getBeginNode()) {
            addNode(blockToNodes, b, endNode);
          }
        }
      }

      if (!floatingReads.isEmpty()) {
        for (Block b : cfg.getBlocks()) {
          if (floatingReads.get(b.getId())) {
            resortEarliestWithinBlock(b, blockToNodes, nodeToBlock, visited);
          }
        }
      }

      assert MemoryScheduleVerification.check(cfg.getStartBlock(), blockToNodes);
    }