Search in sources :

Example 1 with LLVMBasicBlockNode

use of com.oracle.truffle.llvm.nodes.base.LLVMBasicBlockNode in project sulong by graalvm.

the class LLVMDispatchBasicBlockNode method executeGeneric.

@Override
@ExplodeLoop(kind = LoopExplosionKind.MERGE_EXPLODE)
public Object executeGeneric(VirtualFrame frame) {
    copyArgumentsToFrame(frame);
    Object returnValue = null;
    CompilerAsserts.compilationConstant(bodyNodes.length);
    int basicBlockIndex = 0;
    int backEdgeCounter = 0;
    outer: while (basicBlockIndex != LLVMBasicBlockNode.RETURN_FROM_FUNCTION) {
        CompilerAsserts.partialEvaluationConstant(basicBlockIndex);
        LLVMBasicBlockNode bb = bodyNodes[basicBlockIndex];
        // execute all statements
        bb.executeStatements(frame);
        // execute control flow node, write phis, null stack frame slots, and dispatch to
        // the correct successor block
        LLVMControlFlowNode controlFlowNode = bb.termInstruction;
        if (controlFlowNode instanceof LLVMConditionalBranchNode) {
            LLVMConditionalBranchNode conditionalBranchNode = (LLVMConditionalBranchNode) controlFlowNode;
            boolean condition = conditionalBranchNode.executeCondition(frame);
            if (CompilerDirectives.injectBranchProbability(bb.getBranchProbability(LLVMConditionalBranchNode.TRUE_SUCCESSOR), condition)) {
                if (CompilerDirectives.inInterpreter()) {
                    bb.increaseBranchProbability(LLVMConditionalBranchNode.TRUE_SUCCESSOR);
                    if (conditionalBranchNode.getTrueSuccessor() <= basicBlockIndex) {
                        backEdgeCounter++;
                    }
                }
                executePhis(frame, conditionalBranchNode, LLVMConditionalBranchNode.TRUE_SUCCESSOR);
                nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
                basicBlockIndex = conditionalBranchNode.getTrueSuccessor();
                nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
                continue outer;
            } else {
                if (CompilerDirectives.inInterpreter()) {
                    bb.increaseBranchProbability(LLVMConditionalBranchNode.FALSE_SUCCESSOR);
                    if (conditionalBranchNode.getFalseSuccessor() <= basicBlockIndex) {
                        backEdgeCounter++;
                    }
                }
                executePhis(frame, conditionalBranchNode, LLVMConditionalBranchNode.FALSE_SUCCESSOR);
                nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
                basicBlockIndex = conditionalBranchNode.getFalseSuccessor();
                nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
                continue outer;
            }
        } 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++) {
                Object caseValue = switchNode.getCase(i).executeGeneric(frame);
                assert caseValue.getClass() == condition.getClass() : "must be the same type - otherwise equals might wrongly return false";
                if (CompilerDirectives.injectBranchProbability(bb.getBranchProbability(i), condition.equals(caseValue))) {
                    if (CompilerDirectives.inInterpreter()) {
                        bb.increaseBranchProbability(i);
                        if (successors[i] <= basicBlockIndex) {
                            backEdgeCounter++;
                        }
                    }
                    executePhis(frame, switchNode, i);
                    nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
                    basicBlockIndex = successors[i];
                    nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
                    continue outer;
                }
            }
            int i = successors.length - 1;
            if (CompilerDirectives.inInterpreter()) {
                bb.increaseBranchProbability(i);
                if (successors[i] <= basicBlockIndex) {
                    backEdgeCounter++;
                }
            }
            executePhis(frame, switchNode, i);
            nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
            basicBlockIndex = successors[i];
            nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
            continue outer;
        } 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)) {
                    if (CompilerDirectives.inInterpreter()) {
                        bb.increaseBranchProbability(i);
                        if (successors[i] <= basicBlockIndex) {
                            backEdgeCounter++;
                        }
                    }
                    executePhis(frame, indirectBranchNode, i);
                    nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
                    basicBlockIndex = successors[i];
                    nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
                    continue outer;
                }
            }
            int i = successors.length - 1;
            assert successorBasicBlockIndex == successors[i];
            if (CompilerDirectives.inInterpreter()) {
                bb.increaseBranchProbability(i);
                if (successors[i] <= basicBlockIndex) {
                    backEdgeCounter++;
                }
            }
            executePhis(frame, indirectBranchNode, i);
            nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
            basicBlockIndex = successors[i];
            nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
            continue outer;
        } else if (controlFlowNode instanceof LLVMBrUnconditionalNode) {
            LLVMBrUnconditionalNode unconditionalNode = (LLVMBrUnconditionalNode) controlFlowNode;
            if (CompilerDirectives.inInterpreter()) {
                if (unconditionalNode.getSuccessor() <= basicBlockIndex) {
                    backEdgeCounter++;
                }
            }
            // required for instrumentation
            unconditionalNode.execute(frame);
            executePhis(frame, unconditionalNode, 0);
            nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
            basicBlockIndex = unconditionalNode.getSuccessor();
            nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
            continue outer;
        } else if (controlFlowNode instanceof LLVMInvokeNode) {
            LLVMInvokeNode invokeNode = (LLVMInvokeNode) controlFlowNode;
            try {
                invokeNode.execute(frame);
                if (CompilerDirectives.inInterpreter()) {
                    if (invokeNode.getNormalSuccessor() <= basicBlockIndex) {
                        backEdgeCounter++;
                    }
                }
                executePhis(frame, invokeNode, LLVMInvokeNode.NORMAL_SUCCESSOR);
                nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
                basicBlockIndex = invokeNode.getNormalSuccessor();
                nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
                continue outer;
            } catch (LLVMException e) {
                frame.setObject(exceptionValueSlot, e);
                if (CompilerDirectives.inInterpreter()) {
                    if (invokeNode.getUnwindSuccessor() <= basicBlockIndex) {
                        backEdgeCounter++;
                    }
                }
                executePhis(frame, invokeNode, LLVMInvokeNode.UNWIND_SUCCESSOR);
                nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
                basicBlockIndex = invokeNode.getUnwindSuccessor();
                nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
                continue outer;
            }
        } else if (controlFlowNode instanceof LLVMRetNode) {
            LLVMRetNode retNode = (LLVMRetNode) controlFlowNode;
            returnValue = retNode.execute(frame);
            assert noPhisNecessary(retNode);
            nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
            basicBlockIndex = retNode.getSuccessor();
            continue outer;
        } else if (controlFlowNode instanceof LLVMResumeNode) {
            LLVMResumeNode resumeNode = (LLVMResumeNode) controlFlowNode;
            assert noPhisNecessary(resumeNode);
            nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
            resumeNode.execute(frame);
            CompilerAsserts.neverPartOfCompilation();
            throw new IllegalStateException("must not reach here");
        } else if (controlFlowNode instanceof LLVMUnreachableNode) {
            LLVMUnreachableNode unreachableNode = (LLVMUnreachableNode) controlFlowNode;
            assert noPhisNecessary(unreachableNode);
            unreachableNode.execute();
            CompilerAsserts.neverPartOfCompilation();
            throw new IllegalStateException("must not reach here");
        } else {
            CompilerAsserts.neverPartOfCompilation();
            throw new UnsupportedOperationException("unexpected controlFlowNode type: " + controlFlowNode);
        }
    }
    assert backEdgeCounter >= 0;
    LoopNode.reportLoopCount(this, backEdgeCounter);
    return returnValue;
}
Also used : LLVMControlFlowNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMControlFlowNode) LLVMUnreachableNode(com.oracle.truffle.llvm.nodes.others.LLVMUnreachableNode) LLVMInvokeNode(com.oracle.truffle.llvm.nodes.func.LLVMInvokeNode) LLVMException(com.oracle.truffle.llvm.runtime.LLVMException) LLVMResumeNode(com.oracle.truffle.llvm.nodes.func.LLVMResumeNode) LLVMBasicBlockNode(com.oracle.truffle.llvm.nodes.base.LLVMBasicBlockNode) ExplodeLoop(com.oracle.truffle.api.nodes.ExplodeLoop)

Example 2 with LLVMBasicBlockNode

use of com.oracle.truffle.llvm.nodes.base.LLVMBasicBlockNode in project sulong by graalvm.

the class LLVMPrintStackTrace method fillStackTrace.

private static void fillStackTrace(SulongStackTrace stackTrace, Node node) {
    LLVMBasicBlockNode block = NodeUtil.findParent(node, LLVMBasicBlockNode.class);
    LLVMFunctionStartNode f = NodeUtil.findParent(node, LLVMFunctionStartNode.class);
    if (block == null || f == null) {
        LLVMIntrinsicExpressionNode intrinsic = NodeUtil.findParent(node, LLVMIntrinsicExpressionNode.class);
        if (intrinsic != null) {
            stackTrace.addStackTraceElement(intrinsic.toString(), null, null);
        }
        return;
    }
    LLVMSourceLocation location = null;
    if (node instanceof LLVMNode && ((LLVMNode) node).getSourceLocation() != null) {
        location = ((LLVMNode) node).getSourceLocation();
    }
    if (location == null) {
        location = block.getSourceLocation();
    }
    if (location != null) {
        stackTrace.addStackTraceElement(f.getOriginalName(), location, f.getBcName(), f.getBcSource().getName(), blockName(block));
        return;
    }
    SourceSection s = node.getSourceSection();
    if (s == null) {
        s = f.getSourceSection();
    }
    if (s == null) {
        stackTrace.addStackTraceElement(f.getBcName(), f.getBcSource().getName(), blockName(block));
    } else {
        location = LLVMSourceLocation.createUnknown(s);
        stackTrace.addStackTraceElement(f.getOriginalName(), location, f.getBcName(), f.getBcSource().getName(), blockName(block));
    }
}
Also used : LLVMFunctionStartNode(com.oracle.truffle.llvm.nodes.func.LLVMFunctionStartNode) LLVMIntrinsicExpressionNode(com.oracle.truffle.llvm.nodes.intrinsics.llvm.LLVMIntrinsicRootNode.LLVMIntrinsicExpressionNode) LLVMBasicBlockNode(com.oracle.truffle.llvm.nodes.base.LLVMBasicBlockNode) LLVMSourceLocation(com.oracle.truffle.llvm.runtime.debug.scope.LLVMSourceLocation) SourceSection(com.oracle.truffle.api.source.SourceSection) LLVMNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMNode)

Example 3 with LLVMBasicBlockNode

use of com.oracle.truffle.llvm.nodes.base.LLVMBasicBlockNode in project sulong by graalvm.

the class LLVMWriteNode method getSourceDescription.

@Override
public String getSourceDescription() {
    LLVMBasicBlockNode basicBlock = NodeUtil.findParent(this, LLVMBasicBlockNode.class);
    assert basicBlock != null : getParent().getClass();
    LLVMFunctionStartNode functionStartNode = NodeUtil.findParent(basicBlock, LLVMFunctionStartNode.class);
    assert functionStartNode != null : basicBlock.getParent().getClass();
    if (basicBlock.getBlockId() == 0) {
        return String.format("assignment of %s in first basic block in function %s", getSlot().getIdentifier(), functionStartNode.getBcName());
    } else {
        return String.format("assignment of %s in basic block %s in function %s", getSlot().getIdentifier(), basicBlock.getBlockName(), functionStartNode.getBcName());
    }
}
Also used : LLVMFunctionStartNode(com.oracle.truffle.llvm.nodes.func.LLVMFunctionStartNode) LLVMBasicBlockNode(com.oracle.truffle.llvm.nodes.base.LLVMBasicBlockNode)

Aggregations

LLVMBasicBlockNode (com.oracle.truffle.llvm.nodes.base.LLVMBasicBlockNode)3 LLVMFunctionStartNode (com.oracle.truffle.llvm.nodes.func.LLVMFunctionStartNode)2 ExplodeLoop (com.oracle.truffle.api.nodes.ExplodeLoop)1 SourceSection (com.oracle.truffle.api.source.SourceSection)1 LLVMInvokeNode (com.oracle.truffle.llvm.nodes.func.LLVMInvokeNode)1 LLVMResumeNode (com.oracle.truffle.llvm.nodes.func.LLVMResumeNode)1 LLVMIntrinsicExpressionNode (com.oracle.truffle.llvm.nodes.intrinsics.llvm.LLVMIntrinsicRootNode.LLVMIntrinsicExpressionNode)1 LLVMUnreachableNode (com.oracle.truffle.llvm.nodes.others.LLVMUnreachableNode)1 LLVMException (com.oracle.truffle.llvm.runtime.LLVMException)1 LLVMSourceLocation (com.oracle.truffle.llvm.runtime.debug.scope.LLVMSourceLocation)1 LLVMControlFlowNode (com.oracle.truffle.llvm.runtime.nodes.api.LLVMControlFlowNode)1 LLVMNode (com.oracle.truffle.llvm.runtime.nodes.api.LLVMNode)1