Search in sources :

Example 46 with Node

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

the class NodeLIRBuilder method doBlock.

@Override
@SuppressWarnings("try")
public void doBlock(Block block, StructuredGraph graph, BlockMap<List<Node>> blockMap) {
    OptionValues options = graph.getOptions();
    try (BlockScope blockScope = gen.getBlockScope(block)) {
        setSourcePosition(null);
        if (block == gen.getResult().getLIR().getControlFlowGraph().getStartBlock()) {
            assert block.getPredecessorCount() == 0;
            emitPrologue(graph);
        } else {
            assert block.getPredecessorCount() > 0;
            // create phi-in value array
            AbstractBeginNode begin = block.getBeginNode();
            if (begin instanceof AbstractMergeNode) {
                AbstractMergeNode merge = (AbstractMergeNode) begin;
                LabelOp label = (LabelOp) gen.getResult().getLIR().getLIRforBlock(block).get(0);
                label.setPhiValues(createPhiIn(merge));
                if (Options.PrintIRWithLIR.getValue(options) && !TTY.isSuppressed()) {
                    TTY.println("Created PhiIn: " + label);
                }
            }
        }
        doBlockPrologue(block, options);
        List<Node> nodes = blockMap.get(block);
        // Allow NodeLIRBuilder subclass to specialize code generation of any interesting groups
        // of instructions
        matchComplexExpressions(nodes);
        boolean trace = traceLIRGeneratorLevel >= 3;
        for (int i = 0; i < nodes.size(); i++) {
            Node node = nodes.get(i);
            if (node instanceof ValueNode) {
                DebugContext debug = node.getDebug();
                ValueNode valueNode = (ValueNode) node;
                if (trace) {
                    TTY.println("LIRGen for " + valueNode);
                }
                Value operand = getOperand(valueNode);
                if (operand == null) {
                    if (!peephole(valueNode)) {
                        try {
                            doRoot(valueNode);
                        } catch (GraalError e) {
                            throw GraalGraphError.transformAndAddContext(e, valueNode);
                        } catch (Throwable e) {
                            throw new GraalGraphError(e).addContext(valueNode);
                        }
                    }
                } else if (ComplexMatchValue.INTERIOR_MATCH.equals(operand)) {
                    // Doesn't need to be evaluated
                    debug.log("interior match for %s", valueNode);
                } else if (operand instanceof ComplexMatchValue) {
                    debug.log("complex match for %s", valueNode);
                    ComplexMatchValue match = (ComplexMatchValue) operand;
                    operand = match.evaluate(this);
                    if (operand != null) {
                        setResult(valueNode, operand);
                    }
                } else {
                // There can be cases in which the result of an instruction is already set
                // before by other instructions.
                }
            }
        }
        if (!gen.hasBlockEnd(block)) {
            NodeIterable<Node> successors = block.getEndNode().successors();
            assert successors.count() == block.getSuccessorCount();
            if (block.getSuccessorCount() != 1) {
                /*
                     * If we have more than one successor, we cannot just use the first one. Since
                     * successors are unordered, this would be a random choice.
                     */
                throw new GraalError("Block without BlockEndOp: " + block.getEndNode());
            }
            gen.emitJump(getLIRBlock((FixedNode) successors.first()));
        }
        assert verifyBlock(gen.getResult().getLIR(), block);
    }
}
Also used : LabelOp(org.graalvm.compiler.lir.StandardOp.LabelOp) OptionValues(org.graalvm.compiler.options.OptionValues) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) IfNode(org.graalvm.compiler.nodes.IfNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) DeoptimizingNode(org.graalvm.compiler.nodes.DeoptimizingNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) DirectCallTargetNode(org.graalvm.compiler.nodes.DirectCallTargetNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) IntegerTestNode(org.graalvm.compiler.nodes.calc.IntegerTestNode) FullInfopointNode(org.graalvm.compiler.nodes.FullInfopointNode) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) IntegerSwitchNode(org.graalvm.compiler.nodes.extended.IntegerSwitchNode) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) SwitchNode(org.graalvm.compiler.nodes.extended.SwitchNode) LoweredCallTargetNode(org.graalvm.compiler.nodes.LoweredCallTargetNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) ConditionalNode(org.graalvm.compiler.nodes.calc.ConditionalNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IndirectCallTargetNode(org.graalvm.compiler.nodes.IndirectCallTargetNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) Node(org.graalvm.compiler.graph.Node) PhiNode(org.graalvm.compiler.nodes.PhiNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) LIRGenerationDebugContext(org.graalvm.compiler.lir.debug.LIRGenerationDebugContext) DebugContext(org.graalvm.compiler.debug.DebugContext) FixedNode(org.graalvm.compiler.nodes.FixedNode) ComplexMatchValue(org.graalvm.compiler.core.match.ComplexMatchValue) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) GraalError(org.graalvm.compiler.debug.GraalError) BlockScope(org.graalvm.compiler.lir.gen.LIRGeneratorTool.BlockScope) GraalGraphError(org.graalvm.compiler.graph.GraalGraphError) ValueNode(org.graalvm.compiler.nodes.ValueNode) ComplexMatchValue(org.graalvm.compiler.core.match.ComplexMatchValue) Value(jdk.vm.ci.meta.Value) AllocatableValue(jdk.vm.ci.meta.AllocatableValue)

Example 47 with Node

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

the class MatchContext method setResult.

/**
 * Mark the interior nodes with INTERIOR_MATCH and set the Value of the root to be the result.
 * During final LIR generation it will be evaluated to produce the actual LIR value.
 *
 * @param result
 */
public void setResult(ComplexMatchResult result) {
    ComplexMatchValue value = new ComplexMatchValue(result);
    DebugContext debug = root.getDebug();
    if (debug.isLogEnabled()) {
        debug.log("matched %s %s", rule.getName(), rule.getPattern());
        debug.log("with nodes %s", rule.formatMatch(root));
    }
    if (consumed != null) {
        for (Node node : consumed) {
            // All the interior nodes should be skipped during the normal doRoot calls in
            // NodeLIRBuilder so mark them as interior matches. The root of the match will get a
            // closure which will be evaluated to produce the final LIR.
            builder.setMatchResult(node, ComplexMatchValue.INTERIOR_MATCH);
        }
    }
    builder.setMatchResult(root, value);
}
Also used : FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) Node(org.graalvm.compiler.graph.Node) DebugContext(org.graalvm.compiler.debug.DebugContext)

Example 48 with Node

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

the class GraphChangeMonitoringPhase method run.

@Override
@SuppressWarnings("try")
protected void run(StructuredGraph graph, C context) {
    /*
         * Phase may add nodes but not end up using them so ignore additions. Nodes going dead and
         * having their inputs change are the main interesting differences.
         */
    HashSetNodeEventListener listener = new HashSetNodeEventListener().exclude(NodeEvent.NODE_ADDED);
    StructuredGraph graphCopy = (StructuredGraph) graph.copy(graph.getDebug());
    DebugContext debug = graph.getDebug();
    try (NodeEventScope s = graphCopy.trackNodeEvents(listener)) {
        try (DebugContext.Scope s2 = debug.sandbox("WithoutMonitoring", null)) {
            super.run(graphCopy, context);
        } catch (Throwable t) {
            debug.handle(t);
        }
    }
    EconomicSet<Node> filteredNodes = EconomicSet.create(Equivalence.IDENTITY);
    for (Node n : listener.getNodes()) {
        if (n instanceof LogicConstantNode) {
        // Ignore LogicConstantNode since those are sometimes created and deleted as part of
        // running a phase.
        } else {
            filteredNodes.add(n);
        }
    }
    if (!filteredNodes.isEmpty()) {
        /* rerun it on the real graph in a new Debug scope so Dump and Log can find it. */
        listener = new HashSetNodeEventListener();
        try (NodeEventScope s = graph.trackNodeEvents(listener)) {
            try (DebugContext.Scope s2 = debug.scope("WithGraphChangeMonitoring")) {
                if (debug.isDumpEnabled(DebugContext.DETAILED_LEVEL)) {
                    debug.dump(DebugContext.DETAILED_LEVEL, graph, "*** Before phase %s", getName());
                }
                super.run(graph, context);
                if (debug.isDumpEnabled(DebugContext.DETAILED_LEVEL)) {
                    debug.dump(DebugContext.DETAILED_LEVEL, graph, "*** After phase %s %s", getName(), filteredNodes);
                }
                debug.log("*** %s %s %s\n", message, graph, filteredNodes);
            }
        }
    } else {
        // Go ahead and run it normally even though it should have no effect
        super.run(graph, context);
    }
}
Also used : HashSetNodeEventListener(org.graalvm.compiler.phases.common.util.HashSetNodeEventListener) NodeEventScope(org.graalvm.compiler.graph.Graph.NodeEventScope) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) Node(org.graalvm.compiler.graph.Node) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) DebugContext(org.graalvm.compiler.debug.DebugContext)

Example 49 with Node

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

the class DefaultLoopPolicies method shouldUnswitch.

@Override
public boolean shouldUnswitch(LoopEx loop, List<ControlSplitNode> controlSplits) {
    int phis = 0;
    StructuredGraph graph = loop.loopBegin().graph();
    DebugContext debug = graph.getDebug();
    NodeBitMap branchNodes = graph.createNodeBitMap();
    for (ControlSplitNode controlSplit : controlSplits) {
        for (Node successor : controlSplit.successors()) {
            AbstractBeginNode branch = (AbstractBeginNode) successor;
            // this may count twice because of fall-through in switches
            loop.nodesInLoopBranch(branchNodes, branch);
        }
        Block postDomBlock = loop.loopsData().getCFG().blockFor(controlSplit).getPostdominator();
        if (postDomBlock != null) {
            IsolatedInitialization.UNSWITCH_SPLIT_WITH_PHIS.increment(debug);
            phis += ((MergeNode) postDomBlock.getBeginNode()).phis().count();
        }
    }
    int inBranchTotal = branchNodes.count();
    CountingClosure stateNodesCount = new CountingClosure();
    double loopFrequency = loop.loopBegin().loopFrequency();
    OptionValues options = loop.loopBegin().getOptions();
    int maxDiff = Options.LoopUnswitchTrivial.getValue(options) + (int) (Options.LoopUnswitchFrequencyBoost.getValue(options) * (loopFrequency - 1.0 + phis));
    maxDiff = Math.min(maxDiff, Options.LoopUnswitchMaxIncrease.getValue(options));
    int remainingGraphSpace = MaximumDesiredSize.getValue(options) - graph.getNodeCount();
    maxDiff = Math.min(maxDiff, remainingGraphSpace);
    loop.loopBegin().stateAfter().applyToVirtual(stateNodesCount);
    int loopTotal = loop.size() - loop.loopBegin().phis().count() - stateNodesCount.count - 1;
    int actualDiff = (loopTotal - inBranchTotal);
    ControlSplitNode firstSplit = controlSplits.get(0);
    if (firstSplit instanceof TypeSwitchNode) {
        int copies = firstSplit.successors().count() - 1;
        for (Node succ : firstSplit.successors()) {
            FixedNode current = (FixedNode) succ;
            while (current instanceof FixedWithNextNode) {
                current = ((FixedWithNextNode) current).next();
            }
            if (current instanceof DeoptimizeNode) {
                copies--;
            }
        }
        actualDiff = actualDiff * copies;
    }
    debug.log("shouldUnswitch(%s, %s) : delta=%d (%.2f%% inside of branches), max=%d, f=%.2f, phis=%d -> %b", loop, controlSplits, actualDiff, (double) (inBranchTotal) / loopTotal * 100, maxDiff, loopFrequency, phis, actualDiff <= maxDiff);
    if (actualDiff <= maxDiff) {
        // check whether we're allowed to unswitch this loop
        return loop.canDuplicateLoop();
    } else {
        return false;
    }
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) OptionValues(org.graalvm.compiler.options.OptionValues) NodeBitMap(org.graalvm.compiler.graph.NodeBitMap) ControlFlowAnchorNode(org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) TypeSwitchNode(org.graalvm.compiler.nodes.java.TypeSwitchNode) DebugContext(org.graalvm.compiler.debug.DebugContext) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) TypeSwitchNode(org.graalvm.compiler.nodes.java.TypeSwitchNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) Block(org.graalvm.compiler.nodes.cfg.Block) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode)

Example 50 with Node

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

the class DefaultLoopPolicies method shouldPartiallyUnroll.

@Override
public boolean shouldPartiallyUnroll(LoopEx loop) {
    LoopBeginNode loopBegin = loop.loopBegin();
    if (!loop.isCounted()) {
        loopBegin.getDebug().log(DebugContext.VERBOSE_LEVEL, "shouldPartiallyUnroll %s isn't counted", loopBegin);
        return false;
    }
    OptionValues options = loop.entryPoint().getOptions();
    int maxNodes = Options.ExactPartialUnrollMaxNodes.getValue(options);
    maxNodes = Math.min(maxNodes, Math.max(0, MaximumDesiredSize.getValue(options) - loop.loopBegin().graph().getNodeCount()));
    int size = Math.max(1, loop.size() - 1 - loop.loopBegin().phis().count());
    int unrollFactor = loopBegin.getUnrollFactor();
    if (unrollFactor == 1) {
        double loopFrequency = loopBegin.loopFrequency();
        if (loopBegin.isSimpleLoop() && loopFrequency < 5.0) {
            loopBegin.getDebug().log(DebugContext.VERBOSE_LEVEL, "shouldPartiallyUnroll %s frequency too low %s ", loopBegin, loopFrequency);
            return false;
        }
        loopBegin.setLoopOrigFrequency(loopFrequency);
    }
    int maxUnroll = Options.UnrollMaxIterations.getValue(options);
    // Now correct size for the next unroll. UnrollMaxIterations == 1 means perform the
    // pre/main/post transformation but don't actually unroll the main loop.
    size += size;
    if (maxUnroll == 1 && loopBegin.isSimpleLoop() || size <= maxNodes && unrollFactor < maxUnroll) {
        // Will the next unroll fit?
        if ((int) loopBegin.loopOrigFrequency() < (unrollFactor * 2)) {
            return false;
        }
        // Check whether we're allowed to unroll this loop
        for (Node node : loop.inside().nodes()) {
            if (node instanceof ControlFlowAnchorNode) {
                return false;
            }
            if (node instanceof InvokeNode) {
                return false;
            }
        }
        return true;
    } else {
        loopBegin.getDebug().log(DebugContext.VERBOSE_LEVEL, "shouldPartiallyUnroll %s unrolled loop is too large %s ", loopBegin, size);
        return false;
    }
}
Also used : LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) OptionValues(org.graalvm.compiler.options.OptionValues) ControlFlowAnchorNode(org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) TypeSwitchNode(org.graalvm.compiler.nodes.java.TypeSwitchNode) ControlFlowAnchorNode(org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode)

Aggregations

Node (org.graalvm.compiler.graph.Node)189 ValueNode (org.graalvm.compiler.nodes.ValueNode)105 FixedNode (org.graalvm.compiler.nodes.FixedNode)91 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)75 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)74 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)73 PhiNode (org.graalvm.compiler.nodes.PhiNode)64 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)61 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)53 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)47 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)43 FloatingNode (org.graalvm.compiler.nodes.calc.FloatingNode)41 ParameterNode (org.graalvm.compiler.nodes.ParameterNode)38 EndNode (org.graalvm.compiler.nodes.EndNode)37 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)37 MethodCallTargetNode (org.graalvm.compiler.nodes.java.MethodCallTargetNode)37 MergeNode (org.graalvm.compiler.nodes.MergeNode)35 ReturnNode (org.graalvm.compiler.nodes.ReturnNode)35 VirtualObjectNode (org.graalvm.compiler.nodes.virtual.VirtualObjectNode)32 LogicNode (org.graalvm.compiler.nodes.LogicNode)31