Search in sources :

Example 1 with LoopExitNode

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

the class GraphUtil method fixSurvivingAffectedMerges.

private static void fixSurvivingAffectedMerges(EconomicSet<Node> markedNodes, EconomicMap<AbstractMergeNode, List<AbstractEndNode>> unmarkedMerges) {
    MapCursor<AbstractMergeNode, List<AbstractEndNode>> cursor = unmarkedMerges.getEntries();
    while (cursor.advance()) {
        AbstractMergeNode merge = cursor.getKey();
        for (AbstractEndNode end : cursor.getValue()) {
            merge.removeEnd(end);
        }
        if (merge.phiPredecessorCount() == 1) {
            if (merge instanceof LoopBeginNode) {
                LoopBeginNode loopBegin = (LoopBeginNode) merge;
                assert merge.forwardEndCount() == 1;
                for (LoopExitNode loopExit : loopBegin.loopExits().snapshot()) {
                    if (markedNodes.contains(loopExit)) {
                        /*
                             * disconnect from loop begin so that reduceDegenerateLoopBegin doesn't
                             * transform it into a new beginNode
                             */
                        loopExit.replaceFirstInput(loopBegin, null);
                    }
                }
                merge.graph().reduceDegenerateLoopBegin(loopBegin);
            } else {
                merge.graph().reduceTrivialMerge(merge);
            }
        } else {
            assert merge.phiPredecessorCount() > 1 : merge;
        }
    }
}
Also used : LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) List(java.util.List) ArrayList(java.util.ArrayList) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode)

Example 2 with LoopExitNode

use of org.graalvm.compiler.nodes.LoopExitNode 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 3 with LoopExitNode

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

the class BytecodeParser method checkLoopExit.

private Target checkLoopExit(FixedNode target, BciBlock targetBlock, FrameStateBuilder state) {
    if (currentBlock != null) {
        long exits = currentBlock.loops & ~targetBlock.loops;
        if (exits != 0) {
            LoopExitNode firstLoopExit = null;
            LoopExitNode lastLoopExit = null;
            int pos = 0;
            ArrayList<BciBlock> exitLoops = new ArrayList<>(Long.bitCount(exits));
            do {
                long lMask = 1L << pos;
                if ((exits & lMask) != 0) {
                    exitLoops.add(blockMap.getLoopHeader(pos));
                    exits &= ~lMask;
                }
                pos++;
            } while (exits != 0);
            Collections.sort(exitLoops, new Comparator<BciBlock>() {

                @Override
                public int compare(BciBlock o1, BciBlock o2) {
                    return Long.bitCount(o2.loops) - Long.bitCount(o1.loops);
                }
            });
            int bci = targetBlock.startBci;
            if (targetBlock instanceof ExceptionDispatchBlock) {
                bci = ((ExceptionDispatchBlock) targetBlock).deoptBci;
            }
            FrameStateBuilder newState = state.copy();
            for (BciBlock loop : exitLoops) {
                LoopBeginNode loopBegin = (LoopBeginNode) getFirstInstruction(loop);
                LoopExitNode loopExit = graph.add(new LoopExitNode(loopBegin));
                if (lastLoopExit != null) {
                    lastLoopExit.setNext(loopExit);
                }
                if (firstLoopExit == null) {
                    firstLoopExit = loopExit;
                }
                lastLoopExit = loopExit;
                debug.log("Target %s Exits %s, scanning framestates...", targetBlock, loop);
                newState.clearNonLiveLocals(targetBlock, liveness, true);
                newState.insertLoopProxies(loopExit, getEntryState(loop));
                loopExit.setStateAfter(newState.create(bci, loopExit));
            }
            lastLoopExit.setNext(target);
            return new Target(firstLoopExit, newState);
        }
    }
    return new Target(target, state);
}
Also used : LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) ExceptionDispatchBlock(org.graalvm.compiler.java.BciBlockMapping.ExceptionDispatchBlock) ArrayList(java.util.ArrayList) BciBlock(org.graalvm.compiler.java.BciBlockMapping.BciBlock) RuntimeConstraint(jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint)

Example 4 with LoopExitNode

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

the class LoopTransformations method insertPrePostLoops.

// This function splits candidate loops into pre, main and post loops,
// dividing the iteration space to facilitate the majority of iterations
// being executed in a main loop, which will have RCE implemented upon it.
// The initial loop form is constrained to single entry/exit, but can have
// flow. The translation looks like:
// 
// @formatter:off
// 
// (Simple Loop entry)                   (Pre Loop Entry)
// |                                  |
// (LoopBeginNode)                    (LoopBeginNode)
// |                                  |
// (Loop Control Test)<------   ==>  (Loop control Test)<------
// /               \       \         /               \       \
// (Loop Exit)      (Loop Body) |    (Loop Exit)      (Loop Body) |
// |                |       |        |                |       |
// (continue code)     (Loop End)  |  if (M < length)*   (Loop End)  |
// \       /       /      \           \      /
// ----->        /       |            ----->
// /  if ( ... )*
// /     /       \
// /     /         \
// /     /           \
// |     /     (Main Loop Entry)
// |    |             |
// |    |      (LoopBeginNode)
// |    |             |
// |    |     (Loop Control Test)<------
// |    |      /               \        \
// |    |  (Loop Exit)      (Loop Body) |
// \   \      |                |       |
// \   \     |            (Loop End)  |
// \   \    |                \       /
// \   \   |                 ------>
// \   \  |
// (Main Loop Merge)*
// |
// (Post Loop Entry)
// |
// (LoopBeginNode)
// |
// (Loop Control Test)<-----
// /               \       \
// (Loop Exit)     (Loop Body) |
// |               |       |
// (continue code)    (Loop End)  |
// \      /
// ----->
// 
// Key: "*" = optional.
// @formatter:on
// 
// The value "M" is the maximal value of the loop trip for the original
// loop. The value of "length" is applicable to the number of arrays found
// in the loop but is reduced if some or all of the arrays are known to be
// the same length as "M". The maximum number of tests can be equal to the
// number of arrays in the loop, where multiple instances of an array are
// subsumed into a single test for that arrays length.
// 
// If the optional main loop entry tests are absent, the Pre Loop exit
// connects to the Main loops entry and there is no merge hanging off the
// main loops exit to converge flow from said tests. All split use data
// flow is mitigated through phi(s) in the main merge if present and
// passed through the main and post loop phi(s) from the originating pre
// loop with final phi(s) and data flow patched to the "continue code".
// The pre loop is constrained to one iteration for now and will likely
// be updated to produce vector alignment if applicable.
public static LoopBeginNode insertPrePostLoops(LoopEx loop) {
    StructuredGraph graph = loop.loopBegin().graph();
    graph.getDebug().log("LoopTransformations.insertPrePostLoops %s", loop);
    LoopFragmentWhole preLoop = loop.whole();
    CountedLoopInfo preCounted = loop.counted();
    IfNode preLimit = preCounted.getLimitTest();
    assert preLimit != null;
    LoopBeginNode preLoopBegin = loop.loopBegin();
    InductionVariable preIv = preCounted.getCounter();
    LoopExitNode preLoopExitNode = preLoopBegin.getSingleLoopExit();
    FixedNode continuationNode = preLoopExitNode.next();
    // Each duplication is inserted after the original, ergo create the post loop first
    LoopFragmentWhole mainLoop = preLoop.duplicate();
    LoopFragmentWhole postLoop = preLoop.duplicate();
    preLoopBegin.incrementSplits();
    preLoopBegin.incrementSplits();
    preLoopBegin.setPreLoop();
    graph.getDebug().dump(DebugContext.VERBOSE_LEVEL, graph, "After duplication");
    LoopBeginNode mainLoopBegin = mainLoop.getDuplicatedNode(preLoopBegin);
    mainLoopBegin.setMainLoop();
    LoopBeginNode postLoopBegin = postLoop.getDuplicatedNode(preLoopBegin);
    postLoopBegin.setPostLoop();
    EndNode postEndNode = getBlockEndAfterLoopExit(postLoopBegin);
    AbstractMergeNode postMergeNode = postEndNode.merge();
    LoopExitNode postLoopExitNode = postLoopBegin.getSingleLoopExit();
    // Update the main loop phi initialization to carry from the pre loop
    for (PhiNode prePhiNode : preLoopBegin.phis()) {
        PhiNode mainPhiNode = mainLoop.getDuplicatedNode(prePhiNode);
        mainPhiNode.setValueAt(0, prePhiNode);
    }
    EndNode mainEndNode = getBlockEndAfterLoopExit(mainLoopBegin);
    AbstractMergeNode mainMergeNode = mainEndNode.merge();
    AbstractEndNode postEntryNode = postLoopBegin.forwardEnd();
    // In the case of no Bounds tests, we just flow right into the main loop
    AbstractBeginNode mainLandingNode = BeginNode.begin(postEntryNode);
    LoopExitNode mainLoopExitNode = mainLoopBegin.getSingleLoopExit();
    mainLoopExitNode.setNext(mainLandingNode);
    preLoopExitNode.setNext(mainLoopBegin.forwardEnd());
    // Add and update any phi edges as per merge usage as needed and update usages
    processPreLoopPhis(loop, mainLoop, postLoop);
    continuationNode.predecessor().clearSuccessors();
    postLoopExitNode.setNext(continuationNode);
    cleanupMerge(postMergeNode, postLoopExitNode);
    cleanupMerge(mainMergeNode, mainLandingNode);
    // Change the preLoop to execute one iteration for now
    updateMainLoopLimit(preLimit, preIv, mainLoop);
    updatePreLoopLimit(preLimit, preIv, preCounted);
    preLoopBegin.setLoopFrequency(1);
    mainLoopBegin.setLoopFrequency(Math.max(0.0, mainLoopBegin.loopFrequency() - 2));
    postLoopBegin.setLoopFrequency(Math.max(0.0, postLoopBegin.loopFrequency() - 1));
    // The pre and post loops don't require safepoints at all
    for (SafepointNode safepoint : preLoop.nodes().filter(SafepointNode.class)) {
        graph.removeFixed(safepoint);
    }
    for (SafepointNode safepoint : postLoop.nodes().filter(SafepointNode.class)) {
        graph.removeFixed(safepoint);
    }
    graph.getDebug().dump(DebugContext.DETAILED_LEVEL, graph, "InsertPrePostLoops %s", loop);
    return mainLoopBegin;
}
Also used : LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) SafepointNode(org.graalvm.compiler.nodes.SafepointNode) CountedLoopInfo(org.graalvm.compiler.loop.CountedLoopInfo) IfNode(org.graalvm.compiler.nodes.IfNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) LoopFragmentWhole(org.graalvm.compiler.loop.LoopFragmentWhole) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) InductionVariable(org.graalvm.compiler.loop.InductionVariable)

Example 5 with LoopExitNode

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

the class LoopFragmentInside method patchPeeling.

private void patchPeeling(LoopFragmentInside peel) {
    LoopBeginNode loopBegin = loop().loopBegin();
    StructuredGraph graph = loopBegin.graph();
    List<PhiNode> newPhis = new LinkedList<>();
    NodeBitMap usagesToPatch = nodes.copy();
    for (LoopExitNode exit : exits()) {
        markStateNodes(exit, usagesToPatch);
        for (ProxyNode proxy : exit.proxies()) {
            usagesToPatch.markAndGrow(proxy);
        }
    }
    markStateNodes(loopBegin, usagesToPatch);
    List<PhiNode> oldPhis = loopBegin.phis().snapshot();
    for (PhiNode phi : oldPhis) {
        if (phi.hasNoUsages()) {
            continue;
        }
        ValueNode first;
        if (loopBegin.loopEnds().count() == 1) {
            // back edge value
            ValueNode b = phi.valueAt(loopBegin.loopEnds().first());
            // corresponding value in the peel
            first = peel.prim(b);
        } else {
            first = peel.mergedInitializers.get(phi);
        }
        // create a new phi (we don't patch the old one since some usages of the old one may
        // still be valid)
        PhiNode newPhi = patchPhi(graph, phi, loopBegin);
        newPhi.addInput(first);
        for (LoopEndNode end : loopBegin.orderedLoopEnds()) {
            newPhi.addInput(phi.valueAt(end));
        }
        peel.putDuplicatedNode(phi, newPhi);
        newPhis.add(newPhi);
        for (Node usage : phi.usages().snapshot()) {
            // patch only usages that should use the new phi ie usages that were peeled
            if (usagesToPatch.isMarkedAndGrow(usage)) {
                usage.replaceFirstInput(phi, newPhi);
            }
        }
    }
    // new corresponding phis
    for (PhiNode phi : newPhis) {
        for (int i = 0; i < phi.valueCount(); i++) {
            ValueNode v = phi.valueAt(i);
            if (loopBegin.isPhiAtMerge(v)) {
                PhiNode newV = peel.getDuplicatedNode((ValuePhiNode) v);
                if (newV != null) {
                    phi.setValueAt(i, newV);
                }
            }
        }
    }
    boolean progress = true;
    while (progress) {
        progress = false;
        int i = 0;
        outer: while (i < oldPhis.size()) {
            PhiNode oldPhi = oldPhis.get(i);
            for (Node usage : oldPhi.usages()) {
                if (usage instanceof PhiNode && oldPhis.contains(usage)) {
                // Do not mark.
                } else {
                    // Mark alive by removing from delete set.
                    oldPhis.remove(i);
                    progress = true;
                    continue outer;
                }
            }
            i++;
        }
    }
    for (PhiNode deadPhi : oldPhis) {
        deadPhi.clearInputs();
    }
    for (PhiNode deadPhi : oldPhis) {
        if (deadPhi.isAlive()) {
            GraphUtil.killWithUnusedFloatingInputs(deadPhi);
        }
    }
}
Also used : ProxyNode(org.graalvm.compiler.nodes.ProxyNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) MemoryPhiNode(org.graalvm.compiler.nodes.memory.MemoryPhiNode) GuardPhiNode(org.graalvm.compiler.nodes.GuardPhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) NodeBitMap(org.graalvm.compiler.graph.NodeBitMap) 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) LinkedList(java.util.LinkedList) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Aggregations

LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)25 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)18 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)17 FixedNode (org.graalvm.compiler.nodes.FixedNode)16 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)14 Node (org.graalvm.compiler.graph.Node)13 EndNode (org.graalvm.compiler.nodes.EndNode)12 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)10 LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)10 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)10 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)9 PhiNode (org.graalvm.compiler.nodes.PhiNode)9 ProxyNode (org.graalvm.compiler.nodes.ProxyNode)9 ValueNode (org.graalvm.compiler.nodes.ValueNode)9 MergeNode (org.graalvm.compiler.nodes.MergeNode)8 ArrayList (java.util.ArrayList)6 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)6 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)6 IfNode (org.graalvm.compiler.nodes.IfNode)6 FrameState (org.graalvm.compiler.nodes.FrameState)5