Search in sources :

Example 16 with LogicNode

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

the class LoopTransformations method isUnrollableLoop.

public static boolean isUnrollableLoop(LoopEx loop) {
    if (!loop.isCounted() || !loop.counted().getCounter().isConstantStride() || !loop.loop().getChildren().isEmpty()) {
        return false;
    }
    LoopBeginNode loopBegin = loop.loopBegin();
    LogicNode condition = loop.counted().getLimitTest().condition();
    if (!(condition instanceof CompareNode)) {
        return false;
    }
    if (((CompareNode) condition).condition() == CanonicalCondition.EQ) {
        condition.getDebug().log(DebugContext.VERBOSE_LEVEL, "isUnrollableLoop %s condition unsupported %s ", loopBegin, ((CompareNode) condition).condition());
        return false;
    }
    if (loopBegin.isMainLoop() || loopBegin.isSimpleLoop()) {
        // as well.
        if (loop.loop().getBlocks().size() < 3) {
            return true;
        }
        condition.getDebug().log(DebugContext.VERBOSE_LEVEL, "isUnrollableLoop %s too large to unroll %s ", loopBegin, loop.loop().getBlocks().size());
    }
    return false;
}
Also used : LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) LogicNode(org.graalvm.compiler.nodes.LogicNode)

Example 17 with LogicNode

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

the class LoopFragmentInside method placeNewSegmentAndCleanup.

private void placeNewSegmentAndCleanup(LoopEx loop) {
    CountedLoopInfo mainCounted = loop.counted();
    LoopBeginNode mainLoopBegin = loop.loopBegin();
    // Discard the segment entry and its flow, after if merging it into the loop
    StructuredGraph graph = mainLoopBegin.graph();
    IfNode loopTest = mainCounted.getLimitTest();
    IfNode newSegmentTest = getDuplicatedNode(loopTest);
    AbstractBeginNode trueSuccessor = loopTest.trueSuccessor();
    AbstractBeginNode falseSuccessor = loopTest.falseSuccessor();
    FixedNode firstNode;
    boolean codeInTrueSide = false;
    if (trueSuccessor == mainCounted.getBody()) {
        firstNode = trueSuccessor.next();
        codeInTrueSide = true;
    } else {
        assert (falseSuccessor == mainCounted.getBody());
        firstNode = falseSuccessor.next();
    }
    trueSuccessor = newSegmentTest.trueSuccessor();
    falseSuccessor = newSegmentTest.falseSuccessor();
    for (Node usage : falseSuccessor.anchored().snapshot()) {
        usage.replaceFirstInput(falseSuccessor, loopTest.falseSuccessor());
    }
    for (Node usage : trueSuccessor.anchored().snapshot()) {
        usage.replaceFirstInput(trueSuccessor, loopTest.trueSuccessor());
    }
    AbstractBeginNode startBlockNode;
    if (codeInTrueSide) {
        startBlockNode = trueSuccessor;
    } else {
        graph.getDebug().dump(DebugContext.VERBOSE_LEVEL, mainLoopBegin.graph(), "before");
        startBlockNode = falseSuccessor;
    }
    FixedNode lastNode = getBlockEnd(startBlockNode);
    LoopEndNode loopEndNode = mainLoopBegin.getSingleLoopEnd();
    FixedWithNextNode lastCodeNode = (FixedWithNextNode) loopEndNode.predecessor();
    FixedNode newSegmentFirstNode = getDuplicatedNode(firstNode);
    FixedWithNextNode newSegmentLastNode = getDuplicatedNode(lastCodeNode);
    graph.getDebug().dump(DebugContext.DETAILED_LEVEL, loopEndNode.graph(), "Before placing segment");
    if (firstNode instanceof LoopEndNode) {
        GraphUtil.killCFG(getDuplicatedNode(mainLoopBegin));
    } else {
        newSegmentLastNode.clearSuccessors();
        startBlockNode.setNext(lastNode);
        lastCodeNode.replaceFirstSuccessor(loopEndNode, newSegmentFirstNode);
        newSegmentLastNode.replaceFirstSuccessor(lastNode, loopEndNode);
        lastCodeNode.setNext(newSegmentFirstNode);
        newSegmentLastNode.setNext(loopEndNode);
        startBlockNode.clearSuccessors();
        lastNode.safeDelete();
        Node newSegmentTestStart = newSegmentTest.predecessor();
        LogicNode newSegmentIfTest = newSegmentTest.condition();
        newSegmentTestStart.clearSuccessors();
        newSegmentTest.safeDelete();
        newSegmentIfTest.safeDelete();
        trueSuccessor.safeDelete();
        falseSuccessor.safeDelete();
        newSegmentTestStart.safeDelete();
    }
    graph.getDebug().dump(DebugContext.DETAILED_LEVEL, loopEndNode.graph(), "After placing segment");
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) MemoryPhiNode(org.graalvm.compiler.nodes.memory.MemoryPhiNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) AddNode(org.graalvm.compiler.nodes.calc.AddNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IfNode(org.graalvm.compiler.nodes.IfNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) SubNode(org.graalvm.compiler.nodes.calc.SubNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) SafepointNode(org.graalvm.compiler.nodes.SafepointNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) 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) LogicNode(org.graalvm.compiler.nodes.LogicNode) IfNode(org.graalvm.compiler.nodes.IfNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode)

Example 18 with LogicNode

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

the class DefaultJavaLoweringProvider method getBoundsCheck.

protected GuardingNode getBoundsCheck(AccessIndexedNode n, ValueNode array, LoweringTool tool) {
    StructuredGraph graph = n.graph();
    ValueNode arrayLength = readArrayLength(array, tool.getConstantReflection());
    if (arrayLength == null) {
        arrayLength = createReadArrayLength(array, n, tool);
    } else {
        arrayLength = arrayLength.isAlive() ? arrayLength : graph.addOrUniqueWithInputs(arrayLength);
    }
    LogicNode boundsCheck = IntegerBelowNode.create(n.index(), arrayLength, NodeView.DEFAULT);
    if (boundsCheck.isTautology()) {
        return null;
    }
    return tool.createGuard(n, graph.addOrUniqueWithInputs(boundsCheck), BoundsCheckException, InvalidateReprofile);
}
Also used : StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ValueNode(org.graalvm.compiler.nodes.ValueNode) LogicNode(org.graalvm.compiler.nodes.LogicNode)

Example 19 with LogicNode

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

the class DefaultJavaLoweringProvider method lowerStoreIndexedNode.

protected void lowerStoreIndexedNode(StoreIndexedNode storeIndexed, LoweringTool tool) {
    StructuredGraph graph = storeIndexed.graph();
    ValueNode value = storeIndexed.value();
    ValueNode array = storeIndexed.array();
    array = this.createNullCheckedValue(array, storeIndexed, tool);
    GuardingNode boundsCheck = getBoundsCheck(storeIndexed, array, tool);
    JavaKind elementKind = storeIndexed.elementKind();
    LogicNode condition = null;
    if (elementKind == JavaKind.Object && !StampTool.isPointerAlwaysNull(value)) {
        /* Array store check. */
        TypeReference arrayType = StampTool.typeReferenceOrNull(array);
        if (arrayType != null && arrayType.isExact()) {
            ResolvedJavaType elementType = arrayType.getType().getComponentType();
            if (!elementType.isJavaLangObject()) {
                TypeReference typeReference = TypeReference.createTrusted(storeIndexed.graph().getAssumptions(), elementType);
                LogicNode typeTest = graph.addOrUniqueWithInputs(InstanceOfNode.create(typeReference, value));
                condition = LogicNode.or(graph.unique(IsNullNode.create(value)), typeTest, GraalDirectives.UNLIKELY_PROBABILITY);
            }
        } else {
            /*
                 * The guard on the read hub should be the null check of the array that was
                 * introduced earlier.
                 */
            ValueNode arrayClass = createReadHub(graph, array, tool);
            ValueNode componentHub = createReadArrayComponentHub(graph, arrayClass, storeIndexed);
            LogicNode typeTest = graph.unique(InstanceOfDynamicNode.create(graph.getAssumptions(), tool.getConstantReflection(), componentHub, value, false));
            condition = LogicNode.or(graph.unique(IsNullNode.create(value)), typeTest, GraalDirectives.UNLIKELY_PROBABILITY);
        }
    }
    AddressNode address = createArrayIndexAddress(graph, array, elementKind, storeIndexed.index(), boundsCheck);
    WriteNode memoryWrite = graph.add(new WriteNode(address, NamedLocationIdentity.getArrayLocation(elementKind), implicitStoreConvert(graph, elementKind, value), arrayStoreBarrierType(storeIndexed.elementKind())));
    memoryWrite.setGuard(boundsCheck);
    if (condition != null) {
        tool.createGuard(storeIndexed, condition, DeoptimizationReason.ArrayStoreException, DeoptimizationAction.InvalidateReprofile);
    }
    memoryWrite.setStateAfter(storeIndexed.stateAfter());
    graph.replaceFixedWithFixed(storeIndexed, memoryWrite);
}
Also used : StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ValueNode(org.graalvm.compiler.nodes.ValueNode) OffsetAddressNode(org.graalvm.compiler.nodes.memory.address.OffsetAddressNode) AddressNode(org.graalvm.compiler.nodes.memory.address.AddressNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) WriteNode(org.graalvm.compiler.nodes.memory.WriteNode) AtomicReadAndWriteNode(org.graalvm.compiler.nodes.java.AtomicReadAndWriteNode) JavaWriteNode(org.graalvm.compiler.nodes.extended.JavaWriteNode) LoweredAtomicReadAndWriteNode(org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode) GuardingNode(org.graalvm.compiler.nodes.extended.GuardingNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 20 with LogicNode

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

the class ConditionalEliminationTest14 method test1.

@Test
public void test1() {
    StructuredGraph graph = parseEager("test1Snippet", AllowAssumptions.YES);
    CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
    PhaseContext context = new PhaseContext(getProviders());
    /* Convert the LoadIndexNode to ReadNode with floating guards. */
    new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
    /* Convert the ReadNode to FloatingReadNode. */
    new FloatingReadPhase().apply(graph);
    /* Apply the phase that we want to test. */
    new IterativeConditionalEliminationPhase(canonicalizer, true).apply(graph, context);
    Assert.assertEquals("All guards must be floating", 0, graph.getNodes(FixedGuardNode.TYPE).count());
    Assert.assertEquals("All array accesses must have been lowered", 0, graph.getNodes().filter(LoadIndexedNode.class).count());
    Assert.assertEquals("All reads must be floating", 0, graph.getNodes().filter(ReadNode.class).count());
    Assert.assertEquals("Must have floating reads (3 array accesses, 1 array length)", 4, graph.getNodes().filter(FloatingReadNode.class).count());
    NodeIterable<GuardNode> boundsChecks = graph.getNodes(GuardNode.TYPE).filter(n -> ((GuardNode) n).getReason() == DeoptimizationReason.BoundsCheckException);
    Assert.assertEquals("Must have only 1 bounds check remaining", 1, boundsChecks.count());
    LogicNode condition = boundsChecks.first().getCondition();
    Assert.assertTrue("Bounds check must check for array length 8", condition instanceof IntegerBelowNode && ((IntegerBelowNode) condition).getY().valueEquals(ConstantNode.forInt(8)));
}
Also used : PhaseContext(org.graalvm.compiler.phases.tiers.PhaseContext) IterativeConditionalEliminationPhase(org.graalvm.compiler.phases.common.IterativeConditionalEliminationPhase) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) IntegerBelowNode(org.graalvm.compiler.nodes.calc.IntegerBelowNode) LoweringPhase(org.graalvm.compiler.phases.common.LoweringPhase) GuardNode(org.graalvm.compiler.nodes.GuardNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) CanonicalizerPhase(org.graalvm.compiler.phases.common.CanonicalizerPhase) LogicNode(org.graalvm.compiler.nodes.LogicNode) FloatingReadPhase(org.graalvm.compiler.phases.common.FloatingReadPhase) Test(org.junit.Test)

Aggregations

LogicNode (org.graalvm.compiler.nodes.LogicNode)48 ValueNode (org.graalvm.compiler.nodes.ValueNode)37 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)26 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)11 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)11 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)10 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)9 Stamp (org.graalvm.compiler.core.common.type.Stamp)9 IfNode (org.graalvm.compiler.nodes.IfNode)9 TypeReference (org.graalvm.compiler.core.common.type.TypeReference)8 LogicConstantNode (org.graalvm.compiler.nodes.LogicConstantNode)7 CompareNode (org.graalvm.compiler.nodes.calc.CompareNode)7 ConditionalNode (org.graalvm.compiler.nodes.calc.ConditionalNode)7 JavaConstant (jdk.vm.ci.meta.JavaConstant)6 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)6 FixedNode (org.graalvm.compiler.nodes.FixedNode)6 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)6 JavaKind (jdk.vm.ci.meta.JavaKind)5 ObjectStamp (org.graalvm.compiler.core.common.type.ObjectStamp)5 Node (org.graalvm.compiler.graph.Node)5