Search in sources :

Example 1 with OpaqueNode

use of org.graalvm.compiler.nodes.extended.OpaqueNode in project graal by oracle.

the class LongNodeChainTest method longAddChain.

private void longAddChain(boolean reverse) {
    HighTierContext context = getDefaultHighTierContext();
    OptionValues options = getInitialOptions();
    StructuredGraph graph = new StructuredGraph.Builder(options, new Builder(options).build()).build();
    ValueNode constant = graph.unique(ConstantNode.forPrimitive(JavaConstant.INT_1));
    ValueNode value = null;
    if (reverse) {
        // Make sure the constant's stamp is not used to infer the add node's stamp.
        OpaqueNode opaque = graph.unique(new OpaqueNode(constant));
        constant = opaque;
        AddNode addNode = graph.unique(new AddNode(constant, constant));
        value = addNode;
        for (int i = 1; i < N; ++i) {
            AddNode newAddNode = graph.addWithoutUnique(new AddNode(constant, constant));
            addNode.setY(newAddNode);
            addNode = newAddNode;
        }
        opaque.remove();
    } else {
        value = constant;
        for (int i = 0; i < N; ++i) {
            value = graph.unique(new AddNode(constant, value));
        }
    }
    ReturnNode returnNode = graph.add(new ReturnNode(value));
    graph.start().setNext(returnNode);
    for (SchedulingStrategy s : Strategies) {
        SchedulePhase.runWithoutContextOptimizations(graph, s);
    }
    this.createCanonicalizerPhase().apply(graph, context);
    JavaConstant asConstant = (JavaConstant) returnNode.result().asConstant();
    Assert.assertEquals(N + 1, asConstant.asInt());
}
Also used : ReturnNode(org.graalvm.compiler.nodes.ReturnNode) SchedulingStrategy(org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy) OptionValues(org.graalvm.compiler.options.OptionValues) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) Builder(org.graalvm.compiler.debug.DebugContext.Builder) ValueNode(org.graalvm.compiler.nodes.ValueNode) JavaConstant(jdk.vm.ci.meta.JavaConstant) HighTierContext(org.graalvm.compiler.phases.tiers.HighTierContext) OpaqueNode(org.graalvm.compiler.nodes.extended.OpaqueNode) AddNode(org.graalvm.compiler.nodes.calc.AddNode)

Example 2 with OpaqueNode

use of org.graalvm.compiler.nodes.extended.OpaqueNode in project graal by oracle.

the class UnschedulableGraphTest method checkLowTierGraph.

@Override
protected void checkLowTierGraph(StructuredGraph graph) {
    super.checkLowTierGraph(graph);
    ScheduleResult res = graph.getLastSchedule();
    BlockMap<List<Node>> blockToNode = res.getBlockToNodesMap();
    NodeMap<Block> nodeToBlock = res.getNodeToBlockMap();
    Assert.assertEquals(4, res.getCFG().getBlocks().length);
    Block split = res.getCFG().getStartBlock();
    Assert.assertEquals(2, split.getSuccessorCount());
    Block trueSucc = split.getSuccessors()[0];
    Block falseSucc = split.getSuccessors()[1];
    Block merge = trueSucc.getFirstSuccessor();
    Assert.assertEquals(merge, falseSucc.getFirstSuccessor());
    for (OpaqueNode op : graph.getNodes().filter(OpaqueNode.class)) {
        Assert.assertEquals(merge, res.getNodeToBlockMap().get(op));
    }
    int k = 0;
    // destroy dominance relation for NegateNode nodes, they no longer dominate the addition
    for (NegateNode op : graph.getNodes().filter(NegateNode.class)) {
        final Block nonDominatingBlock = k++ % 2 == 0 ? trueSucc : falseSucc;
        blockToNode.get(merge).remove(op);
        blockToNode.get(nonDominatingBlock).add(0, op);
        nodeToBlock.set(op, nonDominatingBlock);
    }
    graph.getDebug().dump(DebugContext.VERBOSE_LEVEL, graph, "After changing constant schedule");
}
Also used : ScheduleResult(org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult) NegateNode(org.graalvm.compiler.nodes.calc.NegateNode) Block(org.graalvm.compiler.nodes.cfg.Block) List(java.util.List) OpaqueNode(org.graalvm.compiler.nodes.extended.OpaqueNode)

Example 3 with OpaqueNode

use of org.graalvm.compiler.nodes.extended.OpaqueNode in project graal by oracle.

the class LoopPartialUnrollPhase method unroll.

@SuppressWarnings("try")
private void unroll(StructuredGraph graph, CoreProviders context) {
    EconomicSetNodeEventListener listener = new EconomicSetNodeEventListener();
    boolean changed = true;
    EconomicMap<LoopBeginNode, OpaqueNode> opaqueUnrolledStrides = null;
    boolean prePostInserted = false;
    while (changed) {
        changed = false;
        try (Graph.NodeEventScope nes = graph.trackNodeEvents(listener)) {
            LoopsData dataCounted = context.getLoopsDataProvider().getLoopsData(graph);
            dataCounted.detectedCountedLoops();
            Graph.Mark mark = graph.getMark();
            for (LoopEx loop : dataCounted.countedLoops()) {
                if (!LoopTransformations.isUnrollableLoop(loop)) {
                    continue;
                }
                if (getPolicies().shouldPartiallyUnroll(loop, context)) {
                    if (loop.loopBegin().isSimpleLoop()) {
                        // First perform the pre/post transformation and do the partial
                        // unroll when we come around again.
                        LoopTransformations.insertPrePostLoops(loop);
                        prePostInserted = true;
                        changed = true;
                    } else if (prePostInserted) {
                        if (opaqueUnrolledStrides == null) {
                            opaqueUnrolledStrides = EconomicMap.create(Equivalence.IDENTITY);
                        }
                        LoopTransformations.partialUnroll(loop, opaqueUnrolledStrides);
                        changed = true;
                    }
                }
            }
            dataCounted.deleteUnusedNodes();
            if (!listener.getNodes().isEmpty()) {
                canonicalizer.applyIncremental(graph, context, listener.getNodes());
                listener.getNodes().clear();
            }
            assert !prePostInserted || checkCounted(graph, context.getLoopsDataProvider(), mark);
        }
    }
    if (opaqueUnrolledStrides != null) {
        try (Graph.NodeEventScope nes = graph.trackNodeEvents(listener)) {
            for (OpaqueNode opaque : opaqueUnrolledStrides.getValues()) {
                opaque.remove();
            }
            if (!listener.getNodes().isEmpty()) {
                canonicalizer.applyIncremental(graph, context, listener.getNodes());
            }
        }
    }
}
Also used : LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) Graph(org.graalvm.compiler.graph.Graph) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) LoopsData(org.graalvm.compiler.nodes.loop.LoopsData) LoopEx(org.graalvm.compiler.nodes.loop.LoopEx) OpaqueNode(org.graalvm.compiler.nodes.extended.OpaqueNode) EconomicSetNodeEventListener(org.graalvm.compiler.phases.common.util.EconomicSetNodeEventListener)

Example 4 with OpaqueNode

use of org.graalvm.compiler.nodes.extended.OpaqueNode in project graal by oracle.

the class DataPatchTest method registerInvocationPlugins.

@Override
protected void registerInvocationPlugins(InvocationPlugins invocationPlugins) {
    Registration r = new Registration(invocationPlugins, DataPatchTest.class);
    r.register(new InvocationPlugin("compressUncompress", Object.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
            CompressEncoding encoding = runtime().getVMConfig().getOopEncoding();
            ValueNode compressed = b.add(HotSpotCompressionNode.compress(arg, encoding));
            ValueNode proxy = b.add(new OpaqueNode(compressed));
            b.addPush(JavaKind.Object, HotSpotCompressionNode.uncompress(proxy, encoding));
            return true;
        }
    });
    super.registerInvocationPlugins(invocationPlugins);
}
Also used : GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) ValueNode(org.graalvm.compiler.nodes.ValueNode) CompressEncoding(org.graalvm.compiler.core.common.CompressEncoding) InvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin) OpaqueNode(org.graalvm.compiler.nodes.extended.OpaqueNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 5 with OpaqueNode

use of org.graalvm.compiler.nodes.extended.OpaqueNode in project graal by oracle.

the class LoopFragmentInside method insertWithinAfter.

/**
 * Duplicate the body within the loop after the current copy copy of the body, updating the
 * iteration limit to account for the duplication.
 */
public void insertWithinAfter(LoopEx loop, EconomicMap<LoopBeginNode, OpaqueNode> opaqueUnrolledStrides) {
    assert isDuplicate() && original().loop() == loop;
    patchNodes(dataFixWithinAfter);
    /*
         * Collect any new back edges values before updating them since they might reference each
         * other.
         */
    LoopBeginNode mainLoopBegin = loop.loopBegin();
    ArrayList<ValueNode> backedgeValues = new ArrayList<>();
    EconomicMap<Node, Node> new2OldPhis = EconomicMap.create();
    EconomicMap<Node, Node> originalPhi2Backedges = EconomicMap.create();
    for (PhiNode mainPhiNode : mainLoopBegin.phis()) {
        originalPhi2Backedges.put(mainPhiNode, mainPhiNode.valueAt(1));
    }
    for (PhiNode mainPhiNode : mainLoopBegin.phis()) {
        ValueNode originalNode = mainPhiNode.valueAt(1);
        ValueNode duplicatedNode = getDuplicatedNode(originalNode);
        if (duplicatedNode == null) {
            if (mainLoopBegin.isPhiAtMerge(originalNode)) {
                duplicatedNode = ((PhiNode) (originalNode)).valueAt(1);
            } else {
                assert originalNode.isConstant() || loop.isOutsideLoop(originalNode) : "Not duplicated node " + originalNode;
            }
        }
        if (duplicatedNode != null) {
            new2OldPhis.put(duplicatedNode, originalNode);
        }
        backedgeValues.add(duplicatedNode);
    }
    int index = 0;
    for (PhiNode mainPhiNode : mainLoopBegin.phis()) {
        ValueNode duplicatedNode = backedgeValues.get(index++);
        if (duplicatedNode != null) {
            mainPhiNode.setValueAt(1, duplicatedNode);
        }
    }
    CompareNode condition = placeNewSegmentAndCleanup(loop, new2OldPhis, originalPhi2Backedges);
    // Remove any safepoints from the original copy leaving only the duplicated one
    assert loop.whole().nodes().filter(SafepointNode.class).count() == nodes().filter(SafepointNode.class).count();
    for (SafepointNode safepoint : loop.whole().nodes().filter(SafepointNode.class)) {
        graph().removeFixed(safepoint);
    }
    StructuredGraph graph = mainLoopBegin.graph();
    if (opaqueUnrolledStrides != null) {
        OpaqueNode opaque = opaqueUnrolledStrides.get(loop.loopBegin());
        CountedLoopInfo counted = loop.counted();
        ValueNode counterStride = counted.getLimitCheckedIV().strideNode();
        if (opaque == null || opaque.isDeleted()) {
            ValueNode limit = counted.getLimit();
            opaque = new OpaqueNode(AddNode.add(counterStride, counterStride, NodeView.DEFAULT));
            ValueNode newLimit = partialUnrollOverflowCheck(opaque, limit, counted);
            condition.replaceFirstInput(limit, graph.addOrUniqueWithInputs(newLimit));
            opaqueUnrolledStrides.put(loop.loopBegin(), opaque);
        } else {
            assert counted.getLimitCheckedIV().isConstantStride();
            assert Math.addExact(counted.getLimitCheckedIV().constantStride(), counted.getLimitCheckedIV().constantStride()) == counted.getLimitCheckedIV().constantStride() * 2;
            ValueNode previousValue = opaque.getValue();
            opaque.setValue(graph.addOrUniqueWithInputs(AddNode.add(counterStride, previousValue, NodeView.DEFAULT)));
            GraphUtil.tryKillUnused(previousValue);
        }
    }
    mainLoopBegin.setUnrollFactor(mainLoopBegin.getUnrollFactor() * 2);
    graph.getDebug().dump(DebugContext.DETAILED_LEVEL, graph, "LoopPartialUnroll %s", loop);
    mainLoopBegin.getDebug().dump(DebugContext.VERBOSE_LEVEL, mainLoopBegin.graph(), "After insertWithinAfter %s", mainLoopBegin);
}
Also used : ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) MemoryPhiNode(org.graalvm.compiler.nodes.memory.MemoryPhiNode) GuardPhiNode(org.graalvm.compiler.nodes.GuardPhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) SafepointNode(org.graalvm.compiler.nodes.SafepointNode) ValueAnchorNode(org.graalvm.compiler.nodes.extended.ValueAnchorNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) OpaqueNode(org.graalvm.compiler.nodes.extended.OpaqueNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) IfNode(org.graalvm.compiler.nodes.IfNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) GuardingNode(org.graalvm.compiler.nodes.extended.GuardingNode) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) AnchoringNode(org.graalvm.compiler.nodes.extended.AnchoringNode) MemoryPhiNode(org.graalvm.compiler.nodes.memory.MemoryPhiNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) GuardProxyNode(org.graalvm.compiler.nodes.GuardProxyNode) AddNode(org.graalvm.compiler.nodes.calc.AddNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) ConditionalNode(org.graalvm.compiler.nodes.calc.ConditionalNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IntegerBelowNode(org.graalvm.compiler.nodes.calc.IntegerBelowNode) MemoryProxyNode(org.graalvm.compiler.nodes.MemoryProxyNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) SubNode(org.graalvm.compiler.nodes.calc.SubNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) SafepointNode(org.graalvm.compiler.nodes.SafepointNode) ValueProxyNode(org.graalvm.compiler.nodes.ValueProxyNode) GuardPhiNode(org.graalvm.compiler.nodes.GuardPhiNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) ArrayList(java.util.ArrayList) OpaqueNode(org.graalvm.compiler.nodes.extended.OpaqueNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Aggregations

OpaqueNode (org.graalvm.compiler.nodes.extended.OpaqueNode)7 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)4 ValueNode (org.graalvm.compiler.nodes.ValueNode)4 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)2 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)2 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)2 AddNode (org.graalvm.compiler.nodes.calc.AddNode)2 GraphBuilderContext (org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext)2 Registration (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration)2 ArrayList (java.util.ArrayList)1 List (java.util.List)1 DeoptimizationAction (jdk.vm.ci.meta.DeoptimizationAction)1 DeoptimizationReason (jdk.vm.ci.meta.DeoptimizationReason)1 JavaConstant (jdk.vm.ci.meta.JavaConstant)1 JavaKind (jdk.vm.ci.meta.JavaKind)1 SpeculationReason (jdk.vm.ci.meta.SpeculationLog.SpeculationReason)1 CompressEncoding (org.graalvm.compiler.core.common.CompressEncoding)1 FloatStamp (org.graalvm.compiler.core.common.type.FloatStamp)1 IntegerStamp (org.graalvm.compiler.core.common.type.IntegerStamp)1 Builder (org.graalvm.compiler.debug.DebugContext.Builder)1