Search in sources :

Example 6 with StateSplit

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

the class BytecodeParser method parseAndInlineCallee.

protected void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args, IntrinsicContext calleeIntrinsicContext) {
    FixedWithNextNode calleeBeforeUnwindNode = null;
    ValueNode calleeUnwindValue = null;
    try (IntrinsicScope s = calleeIntrinsicContext != null && !parsingIntrinsic() ? new IntrinsicScope(this, targetMethod.getSignature().toParameterKinds(!targetMethod.isStatic()), args) : null) {
        BytecodeParser parser = graphBuilderInstance.createBytecodeParser(graph, this, targetMethod, INVOCATION_ENTRY_BCI, calleeIntrinsicContext);
        FrameStateBuilder startFrameState = new FrameStateBuilder(parser, parser.code, graph);
        if (!targetMethod.isStatic()) {
            args[0] = nullCheckedValue(args[0]);
        }
        startFrameState.initializeFromArgumentsArray(args);
        parser.build(this.lastInstr, startFrameState);
        if (parser.returnDataList == null) {
            /* Callee does not return. */
            lastInstr = null;
        } else {
            ValueNode calleeReturnValue;
            MergeNode returnMergeNode = null;
            if (s != null) {
                s.returnDataList = parser.returnDataList;
            }
            if (parser.returnDataList.size() == 1) {
                /* Callee has a single return, we can continue parsing at that point. */
                ReturnToCallerData singleReturnData = parser.returnDataList.get(0);
                lastInstr = singleReturnData.beforeReturnNode;
                calleeReturnValue = singleReturnData.returnValue;
            } else {
                assert parser.returnDataList.size() > 1;
                /* Callee has multiple returns, we need to insert a control flow merge. */
                returnMergeNode = graph.add(new MergeNode());
                calleeReturnValue = ValueMergeUtil.mergeValueProducers(returnMergeNode, parser.returnDataList, returnData -> returnData.beforeReturnNode, returnData -> returnData.returnValue);
            }
            if (calleeReturnValue != null) {
                frameState.push(targetMethod.getSignature().getReturnKind().getStackKind(), calleeReturnValue);
            }
            if (returnMergeNode != null) {
                returnMergeNode.setStateAfter(createFrameState(stream.nextBCI(), returnMergeNode));
                lastInstr = finishInstruction(returnMergeNode, frameState);
            }
        }
        /*
             * Propagate any side effects into the caller when parsing intrinsics.
             */
        if (parser.frameState.isAfterSideEffect() && parsingIntrinsic()) {
            for (StateSplit sideEffect : parser.frameState.sideEffects()) {
                frameState.addSideEffect(sideEffect);
            }
        }
        calleeBeforeUnwindNode = parser.getBeforeUnwindNode();
        if (calleeBeforeUnwindNode != null) {
            calleeUnwindValue = parser.getUnwindValue();
            assert calleeUnwindValue != null;
        }
    }
    /*
         * Method handleException will call createTarget, which wires this exception edge to the
         * corresponding exception dispatch block in the caller. In the case where it wires to the
         * caller's unwind block, any FrameState created meanwhile, e.g., FrameState for
         * LoopExitNode, would be instantiated with AFTER_EXCEPTION_BCI. Such frame states should
         * not be fixed by IntrinsicScope.close, as they denote the states of the caller. Thus, the
         * following code should be placed outside the IntrinsicScope, so that correctly created
         * FrameStates are not replaced.
         */
    if (calleeBeforeUnwindNode != null) {
        calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci(), false));
    }
}
Also used : AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) LOR(org.graalvm.compiler.bytecode.Bytecodes.LOR) JavaTypeProfile(jdk.vm.ci.meta.JavaTypeProfile) LDC2_W(org.graalvm.compiler.bytecode.Bytecodes.LDC2_W) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) IFEQ(org.graalvm.compiler.bytecode.Bytecodes.IFEQ) FCMPG(org.graalvm.compiler.bytecode.Bytecodes.FCMPG) StampFactory.objectNonNull(org.graalvm.compiler.core.common.type.StampFactory.objectNonNull) ConstantPool(jdk.vm.ci.meta.ConstantPool) DUP_X1(org.graalvm.compiler.bytecode.Bytecodes.DUP_X1) DUP_X2(org.graalvm.compiler.bytecode.Bytecodes.DUP_X2) GETSTATIC(org.graalvm.compiler.bytecode.Bytecodes.GETSTATIC) IFGE(org.graalvm.compiler.bytecode.Bytecodes.IFGE) IMUL(org.graalvm.compiler.bytecode.Bytecodes.IMUL) LOOKUPSWITCH(org.graalvm.compiler.bytecode.Bytecodes.LOOKUPSWITCH) DNEG(org.graalvm.compiler.bytecode.Bytecodes.DNEG) FCMPL(org.graalvm.compiler.bytecode.Bytecodes.FCMPL) GraphBuilderConfiguration(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration) ExceptionDispatchBlock(org.graalvm.compiler.java.BciBlockMapping.ExceptionDispatchBlock) AnchoringNode(org.graalvm.compiler.nodes.extended.AnchoringNode) LoadMethodNode(org.graalvm.compiler.nodes.extended.LoadMethodNode) ResolveClassBeforeStaticInvoke(org.graalvm.compiler.core.common.GraalOptions.ResolveClassBeforeStaticInvoke) Bytecodes.nameOf(org.graalvm.compiler.bytecode.Bytecodes.nameOf) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) LSUB(org.graalvm.compiler.bytecode.Bytecodes.LSUB) GraalError.shouldNotReachHere(org.graalvm.compiler.debug.GraalError.shouldNotReachHere) NEWARRAY(org.graalvm.compiler.bytecode.Bytecodes.NEWARRAY) FADD(org.graalvm.compiler.bytecode.Bytecodes.FADD) FixedNode(org.graalvm.compiler.nodes.FixedNode) Unresolved(jdk.vm.ci.meta.DeoptimizationReason.Unresolved) ALOAD(org.graalvm.compiler.bytecode.Bytecodes.ALOAD) FloatConvert(org.graalvm.compiler.core.common.calc.FloatConvert) LineNumberTable(jdk.vm.ci.meta.LineNumberTable) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) FDIV(org.graalvm.compiler.bytecode.Bytecodes.FDIV) ICONST_0(org.graalvm.compiler.bytecode.Bytecodes.ICONST_0) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) ICONST_2(org.graalvm.compiler.bytecode.Bytecodes.ICONST_2) ICONST_1(org.graalvm.compiler.bytecode.Bytecodes.ICONST_1) ARRAYLENGTH(org.graalvm.compiler.bytecode.Bytecodes.ARRAYLENGTH) ICONST_4(org.graalvm.compiler.bytecode.Bytecodes.ICONST_4) FREM(org.graalvm.compiler.bytecode.Bytecodes.FREM) ICONST_3(org.graalvm.compiler.bytecode.Bytecodes.ICONST_3) ICONST_5(org.graalvm.compiler.bytecode.Bytecodes.ICONST_5) SignedDivNode(org.graalvm.compiler.nodes.calc.SignedDivNode) BytecodeTableSwitch(org.graalvm.compiler.bytecode.BytecodeTableSwitch) InvocationPluginReceiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.InvocationPluginReceiver) INLINE_DURING_PARSING(org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.CompilationContext.INLINE_DURING_PARSING) ILOAD(org.graalvm.compiler.bytecode.Bytecodes.ILOAD) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) L2D(org.graalvm.compiler.bytecode.Bytecodes.L2D) L2F(org.graalvm.compiler.bytecode.Bytecodes.L2F) InvalidateRecompile(jdk.vm.ci.meta.DeoptimizationAction.InvalidateRecompile) EconomicMap(org.graalvm.collections.EconomicMap) L2I(org.graalvm.compiler.bytecode.Bytecodes.L2I) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) FieldLocationIdentity(org.graalvm.compiler.nodes.FieldLocationIdentity) PUTSTATIC(org.graalvm.compiler.bytecode.Bytecodes.PUTSTATIC) FCONST_2(org.graalvm.compiler.bytecode.Bytecodes.FCONST_2) TTY(org.graalvm.compiler.debug.TTY) BREAKPOINT(org.graalvm.compiler.bytecode.Bytecodes.BREAKPOINT) HotSpotPrintInlining(org.graalvm.compiler.core.common.GraalOptions.HotSpotPrintInlining) GraphUtil(org.graalvm.compiler.nodes.util.GraphUtil) FCONST_0(org.graalvm.compiler.bytecode.Bytecodes.FCONST_0) FCONST_1(org.graalvm.compiler.bytecode.Bytecodes.FCONST_1) ResolvedJavaMethodBytecode(org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode) PrintProfilingInformation(org.graalvm.compiler.core.common.GraalOptions.PrintProfilingInformation) NewArrayNode(org.graalvm.compiler.nodes.java.NewArrayNode) LRETURN(org.graalvm.compiler.bytecode.Bytecodes.LRETURN) TraceInlineDuringParsing(org.graalvm.compiler.java.BytecodeParserOptions.TraceInlineDuringParsing) CodeUtil(jdk.vm.ci.code.CodeUtil) Signature(jdk.vm.ci.meta.Signature) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) IOR(org.graalvm.compiler.bytecode.Bytecodes.IOR) UseGuardedIntrinsics(org.graalvm.compiler.java.BytecodeParserOptions.UseGuardedIntrinsics) CASTORE(org.graalvm.compiler.bytecode.Bytecodes.CASTORE) Assertions(org.graalvm.compiler.debug.Assertions) InvokeKind(org.graalvm.compiler.nodes.CallTargetNode.InvokeKind) XorNode(org.graalvm.compiler.nodes.calc.XorNode) LoadHubNode(org.graalvm.compiler.nodes.extended.LoadHubNode) INVOKEVIRTUAL(org.graalvm.compiler.bytecode.Bytecodes.INVOKEVIRTUAL) ClassInitializationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.ClassInitializationPlugin) DebugContext(org.graalvm.compiler.debug.DebugContext) NullCheckException(jdk.vm.ci.meta.DeoptimizationReason.NullCheckException) IINC(org.graalvm.compiler.bytecode.Bytecodes.IINC) StampTool.isPointerNonNull(org.graalvm.compiler.nodes.type.StampTool.isPointerNonNull) SYNCHRONIZED(java.lang.reflect.Modifier.SYNCHRONIZED) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) IFGT(org.graalvm.compiler.bytecode.Bytecodes.IFGT) FSTORE(org.graalvm.compiler.bytecode.Bytecodes.FSTORE) Equivalence(org.graalvm.collections.Equivalence) InvalidateReprofile(jdk.vm.ci.meta.DeoptimizationAction.InvalidateReprofile) SIPUSH(org.graalvm.compiler.bytecode.Bytecodes.SIPUSH) LLOAD_2(org.graalvm.compiler.bytecode.Bytecodes.LLOAD_2) BASTORE(org.graalvm.compiler.bytecode.Bytecodes.BASTORE) LLOAD_1(org.graalvm.compiler.bytecode.Bytecodes.LLOAD_1) LLOAD_0(org.graalvm.compiler.bytecode.Bytecodes.LLOAD_0) StampPair(org.graalvm.compiler.core.common.type.StampPair) LLOAD_3(org.graalvm.compiler.bytecode.Bytecodes.LLOAD_3) CALOAD(org.graalvm.compiler.bytecode.Bytecodes.CALOAD) ProfilingPlugin(org.graalvm.compiler.nodes.graphbuilderconf.ProfilingPlugin) BytecodeExceptionNode(org.graalvm.compiler.nodes.extended.BytecodeExceptionNode) POP(org.graalvm.compiler.bytecode.Bytecodes.POP) LNEG(org.graalvm.compiler.bytecode.Bytecodes.LNEG) BALOAD(org.graalvm.compiler.bytecode.Bytecodes.BALOAD) FMUL(org.graalvm.compiler.bytecode.Bytecodes.FMUL) SWAP(org.graalvm.compiler.bytecode.Bytecodes.SWAP) UnsignedRightShiftNode(org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode) RuntimeConstraint(jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint) IFNONNULL(org.graalvm.compiler.bytecode.Bytecodes.IFNONNULL) BeginNode(org.graalvm.compiler.nodes.BeginNode) IntegerLessThanNode(org.graalvm.compiler.nodes.calc.IntegerLessThanNode) NegateNode(org.graalvm.compiler.nodes.calc.NegateNode) ZeroExtendNode(org.graalvm.compiler.nodes.calc.ZeroExtendNode) INVOKEINTERFACE(org.graalvm.compiler.bytecode.Bytecodes.INVOKEINTERFACE) DADD(org.graalvm.compiler.bytecode.Bytecodes.DADD) DREM(org.graalvm.compiler.bytecode.Bytecodes.DREM) EntryProxyNode(org.graalvm.compiler.nodes.EntryProxyNode) ACONST_NULL(org.graalvm.compiler.bytecode.Bytecodes.ACONST_NULL) Stamp(org.graalvm.compiler.core.common.type.Stamp) DLOAD_0(org.graalvm.compiler.bytecode.Bytecodes.DLOAD_0) BytecodeLookupSwitch(org.graalvm.compiler.bytecode.BytecodeLookupSwitch) DDIV(org.graalvm.compiler.bytecode.Bytecodes.DDIV) DLOAD_2(org.graalvm.compiler.bytecode.Bytecodes.DLOAD_2) DLOAD_1(org.graalvm.compiler.bytecode.Bytecodes.DLOAD_1) BytecodeDisassembler(org.graalvm.compiler.bytecode.BytecodeDisassembler) DLOAD_3(org.graalvm.compiler.bytecode.Bytecodes.DLOAD_3) IRETURN(org.graalvm.compiler.bytecode.Bytecodes.IRETURN) RETURN(org.graalvm.compiler.bytecode.Bytecodes.RETURN) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) MetaAccessProvider(jdk.vm.ci.meta.MetaAccessProvider) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) IntrinsicContext(org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext) GraalError.guarantee(org.graalvm.compiler.debug.GraalError.guarantee) ASTORE(org.graalvm.compiler.bytecode.Bytecodes.ASTORE) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) GOTO(org.graalvm.compiler.bytecode.Bytecodes.GOTO) OptimisticOptimizations(org.graalvm.compiler.phases.OptimisticOptimizations) LCMP(org.graalvm.compiler.bytecode.Bytecodes.LCMP) ArrayList(java.util.ArrayList) IFNULL(org.graalvm.compiler.bytecode.Bytecodes.IFNULL) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) BIPUSH(org.graalvm.compiler.bytecode.Bytecodes.BIPUSH) MULTIANEWARRAY(org.graalvm.compiler.bytecode.Bytecodes.MULTIANEWARRAY) STATIC(java.lang.reflect.Modifier.STATIC) ASTORE_0(org.graalvm.compiler.bytecode.Bytecodes.ASTORE_0) ProfilingInfo(jdk.vm.ci.meta.ProfilingInfo) ASTORE_2(org.graalvm.compiler.bytecode.Bytecodes.ASTORE_2) ASTORE_1(org.graalvm.compiler.bytecode.Bytecodes.ASTORE_1) ASTORE_3(org.graalvm.compiler.bytecode.Bytecodes.ASTORE_3) DRETURN(org.graalvm.compiler.bytecode.Bytecodes.DRETURN) CanonicalCondition(org.graalvm.compiler.core.common.calc.CanonicalCondition) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ILOAD_0(org.graalvm.compiler.bytecode.Bytecodes.ILOAD_0) ConstantFieldProvider(org.graalvm.compiler.core.common.spi.ConstantFieldProvider) RawConstant(jdk.vm.ci.meta.RawConstant) ILOAD_1(org.graalvm.compiler.bytecode.Bytecodes.ILOAD_1) ILOAD_2(org.graalvm.compiler.bytecode.Bytecodes.ILOAD_2) ILOAD_3(org.graalvm.compiler.bytecode.Bytecodes.ILOAD_3) SLOW_PATH_PROBABILITY(org.graalvm.compiler.nodes.extended.BranchProbabilityNode.SLOW_PATH_PROBABILITY) InlineInfo(org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo) StateSplitProxyNode(org.graalvm.compiler.nodes.extended.StateSplitProxyNode) NOP(org.graalvm.compiler.bytecode.Bytecodes.NOP) DeoptimizationReason(jdk.vm.ci.meta.DeoptimizationReason) BytecodeProvider(org.graalvm.compiler.bytecode.BytecodeProvider) NodePlugin(org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin) LASTORE(org.graalvm.compiler.bytecode.Bytecodes.LASTORE) Formatter(java.util.Formatter) IF_ACMPNE(org.graalvm.compiler.bytecode.Bytecodes.IF_ACMPNE) StampFactory(org.graalvm.compiler.core.common.type.StampFactory) DebugCloseable(org.graalvm.compiler.debug.DebugCloseable) SignExtendNode(org.graalvm.compiler.nodes.calc.SignExtendNode) FloatConvertNode(org.graalvm.compiler.nodes.calc.FloatConvertNode) NewMultiArrayNode(org.graalvm.compiler.nodes.java.NewMultiArrayNode) FSTORE_1(org.graalvm.compiler.bytecode.Bytecodes.FSTORE_1) FSTORE_0(org.graalvm.compiler.bytecode.Bytecodes.FSTORE_0) INVOKESTATIC(org.graalvm.compiler.bytecode.Bytecodes.INVOKESTATIC) ANEWARRAY(org.graalvm.compiler.bytecode.Bytecodes.ANEWARRAY) StressInvokeWithExceptionNode(org.graalvm.compiler.core.common.GraalOptions.StressInvokeWithExceptionNode) PiNode(org.graalvm.compiler.nodes.PiNode) FSTORE_3(org.graalvm.compiler.bytecode.Bytecodes.FSTORE_3) FSTORE_2(org.graalvm.compiler.bytecode.Bytecodes.FSTORE_2) ValueNode(org.graalvm.compiler.nodes.ValueNode) List(java.util.List) MonitorExitNode(org.graalvm.compiler.nodes.java.MonitorExitNode) LCONST_1(org.graalvm.compiler.bytecode.Bytecodes.LCONST_1) LCONST_0(org.graalvm.compiler.bytecode.Bytecodes.LCONST_0) GraalError(org.graalvm.compiler.debug.GraalError) DUP2(org.graalvm.compiler.bytecode.Bytecodes.DUP2) SALOAD(org.graalvm.compiler.bytecode.Bytecodes.SALOAD) FullInfopointNode(org.graalvm.compiler.nodes.FullInfopointNode) PermanentBailoutException(org.graalvm.compiler.core.common.PermanentBailoutException) GeneratePIC(org.graalvm.compiler.core.common.GraalOptions.GeneratePIC) IUSHR(org.graalvm.compiler.bytecode.Bytecodes.IUSHR) ResolvedJavaMethodBytecodeProvider(org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecodeProvider) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) StampTool(org.graalvm.compiler.nodes.type.StampTool) Condition(org.graalvm.compiler.core.common.calc.Condition) IASTORE(org.graalvm.compiler.bytecode.Bytecodes.IASTORE) TraceBytecodeParserLevel(org.graalvm.compiler.java.BytecodeParserOptions.TraceBytecodeParserLevel) InlinePartialIntrinsicExitDuringParsing(org.graalvm.compiler.java.BytecodeParserOptions.InlinePartialIntrinsicExitDuringParsing) UnwindNode(org.graalvm.compiler.nodes.UnwindNode) LALOAD(org.graalvm.compiler.bytecode.Bytecodes.LALOAD) FLOAD_3(org.graalvm.compiler.bytecode.Bytecodes.FLOAD_3) Bytecodes(org.graalvm.compiler.bytecode.Bytecodes) FLOAD_1(org.graalvm.compiler.bytecode.Bytecodes.FLOAD_1) EndNode(org.graalvm.compiler.nodes.EndNode) FLOAD_2(org.graalvm.compiler.bytecode.Bytecodes.FLOAD_2) LAND(org.graalvm.compiler.bytecode.Bytecodes.LAND) FLOAD_0(org.graalvm.compiler.bytecode.Bytecodes.FLOAD_0) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ALOAD_1(org.graalvm.compiler.bytecode.Bytecodes.ALOAD_1) ALOAD_0(org.graalvm.compiler.bytecode.Bytecodes.ALOAD_0) LDIV(org.graalvm.compiler.bytecode.Bytecodes.LDIV) LocationIdentity(org.graalvm.word.LocationIdentity) DSTORE(org.graalvm.compiler.bytecode.Bytecodes.DSTORE) IF_ICMPGT(org.graalvm.compiler.bytecode.Bytecodes.IF_ICMPGT) INVOKESPECIAL(org.graalvm.compiler.bytecode.Bytecodes.INVOKESPECIAL) NormalizeCompareNode(org.graalvm.compiler.nodes.calc.NormalizeCompareNode) F2L(org.graalvm.compiler.bytecode.Bytecodes.F2L) AndNode(org.graalvm.compiler.nodes.calc.AndNode) F2I(org.graalvm.compiler.bytecode.Bytecodes.F2I) IF_ICMPGE(org.graalvm.compiler.bytecode.Bytecodes.IF_ICMPGE) INEG(org.graalvm.compiler.bytecode.Bytecodes.INEG) JavaSubroutineMismatch(jdk.vm.ci.meta.DeoptimizationReason.JavaSubroutineMismatch) RegisterFinalizerNode(org.graalvm.compiler.nodes.java.RegisterFinalizerNode) MONITOREXIT(org.graalvm.compiler.bytecode.Bytecodes.MONITOREXIT) NodeSourcePosition(org.graalvm.compiler.graph.NodeSourcePosition) F2D(org.graalvm.compiler.bytecode.Bytecodes.F2D) OrNode(org.graalvm.compiler.nodes.calc.OrNode) FRETURN(org.graalvm.compiler.bytecode.Bytecodes.FRETURN) INVOCATION_ENTRY_BCI(jdk.vm.ci.runtime.JVMCICompiler.INVOCATION_ENTRY_BCI) LREM(org.graalvm.compiler.bytecode.Bytecodes.LREM) Snippet(org.graalvm.compiler.api.replacements.Snippet) FrameState(org.graalvm.compiler.nodes.FrameState) ObjectEqualsNode(org.graalvm.compiler.nodes.calc.ObjectEqualsNode) LADD(org.graalvm.compiler.bytecode.Bytecodes.LADD) MulNode(org.graalvm.compiler.nodes.calc.MulNode) ALOAD_3(org.graalvm.compiler.bytecode.Bytecodes.ALOAD_3) ALOAD_2(org.graalvm.compiler.bytecode.Bytecodes.ALOAD_2) GraalOptions(org.graalvm.compiler.core.common.GraalOptions) IF_ICMPEQ(org.graalvm.compiler.bytecode.Bytecodes.IF_ICMPEQ) IntegerEqualsNode(org.graalvm.compiler.nodes.calc.IntegerEqualsNode) IntegerStamp(org.graalvm.compiler.core.common.type.IntegerStamp) PUTFIELD(org.graalvm.compiler.bytecode.Bytecodes.PUTFIELD) LLOAD(org.graalvm.compiler.bytecode.Bytecodes.LLOAD) MergeNode(org.graalvm.compiler.nodes.MergeNode) AALOAD(org.graalvm.compiler.bytecode.Bytecodes.AALOAD) DeoptALot(org.graalvm.compiler.core.common.GraalOptions.DeoptALot) LXOR(org.graalvm.compiler.bytecode.Bytecodes.LXOR) FASTORE(org.graalvm.compiler.bytecode.Bytecodes.FASTORE) CHECKCAST(org.graalvm.compiler.bytecode.Bytecodes.CHECKCAST) TypeCheckedInliningViolated(jdk.vm.ci.meta.DeoptimizationReason.TypeCheckedInliningViolated) ValueAnchorNode(org.graalvm.compiler.nodes.extended.ValueAnchorNode) ICONST_M1(org.graalvm.compiler.bytecode.Bytecodes.ICONST_M1) D2L(org.graalvm.compiler.bytecode.Bytecodes.D2L) GOTO_W(org.graalvm.compiler.bytecode.Bytecodes.GOTO_W) D2I(org.graalvm.compiler.bytecode.Bytecodes.D2I) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode) IfNode(org.graalvm.compiler.nodes.IfNode) DASTORE(org.graalvm.compiler.bytecode.Bytecodes.DASTORE) ISUB(org.graalvm.compiler.bytecode.Bytecodes.ISUB) D2F(org.graalvm.compiler.bytecode.Bytecodes.D2F) DSTORE_1(org.graalvm.compiler.bytecode.Bytecodes.DSTORE_1) LSTORE_2(org.graalvm.compiler.bytecode.Bytecodes.LSTORE_2) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) DSTORE_0(org.graalvm.compiler.bytecode.Bytecodes.DSTORE_0) IF_ACMPEQ(org.graalvm.compiler.bytecode.Bytecodes.IF_ACMPEQ) LSTORE_3(org.graalvm.compiler.bytecode.Bytecodes.LSTORE_3) DSTORE_3(org.graalvm.compiler.bytecode.Bytecodes.DSTORE_3) LSTORE_0(org.graalvm.compiler.bytecode.Bytecodes.LSTORE_0) DSTORE_2(org.graalvm.compiler.bytecode.Bytecodes.DSTORE_2) LSTORE_1(org.graalvm.compiler.bytecode.Bytecodes.LSTORE_1) SignedRemNode(org.graalvm.compiler.nodes.calc.SignedRemNode) NEW(org.graalvm.compiler.bytecode.Bytecodes.NEW) FAST_PATH_PROBABILITY(org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FAST_PATH_PROBABILITY) NodeIterable(org.graalvm.compiler.graph.iterators.NodeIterable) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) LDC_W(org.graalvm.compiler.bytecode.Bytecodes.LDC_W) AASTORE(org.graalvm.compiler.bytecode.Bytecodes.AASTORE) Util(org.graalvm.compiler.core.common.util.Util) DLOAD(org.graalvm.compiler.bytecode.Bytecodes.DLOAD) BranchProbabilityNode(org.graalvm.compiler.nodes.extended.BranchProbabilityNode) Bytes(org.graalvm.compiler.bytecode.Bytes) StartNode(org.graalvm.compiler.nodes.StartNode) BailoutException(jdk.vm.ci.code.BailoutException) LSTORE(org.graalvm.compiler.bytecode.Bytecodes.LSTORE) BeginStateSplitNode(org.graalvm.compiler.nodes.BeginStateSplitNode) RemNode(org.graalvm.compiler.nodes.calc.RemNode) DMUL(org.graalvm.compiler.bytecode.Bytecodes.DMUL) IAND(org.graalvm.compiler.bytecode.Bytecodes.IAND) DUP(org.graalvm.compiler.bytecode.Bytecodes.DUP) LSHR(org.graalvm.compiler.bytecode.Bytecodes.LSHR) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) INSTANCEOF(org.graalvm.compiler.bytecode.Bytecodes.INSTANCEOF) DUP2_X2(org.graalvm.compiler.bytecode.Bytecodes.DUP2_X2) DUP2_X1(org.graalvm.compiler.bytecode.Bytecodes.DUP2_X1) LSHL(org.graalvm.compiler.bytecode.Bytecodes.LSHL) CanonicalizedCondition(org.graalvm.compiler.core.common.calc.Condition.CanonicalizedCondition) StoreIndexedNode(org.graalvm.compiler.nodes.java.StoreIndexedNode) LDC(org.graalvm.compiler.bytecode.Bytecodes.LDC) SubNode(org.graalvm.compiler.nodes.calc.SubNode) ClassCastException(jdk.vm.ci.meta.DeoptimizationReason.ClassCastException) ARETURN(org.graalvm.compiler.bytecode.Bytecodes.ARETURN) StressExplicitExceptionCode(org.graalvm.compiler.core.common.GraalOptions.StressExplicitExceptionCode) Invoke(org.graalvm.compiler.nodes.Invoke) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) Node(org.graalvm.compiler.graph.Node) Comparator(java.util.Comparator) IALOAD(org.graalvm.compiler.bytecode.Bytecodes.IALOAD) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) LogicNegationNode(org.graalvm.compiler.nodes.LogicNegationNode) IADD(org.graalvm.compiler.bytecode.Bytecodes.IADD) ResolvedJavaField(jdk.vm.ci.meta.ResolvedJavaField) GETFIELD(org.graalvm.compiler.bytecode.Bytecodes.GETFIELD) IREM(org.graalvm.compiler.bytecode.Bytecodes.IREM) BytecodeStream(org.graalvm.compiler.bytecode.BytecodeStream) IFNE(org.graalvm.compiler.bytecode.Bytecodes.IFNE) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) None(jdk.vm.ci.meta.DeoptimizationAction.None) IDIV(org.graalvm.compiler.bytecode.Bytecodes.IDIV) JSR(org.graalvm.compiler.bytecode.Bytecodes.JSR) LUSHR(org.graalvm.compiler.bytecode.Bytecodes.LUSHR) DALOAD(org.graalvm.compiler.bytecode.Bytecodes.DALOAD) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) JavaMethod(jdk.vm.ci.meta.JavaMethod) InvokeDynamicPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvokeDynamicPlugin) INVOKEDYNAMIC(org.graalvm.compiler.bytecode.Bytecodes.INVOKEDYNAMIC) NodeView(org.graalvm.compiler.nodes.NodeView) ISHL(org.graalvm.compiler.bytecode.Bytecodes.ISHL) JavaType(jdk.vm.ci.meta.JavaType) ISHR(org.graalvm.compiler.bytecode.Bytecodes.ISHR) FLOAD(org.graalvm.compiler.bytecode.Bytecodes.FLOAD) FloatDivNode(org.graalvm.compiler.nodes.calc.FloatDivNode) DSUB(org.graalvm.compiler.bytecode.Bytecodes.DSUB) LeftShiftNode(org.graalvm.compiler.nodes.calc.LeftShiftNode) IntegerSwitchNode(org.graalvm.compiler.nodes.extended.IntegerSwitchNode) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) I2S(org.graalvm.compiler.bytecode.Bytecodes.I2S) IFLT(org.graalvm.compiler.bytecode.Bytecodes.IFLT) IF_ICMPNE(org.graalvm.compiler.bytecode.Bytecodes.IF_ICMPNE) StateSplit(org.graalvm.compiler.nodes.StateSplit) IFLE(org.graalvm.compiler.bytecode.Bytecodes.IFLE) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) I2C(org.graalvm.compiler.bytecode.Bytecodes.I2C) IXOR(org.graalvm.compiler.bytecode.Bytecodes.IXOR) TriState(jdk.vm.ci.meta.TriState) I2D(org.graalvm.compiler.bytecode.Bytecodes.I2D) MONITORENTER(org.graalvm.compiler.bytecode.Bytecodes.MONITORENTER) I2F(org.graalvm.compiler.bytecode.Bytecodes.I2F) InvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin) I2L(org.graalvm.compiler.bytecode.Bytecodes.I2L) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) IntegerBelowNode(org.graalvm.compiler.nodes.calc.IntegerBelowNode) ISTORE_0(org.graalvm.compiler.bytecode.Bytecodes.ISTORE_0) ValueMergeUtil(org.graalvm.compiler.phases.util.ValueMergeUtil) JavaField(jdk.vm.ci.meta.JavaField) I2B(org.graalvm.compiler.bytecode.Bytecodes.I2B) ISTORE_3(org.graalvm.compiler.bytecode.Bytecodes.ISTORE_3) ISTORE_1(org.graalvm.compiler.bytecode.Bytecodes.ISTORE_1) ISTORE_2(org.graalvm.compiler.bytecode.Bytecodes.ISTORE_2) SASTORE(org.graalvm.compiler.bytecode.Bytecodes.SASTORE) FNEG(org.graalvm.compiler.bytecode.Bytecodes.FNEG) ATHROW(org.graalvm.compiler.bytecode.Bytecodes.ATHROW) Indent(org.graalvm.compiler.debug.Indent) NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) POP2(org.graalvm.compiler.bytecode.Bytecodes.POP2) FSUB(org.graalvm.compiler.bytecode.Bytecodes.FSUB) IF_ICMPLE(org.graalvm.compiler.bytecode.Bytecodes.IF_ICMPLE) BytecodeFrame(jdk.vm.ci.code.BytecodeFrame) DeoptimizationAction(jdk.vm.ci.meta.DeoptimizationAction) JSR_W(org.graalvm.compiler.bytecode.Bytecodes.JSR_W) NarrowNode(org.graalvm.compiler.nodes.calc.NarrowNode) BciBlock(org.graalvm.compiler.java.BciBlockMapping.BciBlock) JavaKind(jdk.vm.ci.meta.JavaKind) ISTORE(org.graalvm.compiler.bytecode.Bytecodes.ISTORE) DCONST_1(org.graalvm.compiler.bytecode.Bytecodes.DCONST_1) DCONST_0(org.graalvm.compiler.bytecode.Bytecodes.DCONST_0) BytecodeSwitch(org.graalvm.compiler.bytecode.BytecodeSwitch) Mark(org.graalvm.compiler.graph.Graph.Mark) ConstantReflectionProvider(jdk.vm.ci.meta.ConstantReflectionProvider) EntryMarkerNode(org.graalvm.compiler.nodes.EntryMarkerNode) CounterKey(org.graalvm.compiler.debug.CounterKey) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) String.format(java.lang.String.format) FinalFieldBarrierNode(org.graalvm.compiler.nodes.java.FinalFieldBarrierNode) Bytecode(org.graalvm.compiler.bytecode.Bytecode) JavaConstant(jdk.vm.ci.meta.JavaConstant) LogicNode(org.graalvm.compiler.nodes.LogicNode) RET(org.graalvm.compiler.bytecode.Bytecodes.RET) TraceParserPlugins(org.graalvm.compiler.java.BytecodeParserOptions.TraceParserPlugins) IF_ICMPLT(org.graalvm.compiler.bytecode.Bytecodes.IF_ICMPLT) DCMPG(org.graalvm.compiler.bytecode.Bytecodes.DCMPG) LMUL(org.graalvm.compiler.bytecode.Bytecodes.LMUL) InlineInvokePlugin(org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) AddNode(org.graalvm.compiler.nodes.calc.AddNode) InstanceOfNode(org.graalvm.compiler.nodes.java.InstanceOfNode) RightShiftNode(org.graalvm.compiler.nodes.calc.RightShiftNode) UnreachedCode(jdk.vm.ci.meta.DeoptimizationReason.UnreachedCode) ConditionalNode(org.graalvm.compiler.nodes.calc.ConditionalNode) DCMPL(org.graalvm.compiler.bytecode.Bytecodes.DCMPL) OptionValues(org.graalvm.compiler.options.OptionValues) BytecodeExceptionMode(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.BytecodeExceptionMode) TABLESWITCH(org.graalvm.compiler.bytecode.Bytecodes.TABLESWITCH) ArrayLengthNode(org.graalvm.compiler.nodes.java.ArrayLengthNode) InfopointReason(jdk.vm.ci.code.site.InfopointReason) ProfiledType(jdk.vm.ci.meta.JavaTypeProfile.ProfiledType) MembarNode(org.graalvm.compiler.nodes.extended.MembarNode) MonitorEnterNode(org.graalvm.compiler.nodes.java.MonitorEnterNode) StampProvider(org.graalvm.compiler.nodes.spi.StampProvider) FALOAD(org.graalvm.compiler.bytecode.Bytecodes.FALOAD) Collections(java.util.Collections) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) StateSplit(org.graalvm.compiler.nodes.StateSplit)

Example 7 with StateSplit

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

the class GraphOrder method visitForward.

private static void visitForward(ArrayList<Node> nodes, NodeBitMap visited, Node node, boolean floatingOnly) {
    try {
        assert node == null || node.isAlive() : node + " not alive";
        if (node != null && !visited.isMarked(node)) {
            if (floatingOnly && node instanceof FixedNode) {
                throw new GraalError("unexpected reference to fixed node: %s (this indicates an unexpected cycle)", node);
            }
            visited.mark(node);
            FrameState stateAfter = null;
            if (node instanceof StateSplit) {
                stateAfter = ((StateSplit) node).stateAfter();
            }
            for (Node input : node.inputs()) {
                if (input != stateAfter) {
                    visitForward(nodes, visited, input, true);
                }
            }
            if (node instanceof EndNode) {
                EndNode end = (EndNode) node;
                for (PhiNode phi : end.merge().phis()) {
                    visitForward(nodes, visited, phi.valueAt(end), true);
                }
            }
            nodes.add(node);
            if (node instanceof AbstractMergeNode) {
                for (PhiNode phi : ((AbstractMergeNode) node).phis()) {
                    visited.mark(phi);
                    nodes.add(phi);
                }
            }
            if (stateAfter != null) {
                visitForward(nodes, visited, stateAfter, true);
            }
        }
    } catch (GraalError e) {
        throw GraalGraphError.transformAndAddContext(e, node);
    }
}
Also used : GraalError(org.graalvm.compiler.debug.GraalError) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) FullInfopointNode(org.graalvm.compiler.nodes.FullInfopointNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FrameState(org.graalvm.compiler.nodes.FrameState) StateSplit(org.graalvm.compiler.nodes.StateSplit)

Example 8 with StateSplit

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

the class GraphOrder method assertSchedulableGraph.

/**
 * This method schedules the graph and makes sure that, for every node, all inputs are available
 * at the position where it is scheduled. This is a very expensive assertion.
 */
public static boolean assertSchedulableGraph(final StructuredGraph graph) {
    assert graph.getGuardsStage() != GuardsStage.AFTER_FSA : "Cannot use the BlockIteratorClosure after FrameState Assignment, HIR Loop Data Structures are no longer valid.";
    try {
        final SchedulePhase schedulePhase = new SchedulePhase(SchedulingStrategy.LATEST_OUT_OF_LOOPS, true);
        final EconomicMap<LoopBeginNode, NodeBitMap> loopEntryStates = EconomicMap.create(Equivalence.IDENTITY);
        schedulePhase.apply(graph, false);
        final ScheduleResult schedule = graph.getLastSchedule();
        BlockIteratorClosure<NodeBitMap> closure = new BlockIteratorClosure<NodeBitMap>() {

            @Override
            protected List<NodeBitMap> processLoop(Loop<Block> loop, NodeBitMap initialState) {
                return ReentrantBlockIterator.processLoop(this, loop, initialState).exitStates;
            }

            @Override
            protected NodeBitMap processBlock(final Block block, final NodeBitMap currentState) {
                final List<Node> list = graph.getLastSchedule().getBlockToNodesMap().get(block);
                /*
                     * A stateAfter is not valid directly after its associated state split, but
                     * right before the next fixed node. Therefore a pending stateAfter is kept that
                     * will be checked at the correct position.
                     */
                FrameState pendingStateAfter = null;
                for (final Node node : list) {
                    if (node instanceof ValueNode) {
                        FrameState stateAfter = node instanceof StateSplit ? ((StateSplit) node).stateAfter() : null;
                        if (node instanceof FullInfopointNode) {
                            stateAfter = ((FullInfopointNode) node).getState();
                        }
                        if (pendingStateAfter != null && node instanceof FixedNode) {
                            pendingStateAfter.applyToNonVirtual(new NodeClosure<Node>() {

                                @Override
                                public void apply(Node usage, Node nonVirtualNode) {
                                    assert currentState.isMarked(nonVirtualNode) || nonVirtualNode instanceof VirtualObjectNode || nonVirtualNode instanceof ConstantNode : nonVirtualNode + " not available at virtualstate " + usage + " before " + node + " in block " + block + " \n" + list;
                                }
                            });
                            pendingStateAfter = null;
                        }
                        if (node instanceof AbstractMergeNode) {
                            // phis aren't scheduled, so they need to be added explicitly
                            currentState.markAll(((AbstractMergeNode) node).phis());
                            if (node instanceof LoopBeginNode) {
                                // remember the state at the loop entry, it's restored at exits
                                loopEntryStates.put((LoopBeginNode) node, currentState.copy());
                            }
                        } else if (node instanceof ProxyNode) {
                            assert false : "proxy nodes should not be in the schedule";
                        } else if (node instanceof LoopExitNode) {
                            if (graph.hasValueProxies()) {
                                for (ProxyNode proxy : ((LoopExitNode) node).proxies()) {
                                    for (Node input : proxy.inputs()) {
                                        if (input != proxy.proxyPoint()) {
                                            assert currentState.isMarked(input) : input + " not available at " + proxy + " in block " + block + "\n" + list;
                                        }
                                    }
                                }
                                // loop contents are only accessible via proxies at the exit
                                currentState.clearAll();
                                currentState.markAll(loopEntryStates.get(((LoopExitNode) node).loopBegin()));
                            }
                            // Loop proxies aren't scheduled, so they need to be added
                            // explicitly
                            currentState.markAll(((LoopExitNode) node).proxies());
                        } else {
                            for (Node input : node.inputs()) {
                                if (input != stateAfter) {
                                    if (input instanceof FrameState) {
                                        ((FrameState) input).applyToNonVirtual(new VirtualState.NodeClosure<Node>() {

                                            @Override
                                            public void apply(Node usage, Node nonVirtual) {
                                                assert currentState.isMarked(nonVirtual) : nonVirtual + " not available at " + node + " in block " + block + "\n" + list;
                                            }
                                        });
                                    } else {
                                        assert currentState.isMarked(input) || input instanceof VirtualObjectNode || input instanceof ConstantNode : input + " not available at " + node + " in block " + block + "\n" + list;
                                    }
                                }
                            }
                        }
                        if (node instanceof AbstractEndNode) {
                            AbstractMergeNode merge = ((AbstractEndNode) node).merge();
                            for (PhiNode phi : merge.phis()) {
                                ValueNode phiValue = phi.valueAt((AbstractEndNode) node);
                                assert phiValue == null || currentState.isMarked(phiValue) || phiValue instanceof ConstantNode : phiValue + " not available at phi " + phi + " / end " + node + " in block " + block;
                            }
                        }
                        if (stateAfter != null) {
                            assert pendingStateAfter == null;
                            pendingStateAfter = stateAfter;
                        }
                        currentState.mark(node);
                    }
                }
                if (pendingStateAfter != null) {
                    pendingStateAfter.applyToNonVirtual(new NodeClosure<Node>() {

                        @Override
                        public void apply(Node usage, Node nonVirtualNode) {
                            assert currentState.isMarked(nonVirtualNode) || nonVirtualNode instanceof VirtualObjectNode || nonVirtualNode instanceof ConstantNode : nonVirtualNode + " not available at virtualstate " + usage + " at end of block " + block + " \n" + list;
                        }
                    });
                }
                return currentState;
            }

            @Override
            protected NodeBitMap merge(Block merge, List<NodeBitMap> states) {
                NodeBitMap result = states.get(0);
                for (int i = 1; i < states.size(); i++) {
                    result.intersect(states.get(i));
                }
                return result;
            }

            @Override
            protected NodeBitMap getInitialState() {
                NodeBitMap ret = graph.createNodeBitMap();
                ret.markAll(graph.getNodes().filter(ConstantNode.class));
                return ret;
            }

            @Override
            protected NodeBitMap cloneState(NodeBitMap oldState) {
                return oldState.copy();
            }
        };
        ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock());
    } catch (Throwable t) {
        graph.getDebug().handle(t);
    }
    return true;
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) SchedulePhase(org.graalvm.compiler.phases.schedule.SchedulePhase) ScheduleResult(org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) FullInfopointNode(org.graalvm.compiler.nodes.FullInfopointNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) FrameState(org.graalvm.compiler.nodes.FrameState) VirtualState(org.graalvm.compiler.nodes.VirtualState) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) ArrayList(java.util.ArrayList) List(java.util.List) Loop(org.graalvm.compiler.core.common.cfg.Loop) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) BlockIteratorClosure(org.graalvm.compiler.phases.graph.ReentrantBlockIterator.BlockIteratorClosure) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) NodeBitMap(org.graalvm.compiler.graph.NodeBitMap) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FullInfopointNode(org.graalvm.compiler.nodes.FullInfopointNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) Block(org.graalvm.compiler.nodes.cfg.Block) StateSplit(org.graalvm.compiler.nodes.StateSplit)

Example 9 with StateSplit

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

the class HostedBytecodeParser method finishInstruction.

/**
 * Insert deopt entries after all state splits.
 */
@Override
protected FixedWithNextNode finishInstruction(FixedWithNextNode instr, FrameStateBuilder stateBuilder) {
    if (getMethod().compilationInfo.isDeoptTarget() && !parsingIntrinsic()) {
        FrameState stateAfter = null;
        if (instr instanceof StateSplit && !(instr instanceof DeoptEntryNode)) {
            /*
                 * The regular case: the instruction is a state split and we insert a DeoptEntryNode
                 * right after it.
                 */
            StateSplit stateSplit = (StateSplit) instr;
            stateAfter = stateSplit.stateAfter();
        } else if (instr instanceof AbstractBeginNode) {
            /*
                 * We are at a block begin. If the block predecessor is a LoopExitNode or an
                 * InvokeWithException (both are state splits), we didn't inserted a deopt entry
                 * yet. So we do it at the begin of a block.
                 *
                 * Note that this only happens if the LoopExitNode/InvokeWithException is the
                 * _single_ predcessor of this block. In case of multiple predecessors, the block
                 * starts with a MergeNode and this is handled like a regular case.
                 */
            Node predecessor = instr.predecessor();
            if (predecessor instanceof KillingBeginNode) {
                /*
                     * This is between an InvokeWithException and the BlockPlaceholderNode.
                     */
                predecessor = predecessor.predecessor();
            }
            if (predecessor instanceof StateSplit && !(predecessor instanceof DeoptEntryNode)) {
                stateAfter = ((StateSplit) predecessor).stateAfter();
            }
        }
        boolean needsDeoptEntry = false;
        boolean needsProxies = false;
        if (stateAfter != null) {
            if (getMethod().compilationInfo.isDeoptEntry(stateAfter.bci, stateAfter.duringCall(), stateAfter.rethrowException())) {
                needsDeoptEntry = true;
                needsProxies = true;
            } else if (instr.predecessor() instanceof Invoke && getMethod().compilationInfo.isDeoptEntry(((Invoke) instr.predecessor()).bci(), true, false)) {
                /*
                     * Invoke nodes can be implicit deoptimization entry points. But we cannot
                     * anchor proxy nodes on invocations: The invoke has two successors (normal and
                     * exception handler), and we need to proxy values at the beginning of both.
                     */
                needsProxies = true;
            } else if (instr instanceof ExceptionObjectNode && getMethod().compilationInfo.isDeoptEntry(((ExceptionObjectNode) instr).stateAfter().bci, true, false)) {
                /*
                     * The predecessor of the ExceptionObjectNode will be an Invoke, but the Invoke
                     * has not been created yet. So the check above for the predecessor does not
                     * trigger.
                     */
                needsProxies = true;
            }
        }
        if (needsProxies) {
            long encodedBci = FrameInfoEncoder.encodeBci(stateAfter.bci, stateAfter.duringCall(), stateAfter.rethrowException());
            DeoptProxyAnchorNode existingDeoptEntry = deoptEntries.get(encodedBci);
            if (existingDeoptEntry != STICKY_DEOPT_ENTRY) {
                if (existingDeoptEntry != null) {
                    /*
                         * Some state splits (i.e. MergeNode and DispatchBeginNode) do not have a
                         * correspondent byte code. Therefore there can be a previously added deopt
                         * entry with the same BCI. For MergeNodes we replace the previous entry
                         * because the new frame state has less live locals.
                         */
                    existingDeoptEntry.replaceAtUsages(null);
                    graph.removeFixed(existingDeoptEntry);
                    deoptEntries.remove(encodedBci);
                    if (existingDeoptEntry instanceof DeoptEntryNode) {
                        /*
                             * We already had a DeoptEntryNode registered earlier for some reason,
                             * so be conservative and create one again (and not just a
                             * DeoptProxyAnchorNode).
                             */
                        needsDeoptEntry = true;
                    }
                }
                assert !deoptEntries.containsKey(encodedBci) : "duplicate deopt entry for encoded BCI " + encodedBci;
                DeoptProxyAnchorNode deoptEntry = createDeoptEntry(stateBuilder, stateAfter, !needsDeoptEntry);
                if (instr instanceof LoopBeginNode) {
                    /*
                         * Loop headers to not have their own bci. Never move a deopt entry for the
                         * loop header down, e.g., into a loop end (that might then end up to be
                         * dead code).
                         */
                    deoptEntries.put(encodedBci, STICKY_DEOPT_ENTRY);
                } else {
                    deoptEntries.put(encodedBci, deoptEntry);
                }
                assert instr.next() == null : "cannot append instruction to instruction which isn't end (" + instr + "->" + instr.next() + ")";
                instr.setNext(deoptEntry);
                return deoptEntry;
            }
        }
    }
    return super.finishInstruction(instr, stateBuilder);
}
Also used : DeoptProxyAnchorNode(com.oracle.svm.core.graal.nodes.DeoptProxyAnchorNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) DeoptEntryNode(com.oracle.svm.core.graal.nodes.DeoptEntryNode) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) SubstrateMethodCallTargetNode(com.oracle.svm.hosted.nodes.SubstrateMethodCallTargetNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) DeoptEntryNode(com.oracle.svm.core.graal.nodes.DeoptEntryNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) DeoptProxyAnchorNode(com.oracle.svm.core.graal.nodes.DeoptProxyAnchorNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) DeoptProxyNode(com.oracle.svm.hosted.nodes.DeoptProxyNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) FrameState(org.graalvm.compiler.nodes.FrameState) StateSplit(org.graalvm.compiler.nodes.StateSplit) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) Invoke(org.graalvm.compiler.nodes.Invoke)

Example 10 with StateSplit

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

the class BytecodeParser method genReturn.

protected void genReturn(ValueNode returnVal, JavaKind returnKind) {
    if (parsingIntrinsic() && returnVal != null) {
        if (returnVal instanceof StateSplit) {
            StateSplit stateSplit = (StateSplit) returnVal;
            FrameState stateAfter = stateSplit.stateAfter();
            if (stateSplit.hasSideEffect()) {
                assert stateSplit != null;
                if (stateAfter.bci == BytecodeFrame.AFTER_BCI) {
                    assert stateAfter.usages().count() == 1;
                    assert stateAfter.usages().first() == stateSplit;
                    stateAfter.replaceAtUsages(graph.add(new FrameState(BytecodeFrame.AFTER_BCI, returnVal)));
                    GraphUtil.killWithUnusedFloatingInputs(stateAfter);
                } else {
                    /*
                         * This must be the return value from within a partial intrinsification.
                         */
                    assert !BytecodeFrame.isPlaceholderBci(stateAfter.bci);
                }
            } else {
                assert stateAfter == null;
            }
        }
    }
    ValueNode realReturnVal = processReturnValue(returnVal, returnKind);
    frameState.setRethrowException(false);
    frameState.clearStack();
    beforeReturn(realReturnVal, returnKind);
    if (parent == null) {
        append(new ReturnNode(realReturnVal));
    } else {
        if (returnDataList == null) {
            returnDataList = new ArrayList<>();
        }
        returnDataList.add(new ReturnToCallerData(realReturnVal, lastInstr));
        lastInstr = null;
    }
}
Also used : ReturnNode(org.graalvm.compiler.nodes.ReturnNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) FrameState(org.graalvm.compiler.nodes.FrameState) StateSplit(org.graalvm.compiler.nodes.StateSplit)

Aggregations

StateSplit (org.graalvm.compiler.nodes.StateSplit)15 Node (org.graalvm.compiler.graph.Node)11 FrameState (org.graalvm.compiler.nodes.FrameState)11 ValueNode (org.graalvm.compiler.nodes.ValueNode)11 FixedNode (org.graalvm.compiler.nodes.FixedNode)10 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)9 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)8 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)7 PhiNode (org.graalvm.compiler.nodes.PhiNode)7 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)6 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)6 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)6 ReturnNode (org.graalvm.compiler.nodes.ReturnNode)6 MethodCallTargetNode (org.graalvm.compiler.nodes.java.MethodCallTargetNode)6 EndNode (org.graalvm.compiler.nodes.EndNode)5 ParameterNode (org.graalvm.compiler.nodes.ParameterNode)5 ExceptionObjectNode (org.graalvm.compiler.nodes.java.ExceptionObjectNode)5 BeginNode (org.graalvm.compiler.nodes.BeginNode)4 InvokeNode (org.graalvm.compiler.nodes.InvokeNode)4 KillingBeginNode (org.graalvm.compiler.nodes.KillingBeginNode)4