Search in sources :

Example 1 with IfNode

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

the class BranchProbabilityNode method simplify.

@Override
public void simplify(SimplifierTool tool) {
    if (!hasUsages()) {
        return;
    }
    if (probability.isConstant()) {
        double probabilityValue = probability.asJavaConstant().asDouble();
        if (probabilityValue < 0.0) {
            throw new GraalError("A negative probability of " + probabilityValue + " is not allowed!");
        } else if (probabilityValue > 1.0) {
            throw new GraalError("A probability of more than 1.0 (" + probabilityValue + ") is not allowed!");
        } else if (Double.isNaN(probabilityValue)) {
            /*
                 * We allow NaN if the node is in unreachable code that will eventually fall away,
                 * or else an error will be thrown during lowering since we keep the node around.
                 */
            return;
        }
        boolean usageFound = false;
        for (IntegerEqualsNode node : this.usages().filter(IntegerEqualsNode.class)) {
            assert node.condition() == CanonicalCondition.EQ;
            ValueNode other = node.getX();
            if (node.getX() == this) {
                other = node.getY();
            }
            if (other.isConstant()) {
                double probabilityToSet = probabilityValue;
                if (other.asJavaConstant().asInt() == 0) {
                    probabilityToSet = 1.0 - probabilityToSet;
                }
                for (IfNode ifNodeUsages : node.usages().filter(IfNode.class)) {
                    usageFound = true;
                    ifNodeUsages.setTrueSuccessorProbability(probabilityToSet);
                }
                if (!usageFound) {
                    usageFound = node.usages().filter(NodePredicates.isA(FixedGuardNode.class).or(ConditionalNode.class)).isNotEmpty();
                }
            }
        }
        if (usageFound) {
            ValueNode currentCondition = condition;
            replaceAndDelete(currentCondition);
            if (tool != null) {
                tool.addToWorkList(currentCondition.usages());
            }
        } else {
            if (!isSubstitutionGraph()) {
                throw new GraalError("Wrong usage of branch probability injection!");
            }
        }
    }
}
Also used : ConditionalNode(org.graalvm.compiler.nodes.calc.ConditionalNode) GraalError(org.graalvm.compiler.debug.GraalError) IntegerEqualsNode(org.graalvm.compiler.nodes.calc.IntegerEqualsNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) IfNode(org.graalvm.compiler.nodes.IfNode)

Example 2 with IfNode

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

the class OptimizeExceptionCallsPhase method setBranchProbability.

/**
 * Sets the branch probability of the guarding IfNode to a small value. The effect is that the
 * exception call block is put at the end of the method. The other block (= the regular path)
 * gets the fall-through block of the IfNode. This should give a better performance - and it
 * looks nicer in the disassembly.
 */
private static void setBranchProbability(Node endNode) {
    Node node = endNode;
    Node predecessor = node.predecessor();
    // Go "up" the graph until we find an IfNode
    while (predecessor != null) {
        if (predecessor instanceof IfNode && node instanceof BeginNode) {
            // We found an IfNode which branches to our runtime exception call
            IfNode ifNode = (IfNode) predecessor;
            ifNode.setTrueSuccessorProbability(node == ifNode.trueSuccessor() ? 0.00001 : 0.99999);
            return;
        }
        if (predecessor instanceof MergeNode || predecessor instanceof ControlSplitNode) {
            // Any other split or merge is suspicious: we abort
            return;
        }
        node = predecessor;
        predecessor = node.predecessor();
    }
}
Also used : MergeNode(org.graalvm.compiler.nodes.MergeNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) IfNode(org.graalvm.compiler.nodes.IfNode) DeadEndNode(com.oracle.svm.core.graal.nodes.DeadEndNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) Node(org.graalvm.compiler.graph.Node) MergeNode(org.graalvm.compiler.nodes.MergeNode) ForeignCallNode(org.graalvm.compiler.nodes.extended.ForeignCallNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) IfNode(org.graalvm.compiler.nodes.IfNode)

Example 3 with IfNode

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

the class AMD64NodeMatchRules method emitIntegerTestBranchMemory.

private ComplexMatchResult emitIntegerTestBranchMemory(IfNode x, ValueNode value, LIRLowerableAccess access) {
    LabelRef trueLabel = getLIRBlock(x.trueSuccessor());
    LabelRef falseLabel = getLIRBlock(x.falseSuccessor());
    double trueLabelProbability = x.probability(x.trueSuccessor());
    AMD64Kind kind = getMemoryKind(access);
    OperandSize size = kind == AMD64Kind.QWORD ? QWORD : DWORD;
    if (value.isConstant()) {
        JavaConstant constant = value.asJavaConstant();
        if (constant != null && kind == AMD64Kind.QWORD && !NumUtil.isInt(constant.asLong())) {
            // Only imm32 as long
            return null;
        }
        return builder -> {
            AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
            gen.append(new AMD64BinaryConsumer.MemoryConstOp(AMD64MIOp.TEST, size, address, (int) constant.asLong(), getState(access)));
            gen.append(new BranchOp(Condition.EQ, trueLabel, falseLabel, trueLabelProbability));
            return null;
        };
    } else {
        return builder -> {
            AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
            gen.append(new AMD64BinaryConsumer.MemoryRMOp(AMD64RMOp.TEST, size, gen.asAllocatable(operand(value)), address, getState(access)));
            gen.append(new BranchOp(Condition.EQ, trueLabel, falseLabel, trueLabelProbability));
            return null;
        };
    }
}
Also used : OperandSize(org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize) AMD64RMOp(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp) AVXOp(org.graalvm.compiler.asm.amd64.AMD64Assembler.AVXOp) AMD64BinaryConsumer(org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer) NarrowNode(org.graalvm.compiler.nodes.calc.NarrowNode) LabelRef(org.graalvm.compiler.lir.LabelRef) UnsignedRightShiftNode(org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode) SUB(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.SUB) SignExtendNode(org.graalvm.compiler.nodes.calc.SignExtendNode) FloatConvertNode(org.graalvm.compiler.nodes.calc.FloatConvertNode) ZeroExtendNode(org.graalvm.compiler.nodes.calc.ZeroExtendNode) AMD64Kind(jdk.vm.ci.amd64.AMD64Kind) NumUtil(org.graalvm.compiler.core.common.NumUtil) IfNode(org.graalvm.compiler.nodes.IfNode) GraphUtil(org.graalvm.compiler.nodes.util.GraphUtil) NodeView(org.graalvm.compiler.nodes.NodeView) LIRLowerableAccess(org.graalvm.compiler.nodes.memory.LIRLowerableAccess) BranchOp(org.graalvm.compiler.lir.amd64.AMD64ControlFlow.BranchOp) MOVSX(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSX) NodeLIRBuilder(org.graalvm.compiler.core.gen.NodeLIRBuilder) DeoptimizingNode(org.graalvm.compiler.nodes.DeoptimizingNode) TargetDescription(jdk.vm.ci.code.TargetDescription) JavaConstant(jdk.vm.ci.meta.JavaConstant) PlatformKind(jdk.vm.ci.meta.PlatformKind) ValueNode(org.graalvm.compiler.nodes.ValueNode) Value(jdk.vm.ci.meta.Value) ComplexMatchResult(org.graalvm.compiler.core.match.ComplexMatchResult) Access(org.graalvm.compiler.nodes.memory.Access) ADD(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.ADD) SS(org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SS) DWORD(org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.DWORD) GraalError(org.graalvm.compiler.debug.GraalError) ValueKind(jdk.vm.ci.meta.ValueKind) MatchRule(org.graalvm.compiler.core.match.MatchRule) LogicCompareAndSwapNode(org.graalvm.compiler.nodes.java.LogicCompareAndSwapNode) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) LeftShiftNode(org.graalvm.compiler.nodes.calc.LeftShiftNode) MOVSXB(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXB) WriteNode(org.graalvm.compiler.nodes.memory.WriteNode) LIRFrameState(org.graalvm.compiler.lir.LIRFrameState) SD(org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SD) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) ReinterpretNode(org.graalvm.compiler.nodes.calc.ReinterpretNode) AMD64RRMOp(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RRMOp) AMD64(jdk.vm.ci.amd64.AMD64) AMD64MIOp(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp) ValueCompareAndSwapNode(org.graalvm.compiler.nodes.java.ValueCompareAndSwapNode) MOVSXD(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXD) Condition(org.graalvm.compiler.core.common.calc.Condition) CPUFeature(jdk.vm.ci.amd64.AMD64.CPUFeature) LIRKind(org.graalvm.compiler.core.common.LIRKind) CanonicalCondition(org.graalvm.compiler.core.common.calc.CanonicalCondition) SSEOp(org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp) OR(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.OR) LIRValueUtil(org.graalvm.compiler.lir.LIRValueUtil) NodeMatchRules(org.graalvm.compiler.core.gen.NodeMatchRules) XOR(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.XOR) LIRGeneratorTool(org.graalvm.compiler.lir.gen.LIRGeneratorTool) AND(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.AND) AMD64AddressValue(org.graalvm.compiler.lir.amd64.AMD64AddressValue) QWORD(org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.QWORD) AMD64AddressValue(org.graalvm.compiler.lir.amd64.AMD64AddressValue) AMD64Kind(jdk.vm.ci.amd64.AMD64Kind) BranchOp(org.graalvm.compiler.lir.amd64.AMD64ControlFlow.BranchOp) JavaConstant(jdk.vm.ci.meta.JavaConstant) LabelRef(org.graalvm.compiler.lir.LabelRef) OperandSize(org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize)

Example 4 with IfNode

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

the class SimpleCFGTest method testImplies.

@Test
public void testImplies() {
    OptionValues options = getInitialOptions();
    DebugContext debug = DebugContext.create(options, new GraalDebugHandlersFactory(getSnippetReflection()));
    StructuredGraph graph = new StructuredGraph.Builder(options, debug, AllowAssumptions.YES).build();
    EndNode trueEnd = graph.add(new EndNode());
    EndNode falseEnd = graph.add(new EndNode());
    AbstractBeginNode trueBegin = graph.add(new BeginNode());
    trueBegin.setNext(trueEnd);
    AbstractBeginNode falseBegin = graph.add(new BeginNode());
    falseBegin.setNext(falseEnd);
    IfNode ifNode = graph.add(new IfNode(null, trueBegin, falseBegin, 0.5));
    graph.start().setNext(ifNode);
    AbstractMergeNode merge = graph.add(new MergeNode());
    merge.addForwardEnd(trueEnd);
    merge.addForwardEnd(falseEnd);
    ReturnNode returnNode = graph.add(new ReturnNode(null));
    merge.setNext(returnNode);
    dumpGraph(graph);
    ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true);
    Block[] blocks = cfg.getBlocks();
    // check number of blocks
    assertDeepEquals(4, blocks.length);
    // check block - node assignment
    assertDeepEquals(blocks[0], cfg.blockFor(graph.start()));
    assertDeepEquals(blocks[0], cfg.blockFor(ifNode));
    assertDeepEquals(blocks[1], cfg.blockFor(trueBegin));
    assertDeepEquals(blocks[1], cfg.blockFor(trueEnd));
    assertDeepEquals(blocks[2], cfg.blockFor(falseBegin));
    assertDeepEquals(blocks[2], cfg.blockFor(falseEnd));
    assertDeepEquals(blocks[3], cfg.blockFor(merge));
    assertDeepEquals(blocks[3], cfg.blockFor(returnNode));
    // check dominators
    assertDominator(blocks[0], null);
    assertDominator(blocks[1], blocks[0]);
    assertDominator(blocks[2], blocks[0]);
    assertDominator(blocks[3], blocks[0]);
    // check dominated
    assertDominatedSize(blocks[0], 3);
    assertDominatedSize(blocks[1], 0);
    assertDominatedSize(blocks[2], 0);
    assertDominatedSize(blocks[3], 0);
    // check postdominators
    assertPostdominator(blocks[0], blocks[3]);
    assertPostdominator(blocks[1], blocks[3]);
    assertPostdominator(blocks[2], blocks[3]);
    assertPostdominator(blocks[3], null);
}
Also used : OptionValues(org.graalvm.compiler.options.OptionValues) DebugContext(org.graalvm.compiler.debug.DebugContext) IfNode(org.graalvm.compiler.nodes.IfNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) GraalDebugHandlersFactory(org.graalvm.compiler.printer.GraalDebugHandlersFactory) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) EndNode(org.graalvm.compiler.nodes.EndNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) ControlFlowGraph(org.graalvm.compiler.nodes.cfg.ControlFlowGraph) Block(org.graalvm.compiler.nodes.cfg.Block) Test(org.junit.Test)

Example 5 with IfNode

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

the class HashMapGetTest method hashMapTest.

@Test
public void hashMapTest() {
    HashMap<Integer, Integer> map = new HashMap<>();
    ResolvedJavaMethod get = getResolvedJavaMethod(HashMapGetTest.class, "mapGet");
    for (int i = 0; i < 5000; i++) {
        mapGet(map, i);
        map.put(i, i);
        mapGet(map, i);
    }
    test(get, null, map, new Integer(0));
    for (IfNode ifNode : lastCompiledGraph.getNodes(IfNode.TYPE)) {
        LogicNode condition = ifNode.condition();
        if (ifNode.getTrueSuccessorProbability() < 0.4 && condition instanceof ObjectEqualsNode) {
            assertTrue(ifNode.trueSuccessor().next() instanceof ReturnNode, "Expected return.", ifNode.trueSuccessor(), ifNode.trueSuccessor().next());
        }
    }
}
Also used : ReturnNode(org.graalvm.compiler.nodes.ReturnNode) HashMap(java.util.HashMap) ObjectEqualsNode(org.graalvm.compiler.nodes.calc.ObjectEqualsNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) IfNode(org.graalvm.compiler.nodes.IfNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) Test(org.junit.Test)

Aggregations

IfNode (org.graalvm.compiler.nodes.IfNode)27 ValueNode (org.graalvm.compiler.nodes.ValueNode)15 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)14 BeginNode (org.graalvm.compiler.nodes.BeginNode)10 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)10 LogicNode (org.graalvm.compiler.nodes.LogicNode)9 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)8 FixedNode (org.graalvm.compiler.nodes.FixedNode)8 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)7 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)7 CompareNode (org.graalvm.compiler.nodes.calc.CompareNode)7 Node (org.graalvm.compiler.graph.Node)6 EndNode (org.graalvm.compiler.nodes.EndNode)6 KillingBeginNode (org.graalvm.compiler.nodes.KillingBeginNode)6 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)5 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)5 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)5 MergeNode (org.graalvm.compiler.nodes.MergeNode)5 Value (jdk.vm.ci.meta.Value)4 Condition (org.graalvm.compiler.core.common.calc.Condition)4