Search in sources :

Example 1 with BinaryArithmeticNode

use of org.graalvm.compiler.nodes.calc.BinaryArithmeticNode in project graal by oracle.

the class LoopEx method findInductionVariables.

/**
 * Collect all the basic induction variables for the loop and the find any induction variables
 * which are derived from the basic ones.
 *
 * @param loop
 * @return a map from node to induction variable
 */
private static EconomicMap<Node, InductionVariable> findInductionVariables(LoopEx loop) {
    EconomicMap<Node, InductionVariable> ivs = EconomicMap.create(Equivalence.IDENTITY);
    Queue<InductionVariable> scanQueue = new LinkedList<>();
    LoopBeginNode loopBegin = loop.loopBegin();
    AbstractEndNode forwardEnd = loopBegin.forwardEnd();
    for (PhiNode phi : loopBegin.valuePhis()) {
        ValueNode backValue = phi.singleBackValueOrThis();
        if (backValue == phi) {
            continue;
        }
        ValueNode stride = addSub(loop, backValue, phi);
        if (stride != null) {
            BasicInductionVariable biv = new BasicInductionVariable(loop, (ValuePhiNode) phi, phi.valueAt(forwardEnd), stride, (BinaryArithmeticNode<?>) backValue);
            ivs.put(phi, biv);
            scanQueue.add(biv);
        }
    }
    while (!scanQueue.isEmpty()) {
        InductionVariable baseIv = scanQueue.remove();
        ValueNode baseIvNode = baseIv.valueNode();
        for (ValueNode op : baseIvNode.usages().filter(ValueNode.class)) {
            if (loop.isOutsideLoop(op)) {
                continue;
            }
            if (op.usages().count() == 1 && op.usages().first() == baseIvNode) {
                /*
                     * This is just the base induction variable increment with no other uses so
                     * don't bother reporting it.
                     */
                continue;
            }
            InductionVariable iv = null;
            ValueNode offset = addSub(loop, op, baseIvNode);
            ValueNode scale;
            if (offset != null) {
                iv = new DerivedOffsetInductionVariable(loop, baseIv, offset, (BinaryArithmeticNode<?>) op);
            } else if (op instanceof NegateNode) {
                iv = new DerivedScaledInductionVariable(loop, baseIv, (NegateNode) op);
            } else if ((scale = mul(loop, op, baseIvNode)) != null) {
                iv = new DerivedScaledInductionVariable(loop, baseIv, scale, op);
            } else {
                boolean isValidConvert = op instanceof PiNode || op instanceof SignExtendNode;
                if (!isValidConvert && op instanceof ZeroExtendNode) {
                    ZeroExtendNode zeroExtendNode = (ZeroExtendNode) op;
                    isValidConvert = zeroExtendNode.isInputAlwaysPositive() || ((IntegerStamp) zeroExtendNode.stamp(NodeView.DEFAULT)).isPositive();
                }
                if (isValidConvert) {
                    iv = new DerivedConvertedInductionVariable(loop, baseIv, op.stamp(NodeView.DEFAULT), op);
                }
            }
            if (iv != null) {
                ivs.put(op, iv);
                scanQueue.offer(iv);
            }
        }
    }
    return ivs;
}
Also used : ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) SignExtendNode(org.graalvm.compiler.nodes.calc.SignExtendNode) ValueAnchorNode(org.graalvm.compiler.nodes.extended.ValueAnchorNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) SignExtendNode(org.graalvm.compiler.nodes.calc.SignExtendNode) IntegerLessThanNode(org.graalvm.compiler.nodes.calc.IntegerLessThanNode) NegateNode(org.graalvm.compiler.nodes.calc.NegateNode) ZeroExtendNode(org.graalvm.compiler.nodes.calc.ZeroExtendNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) IfNode(org.graalvm.compiler.nodes.IfNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) PiNode(org.graalvm.compiler.nodes.PiNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) BinaryArithmeticNode(org.graalvm.compiler.nodes.calc.BinaryArithmeticNode) FullInfopointNode(org.graalvm.compiler.nodes.FullInfopointNode) MulNode(org.graalvm.compiler.nodes.calc.MulNode) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) LeftShiftNode(org.graalvm.compiler.nodes.calc.LeftShiftNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) IntegerEqualsNode(org.graalvm.compiler.nodes.calc.IntegerEqualsNode) AddNode(org.graalvm.compiler.nodes.calc.AddNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IntegerBelowNode(org.graalvm.compiler.nodes.calc.IntegerBelowNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) SubNode(org.graalvm.compiler.nodes.calc.SubNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) PiNode(org.graalvm.compiler.nodes.PiNode) ZeroExtendNode(org.graalvm.compiler.nodes.calc.ZeroExtendNode) BinaryArithmeticNode(org.graalvm.compiler.nodes.calc.BinaryArithmeticNode) LinkedList(java.util.LinkedList) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) IntegerStamp(org.graalvm.compiler.core.common.type.IntegerStamp) ValueNode(org.graalvm.compiler.nodes.ValueNode) NegateNode(org.graalvm.compiler.nodes.calc.NegateNode)

Example 2 with BinaryArithmeticNode

use of org.graalvm.compiler.nodes.calc.BinaryArithmeticNode in project graal by oracle.

the class SchedulingTest method testValueProxyInputs.

@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));
        }
    }
}
Also used : SchedulePhase(org.graalvm.compiler.phases.schedule.SchedulePhase) ScheduleResult(org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) AddNode(org.graalvm.compiler.nodes.calc.AddNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) BinaryArithmeticNode(org.graalvm.compiler.nodes.calc.BinaryArithmeticNode) Node(org.graalvm.compiler.graph.Node) Block(org.graalvm.compiler.nodes.cfg.Block) FrameState(org.graalvm.compiler.nodes.FrameState) AddNode(org.graalvm.compiler.nodes.calc.AddNode) Test(org.junit.Test)

Example 3 with BinaryArithmeticNode

use of org.graalvm.compiler.nodes.calc.BinaryArithmeticNode in project graal by oracle.

the class SchedulingTest2 method testValueProxyInputs.

@Test
public void testValueProxyInputs() {
    StructuredGraph graph = parseEager("testSnippet", AllowAssumptions.YES);
    DebugContext debug = graph.getDebug();
    ReturnNode returnNode = graph.getNodes(ReturnNode.TYPE).first();
    BeginNode beginNode = graph.add(new BeginNode());
    returnNode.replaceAtPredecessor(beginNode);
    beginNode.setNext(returnNode);
    debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
    SchedulePhase schedulePhase = new SchedulePhase(SchedulingStrategy.EARLIEST_WITH_GUARD_ORDER);
    schedulePhase.apply(graph);
    ScheduleResult schedule = graph.getLastSchedule();
    BlockMap<List<Node>> blockToNodesMap = schedule.getBlockToNodesMap();
    NodeMap<Block> nodeToBlock = schedule.getNodeToBlockMap();
    assertDeepEquals(2, schedule.getCFG().getBlocks().length);
    for (BinaryArithmeticNode<?> node : graph.getNodes().filter(BinaryArithmeticNode.class)) {
        if (node instanceof AddNode) {
            assertTrue(node.toString() + " expected: " + nodeToBlock.get(beginNode) + " but was: " + nodeToBlock.get(node), nodeToBlock.get(node) != nodeToBlock.get(beginNode));
        }
    }
    for (FrameState fs : graph.getNodes(FrameState.TYPE)) {
        Block block = nodeToBlock.get(fs);
        assertTrue(fs.toString(), block == schedule.getCFG().getStartBlock());
        for (Node usage : fs.usages()) {
            if (usage instanceof StateSplit && ((StateSplit) usage).stateAfter() == fs) {
                assertTrue(usage.toString(), nodeToBlock.get(usage) == block);
                if (usage != block.getBeginNode()) {
                    List<Node> map = blockToNodesMap.get(block);
                    assertTrue(map.indexOf(fs) + " < " + map.indexOf(usage), map.indexOf(fs) < map.indexOf(usage));
                }
            }
        }
    }
    PhaseContext context = new PhaseContext(getProviders());
    new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
    new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, context);
    MidTierContext midContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
    new GuardLoweringPhase().apply(graph, midContext);
    FrameStateAssignmentPhase phase = new FrameStateAssignmentPhase();
    phase.apply(graph);
    schedulePhase.apply(graph);
    schedule = graph.getLastSchedule();
    blockToNodesMap = schedule.getBlockToNodesMap();
    nodeToBlock = schedule.getNodeToBlockMap();
    for (FrameState fs : graph.getNodes(FrameState.TYPE)) {
        Block block = nodeToBlock.get(fs);
        assertTrue(fs.toString(), block == schedule.getCFG().getStartBlock());
        for (Node usage : fs.usages()) {
            if ((usage instanceof StateSplit && ((StateSplit) usage).stateAfter() == fs) || (usage instanceof DeoptDuring && ((DeoptDuring) usage).stateDuring() == fs)) {
                assertTrue(usage.toString(), nodeToBlock.get(usage) == block);
                if (usage != block.getBeginNode()) {
                    List<Node> map = blockToNodesMap.get(block);
                    assertTrue(map.indexOf(fs) + " < " + map.indexOf(usage), map.indexOf(fs) < map.indexOf(usage));
                }
            }
        }
    }
}
Also used : FrameStateAssignmentPhase(org.graalvm.compiler.phases.common.FrameStateAssignmentPhase) SchedulePhase(org.graalvm.compiler.phases.schedule.SchedulePhase) ScheduleResult(org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult) AddNode(org.graalvm.compiler.nodes.calc.AddNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) BinaryArithmeticNode(org.graalvm.compiler.nodes.calc.BinaryArithmeticNode) Node(org.graalvm.compiler.graph.Node) GuardLoweringPhase(org.graalvm.compiler.phases.common.GuardLoweringPhase) LoweringPhase(org.graalvm.compiler.phases.common.LoweringPhase) DebugContext(org.graalvm.compiler.debug.DebugContext) FrameState(org.graalvm.compiler.nodes.FrameState) PhaseContext(org.graalvm.compiler.phases.tiers.PhaseContext) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) MidTierContext(org.graalvm.compiler.phases.tiers.MidTierContext) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) BeginNode(org.graalvm.compiler.nodes.BeginNode) DeoptDuring(org.graalvm.compiler.nodes.DeoptimizingNode.DeoptDuring) Block(org.graalvm.compiler.nodes.cfg.Block) List(java.util.List) CanonicalizerPhase(org.graalvm.compiler.phases.common.CanonicalizerPhase) AddNode(org.graalvm.compiler.nodes.calc.AddNode) GuardLoweringPhase(org.graalvm.compiler.phases.common.GuardLoweringPhase) StateSplit(org.graalvm.compiler.nodes.StateSplit) Test(org.junit.Test)

Aggregations

Node (org.graalvm.compiler.graph.Node)3 AddNode (org.graalvm.compiler.nodes.calc.AddNode)3 BinaryArithmeticNode (org.graalvm.compiler.nodes.calc.BinaryArithmeticNode)3 FrameState (org.graalvm.compiler.nodes.FrameState)2 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)2 ScheduleResult (org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult)2 Block (org.graalvm.compiler.nodes.cfg.Block)2 SchedulePhase (org.graalvm.compiler.phases.schedule.SchedulePhase)2 Test (org.junit.Test)2 LinkedList (java.util.LinkedList)1 List (java.util.List)1 IntegerStamp (org.graalvm.compiler.core.common.type.IntegerStamp)1 DebugContext (org.graalvm.compiler.debug.DebugContext)1 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)1 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)1 BeginNode (org.graalvm.compiler.nodes.BeginNode)1 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)1 DeoptDuring (org.graalvm.compiler.nodes.DeoptimizingNode.DeoptDuring)1 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)1 FixedNode (org.graalvm.compiler.nodes.FixedNode)1