Search in sources :

Example 26 with Graph

use of org.graalvm.compiler.graph.Graph in project graal by oracle.

the class TypedNodeIteratorTest2 method simpleSubclassTest.

@Test
public void simpleSubclassTest() {
    Graph graph = new Graph(getOptions(), getDebug());
    graph.add(new NodeB("b"));
    graph.add(new NodeD("d"));
    Assert.assertEquals("bd", TypedNodeIteratorTest.toString(graph.getNodes(NodeB.TYPE)));
    Assert.assertEquals("d", TypedNodeIteratorTest.toString(graph.getNodes(NodeD.TYPE)));
}
Also used : Graph(org.graalvm.compiler.graph.Graph) Test(org.junit.Test)

Example 27 with Graph

use of org.graalvm.compiler.graph.Graph in project graal by oracle.

the class LoopFragment method computeNodes.

protected static void computeNodes(NodeBitMap nodes, Graph graph, Iterable<AbstractBeginNode> blocks, Iterable<AbstractBeginNode> earlyExits) {
    for (AbstractBeginNode b : blocks) {
        if (b.isDeleted()) {
            continue;
        }
        for (Node n : b.getBlockNodes()) {
            if (n instanceof Invoke) {
                nodes.mark(((Invoke) n).callTarget());
            }
            if (n instanceof NodeWithState) {
                NodeWithState withState = (NodeWithState) n;
                withState.states().forEach(state -> state.applyToVirtual(node -> nodes.mark(node)));
            }
            if (n instanceof AbstractMergeNode) {
                // if a merge is in the loop, all of its phis are also in the loop
                for (PhiNode phi : ((AbstractMergeNode) n).phis()) {
                    nodes.mark(phi);
                }
            }
            nodes.mark(n);
        }
    }
    for (AbstractBeginNode earlyExit : earlyExits) {
        if (earlyExit.isDeleted()) {
            continue;
        }
        nodes.mark(earlyExit);
        if (earlyExit instanceof LoopExitNode) {
            LoopExitNode loopExit = (LoopExitNode) earlyExit;
            FrameState stateAfter = loopExit.stateAfter();
            if (stateAfter != null) {
                stateAfter.applyToVirtual(node -> nodes.mark(node));
            }
            for (ProxyNode proxy : loopExit.proxies()) {
                nodes.mark(proxy);
            }
        }
    }
    final NodeBitMap nonLoopNodes = graph.createNodeBitMap();
    Deque<WorkListEntry> worklist = new ArrayDeque<>();
    for (AbstractBeginNode b : blocks) {
        if (b.isDeleted()) {
            continue;
        }
        for (Node n : b.getBlockNodes()) {
            if (n instanceof CommitAllocationNode) {
                for (VirtualObjectNode obj : ((CommitAllocationNode) n).getVirtualObjects()) {
                    markFloating(worklist, obj, nodes, nonLoopNodes);
                }
            }
            if (n instanceof MonitorEnterNode) {
                markFloating(worklist, ((MonitorEnterNode) n).getMonitorId(), nodes, nonLoopNodes);
            }
            if (n instanceof AbstractMergeNode) {
                /*
                     * Since we already marked all phi nodes as being in the loop to break cycles,
                     * we also have to iterate over their usages here.
                     */
                for (PhiNode phi : ((AbstractMergeNode) n).phis()) {
                    for (Node usage : phi.usages()) {
                        markFloating(worklist, usage, nodes, nonLoopNodes);
                    }
                }
            }
            for (Node usage : n.usages()) {
                markFloating(worklist, usage, nodes, nonLoopNodes);
            }
        }
    }
}
Also used : GuardNode(org.graalvm.compiler.nodes.GuardNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) GuardProxyNode(org.graalvm.compiler.nodes.GuardProxyNode) Deque(java.util.Deque) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) TriState(jdk.vm.ci.meta.TriState) EconomicMap(org.graalvm.collections.EconomicMap) MergeNode(org.graalvm.compiler.nodes.MergeNode) VirtualState(org.graalvm.compiler.nodes.VirtualState) FixedNode(org.graalvm.compiler.nodes.FixedNode) NodeWithState(org.graalvm.compiler.nodes.spi.NodeWithState) Iterator(java.util.Iterator) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) NodeView(org.graalvm.compiler.nodes.NodeView) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) NodeBitMap(org.graalvm.compiler.graph.NodeBitMap) CommitAllocationNode(org.graalvm.compiler.nodes.virtual.CommitAllocationNode) Graph(org.graalvm.compiler.graph.Graph) ValueNode(org.graalvm.compiler.nodes.ValueNode) ValueProxyNode(org.graalvm.compiler.nodes.ValueProxyNode) DuplicationReplacement(org.graalvm.compiler.graph.Graph.DuplicationReplacement) GuardPhiNode(org.graalvm.compiler.nodes.GuardPhiNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) FrameState(org.graalvm.compiler.nodes.FrameState) NodeIterable(org.graalvm.compiler.graph.iterators.NodeIterable) Invoke(org.graalvm.compiler.nodes.Invoke) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) MonitorEnterNode(org.graalvm.compiler.nodes.java.MonitorEnterNode) Block(org.graalvm.compiler.nodes.cfg.Block) GraalError(org.graalvm.compiler.debug.GraalError) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) ArrayDeque(java.util.ArrayDeque) Collections(java.util.Collections) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) GuardProxyNode(org.graalvm.compiler.nodes.GuardProxyNode) ValueProxyNode(org.graalvm.compiler.nodes.ValueProxyNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) GuardPhiNode(org.graalvm.compiler.nodes.GuardPhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) NodeBitMap(org.graalvm.compiler.graph.NodeBitMap) GuardNode(org.graalvm.compiler.nodes.GuardNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) GuardProxyNode(org.graalvm.compiler.nodes.GuardProxyNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) CommitAllocationNode(org.graalvm.compiler.nodes.virtual.CommitAllocationNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) ValueProxyNode(org.graalvm.compiler.nodes.ValueProxyNode) GuardPhiNode(org.graalvm.compiler.nodes.GuardPhiNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) MonitorEnterNode(org.graalvm.compiler.nodes.java.MonitorEnterNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FrameState(org.graalvm.compiler.nodes.FrameState) ArrayDeque(java.util.ArrayDeque) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) Invoke(org.graalvm.compiler.nodes.Invoke) MonitorEnterNode(org.graalvm.compiler.nodes.java.MonitorEnterNode) NodeWithState(org.graalvm.compiler.nodes.spi.NodeWithState) CommitAllocationNode(org.graalvm.compiler.nodes.virtual.CommitAllocationNode)

Example 28 with Graph

use of org.graalvm.compiler.graph.Graph in project graal by oracle.

the class ExpandLogicPhase method processConditional.

@SuppressWarnings("try")
private static void processConditional(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, ConditionalNode conditional) {
    try (DebugCloseable context = conditional.withNodeSourcePosition()) {
        ValueNode trueTarget = conditional.trueValue();
        ValueNode falseTarget = conditional.falseValue();
        Graph graph = conditional.graph();
        ConditionalNode secondConditional = graph.unique(new ConditionalNode(y, yNegated ? falseTarget : trueTarget, yNegated ? trueTarget : falseTarget));
        ConditionalNode firstConditional = graph.unique(new ConditionalNode(x, xNegated ? secondConditional : trueTarget, xNegated ? trueTarget : secondConditional));
        conditional.replaceAndDelete(firstConditional);
    }
}
Also used : Graph(org.graalvm.compiler.graph.Graph) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ConditionalNode(org.graalvm.compiler.nodes.calc.ConditionalNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) DebugCloseable(org.graalvm.compiler.debug.DebugCloseable)

Example 29 with Graph

use of org.graalvm.compiler.graph.Graph in project graal by oracle.

the class ExpandLogicPhase method processIf.

@SuppressWarnings("try")
private static void processIf(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, IfNode ifNode, double shortCircuitProbability) {
    try (DebugCloseable context = ifNode.withNodeSourcePosition()) {
        /*
             * this method splits an IfNode, which has a ShortCircuitOrNode as its condition, into
             * two separate IfNodes: if(X) and if(Y)
             *
             * for computing the probabilities P(X) and P(Y), we use two different approaches. The
             * first one assumes that the shortCircuitProbability and the probability on the IfNode
             * were created with each other in mind. If this assumption does not hold, we fall back
             * to another mechanism for computing the probabilities.
             */
        AbstractBeginNode trueTarget = ifNode.trueSuccessor();
        AbstractBeginNode falseTarget = ifNode.falseSuccessor();
        // 1st approach
        // assumption: P(originalIf.trueSuccessor) == P(X) + ((1 - P(X)) * P(Y))
        double firstIfTrueProbability = shortCircuitProbability;
        double secondIfTrueProbability = sanitizeProbability((ifNode.getTrueSuccessorProbability() - shortCircuitProbability) / (1 - shortCircuitProbability));
        double expectedOriginalIfTrueProbability = firstIfTrueProbability + (1 - firstIfTrueProbability) * secondIfTrueProbability;
        if (!doubleEquals(ifNode.getTrueSuccessorProbability(), expectedOriginalIfTrueProbability)) {
            /*
                 * 2nd approach
                 *
                 * the assumption above did not hold, so we either used an artificial probability as
                 * shortCircuitProbability or the ShortCircuitOrNode was moved to some other IfNode.
                 *
                 * so, we distribute the if's trueSuccessorProbability between the newly generated
                 * if nodes according to the shortCircuitProbability. the following invariant is
                 * always true in this case: P(originalIf.trueSuccessor) == P(X) + ((1 - P(X)) *
                 * P(Y))
                 */
            firstIfTrueProbability = ifNode.getTrueSuccessorProbability() * shortCircuitProbability;
            secondIfTrueProbability = sanitizeProbability(1 - (ifNode.probability(falseTarget) / (1 - firstIfTrueProbability)));
        }
        ifNode.clearSuccessors();
        Graph graph = ifNode.graph();
        AbstractMergeNode trueTargetMerge = graph.add(new MergeNode());
        trueTargetMerge.setNext(trueTarget);
        EndNode firstTrueEnd = graph.add(new EndNode());
        EndNode secondTrueEnd = graph.add(new EndNode());
        trueTargetMerge.addForwardEnd(firstTrueEnd);
        trueTargetMerge.addForwardEnd(secondTrueEnd);
        AbstractBeginNode firstTrueTarget = BeginNode.begin(firstTrueEnd);
        AbstractBeginNode secondTrueTarget = BeginNode.begin(secondTrueEnd);
        if (yNegated) {
            secondIfTrueProbability = 1.0 - secondIfTrueProbability;
        }
        if (xNegated) {
            firstIfTrueProbability = 1.0 - firstIfTrueProbability;
        }
        AbstractBeginNode secondIf = BeginNode.begin(graph.add(new IfNode(y, yNegated ? falseTarget : secondTrueTarget, yNegated ? secondTrueTarget : falseTarget, secondIfTrueProbability)));
        IfNode firstIf = graph.add(new IfNode(x, xNegated ? secondIf : firstTrueTarget, xNegated ? firstTrueTarget : secondIf, firstIfTrueProbability));
        ifNode.replaceAtPredecessor(firstIf);
        ifNode.safeDelete();
    }
}
Also used : AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) Graph(org.graalvm.compiler.graph.Graph) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) EndNode(org.graalvm.compiler.nodes.EndNode) DebugCloseable(org.graalvm.compiler.debug.DebugCloseable) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) IfNode(org.graalvm.compiler.nodes.IfNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Example 30 with Graph

use of org.graalvm.compiler.graph.Graph in project graal by oracle.

the class LoopPartialUnrollPhase method run.

@Override
@SuppressWarnings("try")
protected void run(StructuredGraph graph, PhaseContext context) {
    if (graph.hasLoops()) {
        HashSetNodeEventListener listener = new HashSetNodeEventListener();
        boolean changed = true;
        while (changed) {
            changed = false;
            try (Graph.NodeEventScope nes = graph.trackNodeEvents(listener)) {
                LoopsData dataCounted = new LoopsData(graph);
                dataCounted.detectedCountedLoops();
                Graph.Mark mark = graph.getMark();
                boolean prePostInserted = false;
                for (LoopEx loop : dataCounted.countedLoops()) {
                    if (!LoopTransformations.isUnrollableLoop(loop)) {
                        continue;
                    }
                    if (getPolicies().shouldPartiallyUnroll(loop)) {
                        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;
                        } else {
                            LoopTransformations.partialUnroll(loop);
                        }
                        changed = true;
                    }
                }
                dataCounted.deleteUnusedNodes();
                if (!listener.getNodes().isEmpty()) {
                    canonicalizer.applyIncremental(graph, context, listener.getNodes());
                    listener.getNodes().clear();
                }
                assert !prePostInserted || checkCounted(graph, mark);
            }
        }
    }
}
Also used : HashSetNodeEventListener(org.graalvm.compiler.phases.common.util.HashSetNodeEventListener) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) Graph(org.graalvm.compiler.graph.Graph) LoopsData(org.graalvm.compiler.loop.LoopsData) LoopEx(org.graalvm.compiler.loop.LoopEx)

Aggregations

Graph (org.graalvm.compiler.graph.Graph)33 Test (org.junit.Test)22 OptionValues (org.graalvm.compiler.options.OptionValues)21 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)8 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)3 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)3 EndNode (org.graalvm.compiler.nodes.EndNode)3 FixedNode (org.graalvm.compiler.nodes.FixedNode)3 ValueNode (org.graalvm.compiler.nodes.ValueNode)3 DebugCloseable (org.graalvm.compiler.debug.DebugCloseable)2 DebugContext (org.graalvm.compiler.debug.DebugContext)2 DuplicationReplacement (org.graalvm.compiler.graph.Graph.DuplicationReplacement)2 Node (org.graalvm.compiler.graph.Node)2 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)2 MergeNode (org.graalvm.compiler.nodes.MergeNode)2 Before (org.junit.Before)2 IOException (java.io.IOException)1 ArrayDeque (java.util.ArrayDeque)1 Collections (java.util.Collections)1 Deque (java.util.Deque)1