Search in sources :

Example 31 with LogicNode

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

the class BytecodeParser method genIf.

protected void genIf(LogicNode conditionInput, BciBlock trueBlockInput, BciBlock falseBlockInput, double probabilityInput) {
    BciBlock trueBlock = trueBlockInput;
    BciBlock falseBlock = falseBlockInput;
    LogicNode condition = conditionInput;
    double probability = probabilityInput;
    FrameState stateBefore = null;
    ProfilingPlugin profilingPlugin = this.graphBuilderConfig.getPlugins().getProfilingPlugin();
    if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
        stateBefore = frameState.create(bci(), getNonIntrinsicAncestor(), false, null, null);
    }
    // Remove a logic negation node.
    if (condition instanceof LogicNegationNode) {
        LogicNegationNode logicNegationNode = (LogicNegationNode) condition;
        BciBlock tmpBlock = trueBlock;
        trueBlock = falseBlock;
        falseBlock = tmpBlock;
        probability = 1 - probability;
        condition = logicNegationNode.getValue();
    }
    if (condition instanceof LogicConstantNode) {
        genConstantTargetIf(trueBlock, falseBlock, condition);
    } else {
        if (condition.graph() == null) {
            condition = genUnique(condition);
        }
        if (isNeverExecutedCode(probability)) {
            append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, true));
            if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
                profilingPlugin.profileGoto(this, method, bci(), falseBlock.startBci, stateBefore);
            }
            appendGoto(falseBlock);
            return;
        } else if (isNeverExecutedCode(1 - probability)) {
            append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, false));
            if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
                profilingPlugin.profileGoto(this, method, bci(), trueBlock.startBci, stateBefore);
            }
            appendGoto(trueBlock);
            return;
        }
        if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
            profilingPlugin.profileIf(this, method, bci(), condition, trueBlock.startBci, falseBlock.startBci, stateBefore);
        }
        int oldBci = stream.currentBCI();
        int trueBlockInt = checkPositiveIntConstantPushed(trueBlock);
        if (trueBlockInt != -1) {
            int falseBlockInt = checkPositiveIntConstantPushed(falseBlock);
            if (falseBlockInt != -1) {
                if (tryGenConditionalForIf(trueBlock, falseBlock, condition, oldBci, trueBlockInt, falseBlockInt)) {
                    return;
                }
            }
        }
        this.controlFlowSplit = true;
        FixedNode trueSuccessor = createTarget(trueBlock, frameState, false, false);
        FixedNode falseSuccessor = createTarget(falseBlock, frameState, false, true);
        ValueNode ifNode = genIfNode(condition, trueSuccessor, falseSuccessor, probability);
        postProcessIfNode(ifNode);
        append(ifNode);
    }
}
Also used : FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) LogicNegationNode(org.graalvm.compiler.nodes.LogicNegationNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) FrameState(org.graalvm.compiler.nodes.FrameState) BciBlock(org.graalvm.compiler.java.BciBlockMapping.BciBlock) RuntimeConstraint(jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint) ProfilingPlugin(org.graalvm.compiler.nodes.graphbuilderconf.ProfilingPlugin)

Example 32 with LogicNode

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

the class BytecodeParser method guardIntrinsic.

/**
 * Weaves a test of the receiver type to ensure the dispatch will select {@code targetMethod}
 * and not another method that overrides it. This should only be called if there is an intrinsic
 * (i.e., an {@link InvocationPlugin}) for {@code targetMethod} and the invocation is indirect.
 *
 * The control flow woven around the intrinsic is as follows:
 *
 * <pre>
 *  if (LoadMethod(LoadHub(receiver)) == targetMethod) {
 *       <intrinsic for targetMethod>
 *  } else {
 *       <virtual call to targetMethod>
 *  }
 * </pre>
 *
 * The {@code else} branch is woven by {@link #afterInvocationPluginExecution}.
 *
 * @return {@code null} if the intrinsic cannot be used otherwise an object to be used by
 *         {@link #afterInvocationPluginExecution} to weave code for the non-intrinsic branch
 */
protected IntrinsicGuard guardIntrinsic(ValueNode[] args, ResolvedJavaMethod targetMethod, InvocationPluginReceiver pluginReceiver) {
    ValueNode intrinsicReceiver = args[0];
    ResolvedJavaType receiverType = StampTool.typeOrNull(intrinsicReceiver);
    if (receiverType == null) {
        // The verifier guarantees it to be at least type declaring targetMethod
        receiverType = targetMethod.getDeclaringClass();
    }
    ResolvedJavaMethod resolvedMethod = receiverType.resolveMethod(targetMethod, method.getDeclaringClass());
    if (resolvedMethod == null || resolvedMethod.equals(targetMethod)) {
        assert resolvedMethod == null || targetMethod.getDeclaringClass().isAssignableFrom(resolvedMethod.getDeclaringClass());
        Mark mark = graph.getMark();
        FixedWithNextNode currentLastInstr = lastInstr;
        ValueNode nonNullReceiver = pluginReceiver.get();
        Stamp methodStamp = stampProvider.createMethodStamp();
        LoadHubNode hub = graph.unique(new LoadHubNode(stampProvider, nonNullReceiver));
        LoadMethodNode actual = append(new LoadMethodNode(methodStamp, targetMethod, receiverType, method.getDeclaringClass(), hub));
        ConstantNode expected = graph.unique(ConstantNode.forConstant(methodStamp, targetMethod.getEncoding(), getMetaAccess()));
        LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, CanonicalCondition.EQ, actual, expected, NodeView.DEFAULT));
        JavaTypeProfile profile = null;
        if (profilingInfo != null && this.optimisticOpts.useTypeCheckHints(getOptions())) {
            profile = profilingInfo.getTypeProfile(bci());
            if (profile != null) {
                JavaTypeProfile newProfile = adjustProfileForInvocationPlugin(profile, targetMethod);
                if (newProfile != profile) {
                    if (newProfile.getTypes().length == 0) {
                        // All profiled types select the intrinsic so
                        // emit a fixed guard instead of an if-then-else.
                        lastInstr = append(new FixedGuardNode(compare, TypeCheckedInliningViolated, InvalidateReprofile, false));
                        return new IntrinsicGuard(currentLastInstr, intrinsicReceiver, mark, null, null);
                    }
                } else {
                    // No profiled types select the intrinsic so emit a virtual call
                    return null;
                }
                profile = newProfile;
            }
        }
        AbstractBeginNode intrinsicBranch = graph.add(new BeginNode());
        AbstractBeginNode nonIntrinsicBranch = graph.add(new BeginNode());
        append(new IfNode(compare, intrinsicBranch, nonIntrinsicBranch, FAST_PATH_PROBABILITY));
        lastInstr = intrinsicBranch;
        return new IntrinsicGuard(currentLastInstr, intrinsicReceiver, mark, nonIntrinsicBranch, profile);
    } else {
        // Receiver selects an overriding method so emit a virtual call
        return null;
    }
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) LoadHubNode(org.graalvm.compiler.nodes.extended.LoadHubNode) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) Stamp(org.graalvm.compiler.core.common.type.Stamp) IntegerStamp(org.graalvm.compiler.core.common.type.IntegerStamp) Mark(org.graalvm.compiler.graph.Graph.Mark) IfNode(org.graalvm.compiler.nodes.IfNode) LoadMethodNode(org.graalvm.compiler.nodes.extended.LoadMethodNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) JavaTypeProfile(jdk.vm.ci.meta.JavaTypeProfile) ValueNode(org.graalvm.compiler.nodes.ValueNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 33 with LogicNode

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

the class BytecodeParser method genInstanceOf.

private void genInstanceOf() {
    int cpi = getStream().readCPI();
    JavaType type = lookupType(cpi, INSTANCEOF);
    ValueNode object = frameState.pop(JavaKind.Object);
    if (!(type instanceof ResolvedJavaType)) {
        handleUnresolvedInstanceOf(type, object);
        return;
    }
    TypeReference resolvedType = TypeReference.createTrusted(graph.getAssumptions(), (ResolvedJavaType) type);
    JavaTypeProfile profile = getProfileForTypeCheck(resolvedType);
    for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
        if (plugin.handleInstanceOf(this, object, resolvedType.getType(), profile)) {
            return;
        }
    }
    LogicNode instanceOfNode = null;
    if (profile != null) {
        if (profile.getNullSeen().isFalse()) {
            object = nullCheckedValue(object);
            ResolvedJavaType singleType = profile.asSingleType();
            if (singleType != null) {
                LogicNode typeCheck = append(createInstanceOf(TypeReference.createExactTrusted(singleType), object, profile));
                if (!typeCheck.isTautology()) {
                    append(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile));
                }
                instanceOfNode = LogicConstantNode.forBoolean(resolvedType.getType().isAssignableFrom(singleType));
            }
        }
    }
    if (instanceOfNode == null) {
        instanceOfNode = createInstanceOf(resolvedType, object, null);
    }
    LogicNode logicNode = genUnique(instanceOfNode);
    int next = getStream().nextBCI();
    int value = getStream().readUByte(next);
    if (next <= currentBlock.endBci && (value == Bytecodes.IFEQ || value == Bytecodes.IFNE)) {
        getStream().next();
        BciBlock firstSucc = currentBlock.getSuccessor(0);
        BciBlock secondSucc = currentBlock.getSuccessor(1);
        if (firstSucc != secondSucc) {
            boolean negate = value != Bytecodes.IFNE;
            if (negate) {
                BciBlock tmp = firstSucc;
                firstSucc = secondSucc;
                secondSucc = tmp;
            }
            genIf(instanceOfNode, firstSucc, secondSucc, getProfileProbability(negate));
        } else {
            appendGoto(firstSucc);
        }
    } else {
        // Most frequent for value is IRETURN, followed by ISTORE.
        frameState.push(JavaKind.Int, append(genConditional(logicNode)));
    }
}
Also used : FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaType(jdk.vm.ci.meta.JavaType) NodePlugin(org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin) JavaTypeProfile(jdk.vm.ci.meta.JavaTypeProfile) ValueNode(org.graalvm.compiler.nodes.ValueNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) BciBlock(org.graalvm.compiler.java.BciBlockMapping.BciBlock) RuntimeConstraint(jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Example 34 with LogicNode

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

the class BytecodeParser method genCheckCast.

private void genCheckCast() {
    int cpi = getStream().readCPI();
    JavaType type = lookupType(cpi, CHECKCAST);
    ValueNode object = frameState.pop(JavaKind.Object);
    if (!(type instanceof ResolvedJavaType)) {
        handleUnresolvedCheckCast(type, object);
        return;
    }
    TypeReference checkedType = TypeReference.createTrusted(graph.getAssumptions(), (ResolvedJavaType) type);
    JavaTypeProfile profile = getProfileForTypeCheck(checkedType);
    for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
        if (plugin.handleCheckCast(this, object, checkedType.getType(), profile)) {
            return;
        }
    }
    ValueNode castNode = null;
    if (profile != null) {
        if (profile.getNullSeen().isFalse()) {
            object = nullCheckedValue(object);
            ResolvedJavaType singleType = profile.asSingleType();
            if (singleType != null && checkedType.getType().isAssignableFrom(singleType)) {
                LogicNode typeCheck = append(createInstanceOf(TypeReference.createExactTrusted(singleType), object, profile));
                if (typeCheck.isTautology()) {
                    castNode = object;
                } else {
                    FixedGuardNode fixedGuard = append(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile, false));
                    castNode = append(PiNode.create(object, StampFactory.objectNonNull(TypeReference.createExactTrusted(singleType)), fixedGuard));
                }
            }
        }
    }
    boolean nonNull = ((ObjectStamp) object.stamp(NodeView.DEFAULT)).nonNull();
    if (castNode == null) {
        LogicNode condition = genUnique(createInstanceOfAllowNull(checkedType, object, null));
        if (condition.isTautology()) {
            castNode = object;
        } else {
            FixedGuardNode fixedGuard = append(new FixedGuardNode(condition, DeoptimizationReason.ClassCastException, DeoptimizationAction.InvalidateReprofile, false));
            castNode = append(PiNode.create(object, StampFactory.object(checkedType, nonNull), fixedGuard));
        }
    }
    frameState.push(JavaKind.Object, castNode);
}
Also used : FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaType(jdk.vm.ci.meta.JavaType) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) NodePlugin(org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin) JavaTypeProfile(jdk.vm.ci.meta.JavaTypeProfile) ValueNode(org.graalvm.compiler.nodes.ValueNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) RuntimeConstraint(jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Example 35 with LogicNode

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

the class BytecodeParser method genRet.

protected void genRet(int localIndex) {
    BciBlock successor = currentBlock.getRetSuccessor();
    ValueNode local = frameState.loadLocal(localIndex, JavaKind.Object);
    JsrScope scope = currentBlock.getJsrScope();
    int retAddress = scope.nextReturnAddress();
    ConstantNode returnBciNode = getJsrConstant(retAddress);
    LogicNode guard = IntegerEqualsNode.create(constantReflection, metaAccess, options, null, local, returnBciNode, NodeView.DEFAULT);
    guard = graph.addOrUniqueWithInputs(guard);
    append(new FixedGuardNode(guard, JavaSubroutineMismatch, InvalidateReprofile));
    if (!successor.getJsrScope().equals(scope.pop())) {
        throw new JsrNotSupportedBailout("unstructured control flow (ret leaves more than one scope)");
    }
    appendGoto(successor);
}
Also used : FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) BciBlock(org.graalvm.compiler.java.BciBlockMapping.BciBlock) RuntimeConstraint(jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint)

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