Search in sources :

Example 1 with LLVMUnreachableNode

use of com.oracle.truffle.llvm.runtime.nodes.others.LLVMUnreachableNode in project graal by oracle.

the class LLVMDispatchBasicBlockNode method dispatchFromBasicBlock.

/**
 * The code in this function is mirrored in {@link LLVMLoopDispatchNode}, any changes need to be
 * done in both places.
 */
@ExplodeLoop(kind = LoopExplosionKind.MERGE_EXPLODE)
private Object dispatchFromBasicBlock(VirtualFrame frame, int bci, Counter counter) {
    assert counter != null;
    Object returnValue = null;
    int basicBlockIndex = bci;
    CompilerAsserts.partialEvaluationConstant(bodyNodes.length);
    try {
        outer: while (basicBlockIndex != LLVMBasicBlockNode.RETURN_FROM_FUNCTION) {
            CompilerAsserts.partialEvaluationConstant(basicBlockIndex);
            LLVMBasicBlockNode bb = bodyNodes[basicBlockIndex];
            // lazily insert the basic block into the AST
            bb.initialize();
            // the newly inserted block may have been instrumented
            bb = bodyNodes[basicBlockIndex];
            // execute all statements
            bb.execute(frame);
            // execute control flow node, write phis, null stack frame slots, and dispatch to
            // the correct successor block
            LLVMControlFlowNode controlFlowNode = bb.getTerminatingInstruction();
            if (controlFlowNode instanceof LLVMConditionalBranchNode) {
                LLVMConditionalBranchNode conditionalBranchNode = (LLVMConditionalBranchNode) controlFlowNode;
                boolean condition = conditionalBranchNode.executeCondition(frame);
                if (CompilerDirectives.injectBranchProbability(bb.getBranchProbability(LLVMConditionalBranchNode.TRUE_SUCCESSOR), condition)) {
                    bb.enterSuccessor(LLVMConditionalBranchNode.TRUE_SUCCESSOR);
                    basicBlockIndex = beforeJumpChecks(basicBlockIndex, conditionalBranchNode.getTrueSuccessor(), LLVMConditionalBranchNode.TRUE_SUCCESSOR, counter, controlFlowNode, frame);
                // continue outer;
                } else {
                    bb.enterSuccessor(LLVMConditionalBranchNode.FALSE_SUCCESSOR);
                    basicBlockIndex = beforeJumpChecks(basicBlockIndex, conditionalBranchNode.getFalseSuccessor(), LLVMConditionalBranchNode.FALSE_SUCCESSOR, counter, controlFlowNode, frame);
                }
            } else if (controlFlowNode instanceof LLVMSwitchNode) {
                LLVMSwitchNode switchNode = (LLVMSwitchNode) controlFlowNode;
                Object condition = switchNode.executeCondition(frame);
                int[] successors = switchNode.getSuccessors();
                for (int i = 0; i < successors.length - 1; i++) {
                    if (CompilerDirectives.injectBranchProbability(bb.getBranchProbability(i), switchNode.checkCase(frame, i, condition))) {
                        bb.enterSuccessor(i);
                        basicBlockIndex = beforeJumpChecks(basicBlockIndex, successors[i], i, counter, controlFlowNode, frame);
                        continue outer;
                    }
                }
                int i = successors.length - 1;
                bb.enterSuccessor(i);
                basicBlockIndex = beforeJumpChecks(basicBlockIndex, successors[i], i, counter, controlFlowNode, frame);
            } else if (controlFlowNode instanceof LLVMLoopNode) {
                LLVMLoopNode loop = (LLVMLoopNode) controlFlowNode;
                loop.executeLoop(frame);
                int successorBasicBlockIndex = frame.getInt(loopSuccessorSlot);
                // null frame
                frame.setInt(loopSuccessorSlot, 0);
                int[] successors = loop.getSuccessors();
                for (int i = 0; i < successors.length - 1; i++) {
                    if (successorBasicBlockIndex == successors[i]) {
                        basicBlockIndex = beforeJumpChecks(basicBlockIndex, successors[i], -1, counter, null, frame);
                        continue outer;
                    }
                }
                int i = successors.length - 1;
                assert successors[i] == successorBasicBlockIndex : "Could not find loop successor!";
                basicBlockIndex = beforeJumpChecks(basicBlockIndex, successors[i], -1, counter, null, frame);
            } else if (controlFlowNode instanceof LLVMIndirectBranchNode) {
                // TODO (chaeubl): we need a different approach here - this is awfully
                // inefficient (see GR-3664)
                LLVMIndirectBranchNode indirectBranchNode = (LLVMIndirectBranchNode) controlFlowNode;
                int[] successors = indirectBranchNode.getSuccessors();
                int successorBasicBlockIndex = indirectBranchNode.executeCondition(frame);
                for (int i = 0; i < successors.length - 1; i++) {
                    if (CompilerDirectives.injectBranchProbability(bb.getBranchProbability(i), successors[i] == successorBasicBlockIndex)) {
                        bb.enterSuccessor(i);
                        basicBlockIndex = beforeJumpChecks(basicBlockIndex, successors[i], i, counter, controlFlowNode, frame);
                        continue outer;
                    }
                }
                int i = successors.length - 1;
                assert successorBasicBlockIndex == successors[i];
                bb.enterSuccessor(i);
                basicBlockIndex = beforeJumpChecks(basicBlockIndex, successors[i], i, counter, indirectBranchNode, frame);
            } else if (controlFlowNode instanceof LLVMBrUnconditionalNode) {
                LLVMBrUnconditionalNode unconditionalNode = (LLVMBrUnconditionalNode) controlFlowNode;
                // required for instrumentation
                unconditionalNode.execute(frame);
                basicBlockIndex = beforeJumpChecks(basicBlockIndex, unconditionalNode.getSuccessor(), 0, counter, controlFlowNode, frame);
            } else if (controlFlowNode instanceof LLVMInvokeNode) {
                LLVMInvokeNode invokeNode = (LLVMInvokeNode) controlFlowNode;
                try {
                    invokeNode.execute(frame);
                    bb.enterSuccessor(LLVMInvokeNode.NORMAL_SUCCESSOR);
                    basicBlockIndex = beforeJumpChecks(basicBlockIndex, invokeNode.getNormalSuccessor(), LLVMInvokeNode.NORMAL_SUCCESSOR, counter, controlFlowNode, frame);
                } catch (LLVMUserException e) {
                    bb.enterSuccessor(LLVMInvokeNode.UNWIND_SUCCESSOR);
                    frame.setObject(exceptionValueSlot, e);
                    basicBlockIndex = beforeJumpChecks(basicBlockIndex, invokeNode.getUnwindSuccessor(), LLVMInvokeNode.UNWIND_SUCCESSOR, counter, controlFlowNode, frame);
                }
            } else if (controlFlowNode instanceof LLVMRetNode) {
                LLVMRetNode retNode = (LLVMRetNode) controlFlowNode;
                returnValue = retNode.execute(frame);
                assert noPhisNecessary(retNode);
                nullDeadSlots(frame, bb.nullableAfter);
                basicBlockIndex = beforeJumpChecks(basicBlockIndex, retNode.getSuccessor(), -1, counter, null, frame);
            } else if (controlFlowNode instanceof LLVMResumeNode) {
                LLVMResumeNode resumeNode = (LLVMResumeNode) controlFlowNode;
                assert noPhisNecessary(resumeNode);
                resumeNode.execute(frame);
                CompilerDirectives.transferToInterpreterAndInvalidate();
                throw new IllegalStateException("must not reach here");
            } else if (controlFlowNode instanceof LLVMUnreachableNode) {
                LLVMUnreachableNode unreachableNode = (LLVMUnreachableNode) controlFlowNode;
                assert noPhisNecessary(unreachableNode);
                unreachableNode.execute(frame);
                CompilerDirectives.transferToInterpreterAndInvalidate();
                throw new IllegalStateException("must not reach here");
            } else {
                CompilerDirectives.transferToInterpreterAndInvalidate();
                throw new UnsupportedOperationException("unexpected controlFlowNode type: " + controlFlowNode);
            }
        }
    } catch (OSRReturnException e) {
        returnValue = e.getResult();
    }
    // only report non-zero counters to reduce interpreter overhead
    int value = counter.value;
    if (CompilerDirectives.hasNextTier() && value != 0) {
        LoopNode.reportLoopCount(this, value > 0 ? value : Integer.MAX_VALUE);
    }
    assert returnValue != null;
    return returnValue;
}
Also used : LLVMControlFlowNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMControlFlowNode) LLVMUnreachableNode(com.oracle.truffle.llvm.runtime.nodes.others.LLVMUnreachableNode) LLVMInvokeNode(com.oracle.truffle.llvm.runtime.nodes.func.LLVMInvokeNode) LLVMUserException(com.oracle.truffle.llvm.runtime.except.LLVMUserException) LLVMResumeNode(com.oracle.truffle.llvm.runtime.nodes.func.LLVMResumeNode) LLVMBasicBlockNode(com.oracle.truffle.llvm.runtime.nodes.base.LLVMBasicBlockNode) ExplodeLoop(com.oracle.truffle.api.nodes.ExplodeLoop)

Aggregations

ExplodeLoop (com.oracle.truffle.api.nodes.ExplodeLoop)1 LLVMUserException (com.oracle.truffle.llvm.runtime.except.LLVMUserException)1 LLVMControlFlowNode (com.oracle.truffle.llvm.runtime.nodes.api.LLVMControlFlowNode)1 LLVMBasicBlockNode (com.oracle.truffle.llvm.runtime.nodes.base.LLVMBasicBlockNode)1 LLVMInvokeNode (com.oracle.truffle.llvm.runtime.nodes.func.LLVMInvokeNode)1 LLVMResumeNode (com.oracle.truffle.llvm.runtime.nodes.func.LLVMResumeNode)1 LLVMUnreachableNode (com.oracle.truffle.llvm.runtime.nodes.others.LLVMUnreachableNode)1