Search in sources :

Example 1 with LLVMControlFlowNode

use of com.oracle.truffle.llvm.runtime.nodes.api.LLVMControlFlowNode 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 LLVMControlFlowNode

use of com.oracle.truffle.llvm.runtime.nodes.api.LLVMControlFlowNode in project sulong by graalvm.

the class LLVMBitcodeInstructionVisitor method visit.

@Override
public void visit(InvokeInstruction call) {
    final Type targetType = call.getType();
    int argumentCount = getArgumentCount(call.getArgumentCount(), targetType);
    final LLVMExpressionNode[] argNodes = new LLVMExpressionNode[argumentCount];
    final Type[] argTypes = new Type[argumentCount];
    int argIndex = 0;
    argNodes[argIndex] = nodeFactory.createFrameRead(runtime, PointerType.VOID, getStackSlot());
    argTypes[argIndex] = new PointerType(null);
    argIndex++;
    if (targetType instanceof StructureType) {
        argTypes[argIndex] = new PointerType(targetType);
        argNodes[argIndex] = nodeFactory.createAlloca(runtime, targetType);
        argIndex++;
    }
    for (int i = 0; argIndex < argumentCount; i++, argIndex++) {
        argNodes[argIndex] = symbols.resolve(call.getArgument(i));
        argTypes[argIndex] = call.getArgument(i).getType();
        final AttributesGroup paramAttr = call.getParameterAttributesGroup(i);
        if (isByValue(paramAttr)) {
            argNodes[argIndex] = capsuleAddressByValue(argNodes[argIndex], argTypes[argIndex], paramAttr);
        }
    }
    final SymbolImpl target = call.getCallTarget();
    int regularIndex = call.normalSuccessor().getBlockIndex();
    int unwindIndex = call.unwindSuccessor().getBlockIndex();
    List<FrameSlot> normalTo = new ArrayList<>();
    List<FrameSlot> unwindTo = new ArrayList<>();
    List<Type> normalType = new ArrayList<>();
    List<Type> unwindType = new ArrayList<>();
    List<LLVMExpressionNode> normalValue = new ArrayList<>();
    List<LLVMExpressionNode> unwindValue = new ArrayList<>();
    if (blockPhis != null) {
        for (Phi phi : blockPhis) {
            FrameSlot slot = getSlot(phi.getPhiValue().getName());
            LLVMExpressionNode value = symbols.resolve(phi.getValue());
            if (call.normalSuccessor() == phi.getBlock()) {
                normalTo.add(slot);
                normalType.add(phi.getValue().getType());
                normalValue.add(value);
            } else {
                unwindTo.add(slot);
                unwindType.add(phi.getValue().getType());
                unwindValue.add(value);
            }
        }
    }
    LLVMExpressionNode normalPhi = nodeFactory.createPhi(runtime, normalValue.toArray(new LLVMExpressionNode[normalValue.size()]), normalTo.toArray(new FrameSlot[normalTo.size()]), normalType.toArray(Type.EMPTY_ARRAY));
    LLVMExpressionNode unwindPhi = nodeFactory.createPhi(runtime, unwindValue.toArray(new LLVMExpressionNode[unwindValue.size()]), unwindTo.toArray(new FrameSlot[unwindTo.size()]), unwindType.toArray(Type.EMPTY_ARRAY));
    final LLVMSourceLocation source = sourceFunction.getSourceLocation(call);
    LLVMExpressionNode function = nodeFactory.createLLVMBuiltin(runtime, target, argNodes, argCount, null);
    if (function == null) {
        function = symbols.resolve(target);
    }
    LLVMControlFlowNode result = nodeFactory.createFunctionInvoke(runtime, getSlot(call.getName()), function, argNodes, new FunctionType(targetType, argTypes, false), regularIndex, unwindIndex, normalPhi, unwindPhi, source);
    setControlFlowNode(result);
}
Also used : LLVMControlFlowNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMControlFlowNode) FrameSlot(com.oracle.truffle.api.frame.FrameSlot) FunctionType(com.oracle.truffle.llvm.runtime.types.FunctionType) ArrayList(java.util.ArrayList) PointerType(com.oracle.truffle.llvm.runtime.types.PointerType) LLVMSourceLocation(com.oracle.truffle.llvm.runtime.debug.scope.LLVMSourceLocation) Phi(com.oracle.truffle.llvm.parser.LLVMPhiManager.Phi) SymbolImpl(com.oracle.truffle.llvm.parser.model.SymbolImpl) LLVMConversionType(com.oracle.truffle.llvm.parser.instructions.LLVMConversionType) PrimitiveType(com.oracle.truffle.llvm.runtime.types.PrimitiveType) StructureType(com.oracle.truffle.llvm.runtime.types.StructureType) ArrayType(com.oracle.truffle.llvm.runtime.types.ArrayType) AggregateType(com.oracle.truffle.llvm.runtime.types.AggregateType) LLVMArithmeticInstructionType(com.oracle.truffle.llvm.parser.instructions.LLVMArithmeticInstructionType) Type(com.oracle.truffle.llvm.runtime.types.Type) PointerType(com.oracle.truffle.llvm.runtime.types.PointerType) FunctionType(com.oracle.truffle.llvm.runtime.types.FunctionType) AttributesGroup(com.oracle.truffle.llvm.parser.model.attributes.AttributesGroup) StructureType(com.oracle.truffle.llvm.runtime.types.StructureType) LLVMExpressionNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode)

Example 3 with LLVMControlFlowNode

use of com.oracle.truffle.llvm.runtime.nodes.api.LLVMControlFlowNode in project sulong by graalvm.

the class LLVMBitcodeInstructionVisitor method visit.

@Override
public void visit(ResumeInstruction resumeInstruction) {
    LLVMControlFlowNode resume = nodeFactory.createResumeInstruction(runtime, getExceptionSlot(), sourceFunction.getSourceLocation(resumeInstruction));
    setControlFlowNode(resume);
}
Also used : LLVMControlFlowNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMControlFlowNode)

Example 4 with LLVMControlFlowNode

use of com.oracle.truffle.llvm.runtime.nodes.api.LLVMControlFlowNode in project sulong by graalvm.

the class LLVMBitcodeInstructionVisitor method visit.

@Override
public void visit(IndirectBranchInstruction branch) {
    if (branch.getSuccessorCount() > 1) {
        int[] labelTargets = new int[branch.getSuccessorCount()];
        for (int i = 0; i < labelTargets.length; i++) {
            labelTargets[i] = branch.getSuccessor(i).getBlockIndex();
        }
        LLVMExpressionNode value = symbols.resolve(branch.getAddress());
        LLVMControlFlowNode node = nodeFactory.createIndirectBranch(runtime, value, labelTargets, getPhiWriteNodes(branch), sourceFunction.getSourceLocation(branch));
        setControlFlowNode(node);
    } else {
        assert branch.getSuccessorCount() == 1;
        LLVMControlFlowNode node = nodeFactory.createUnconditionalBranch(runtime, branch.getSuccessor(0).getBlockIndex(), getPhiWriteNodes(branch)[0], sourceFunction.getSourceLocation(branch));
        setControlFlowNode(node);
    }
}
Also used : LLVMControlFlowNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMControlFlowNode) LLVMExpressionNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode)

Example 5 with LLVMControlFlowNode

use of com.oracle.truffle.llvm.runtime.nodes.api.LLVMControlFlowNode in project sulong by graalvm.

the class LLVMBitcodeInstructionVisitor method visit.

@Override
public void visit(SwitchInstruction zwitch) {
    LLVMExpressionNode cond = symbols.resolve(zwitch.getCondition());
    int[] successors = new int[zwitch.getCaseCount() + 1];
    for (int i = 0; i < successors.length - 1; i++) {
        successors[i] = zwitch.getCaseBlock(i).getBlockIndex();
    }
    successors[successors.length - 1] = zwitch.getDefaultBlock().getBlockIndex();
    Type llvmType = zwitch.getCondition().getType();
    LLVMExpressionNode[] cases = new LLVMExpressionNode[zwitch.getCaseCount()];
    for (int i = 0; i < cases.length; i++) {
        cases[i] = symbols.resolve(zwitch.getCaseValue(i));
    }
    LLVMControlFlowNode node = nodeFactory.createSwitch(runtime, cond, successors, cases, llvmType, getPhiWriteNodes(zwitch), sourceFunction.getSourceLocation(zwitch));
    setControlFlowNode(node);
}
Also used : LLVMConversionType(com.oracle.truffle.llvm.parser.instructions.LLVMConversionType) PrimitiveType(com.oracle.truffle.llvm.runtime.types.PrimitiveType) StructureType(com.oracle.truffle.llvm.runtime.types.StructureType) ArrayType(com.oracle.truffle.llvm.runtime.types.ArrayType) AggregateType(com.oracle.truffle.llvm.runtime.types.AggregateType) LLVMArithmeticInstructionType(com.oracle.truffle.llvm.parser.instructions.LLVMArithmeticInstructionType) Type(com.oracle.truffle.llvm.runtime.types.Type) PointerType(com.oracle.truffle.llvm.runtime.types.PointerType) FunctionType(com.oracle.truffle.llvm.runtime.types.FunctionType) LLVMControlFlowNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMControlFlowNode) LLVMExpressionNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode)

Aggregations

LLVMControlFlowNode (com.oracle.truffle.llvm.runtime.nodes.api.LLVMControlFlowNode)10 LLVMExpressionNode (com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode)7 PrimitiveType (com.oracle.truffle.llvm.runtime.types.PrimitiveType)5 LLVMArithmeticInstructionType (com.oracle.truffle.llvm.parser.instructions.LLVMArithmeticInstructionType)4 LLVMConversionType (com.oracle.truffle.llvm.parser.instructions.LLVMConversionType)4 AggregateType (com.oracle.truffle.llvm.runtime.types.AggregateType)4 ArrayType (com.oracle.truffle.llvm.runtime.types.ArrayType)4 FunctionType (com.oracle.truffle.llvm.runtime.types.FunctionType)4 PointerType (com.oracle.truffle.llvm.runtime.types.PointerType)4 StructureType (com.oracle.truffle.llvm.runtime.types.StructureType)4 Type (com.oracle.truffle.llvm.runtime.types.Type)4 FrameSlot (com.oracle.truffle.api.frame.FrameSlot)2 Phi (com.oracle.truffle.llvm.parser.LLVMPhiManager.Phi)2 SymbolImpl (com.oracle.truffle.llvm.parser.model.SymbolImpl)2 AttributesGroup (com.oracle.truffle.llvm.parser.model.attributes.AttributesGroup)2 LLVMSourceLocation (com.oracle.truffle.llvm.runtime.debug.scope.LLVMSourceLocation)2 ArrayList (java.util.ArrayList)2 ExplodeLoop (com.oracle.truffle.api.nodes.ExplodeLoop)1 LLVMBasicBlockNode (com.oracle.truffle.llvm.nodes.base.LLVMBasicBlockNode)1 LLVMInvokeNode (com.oracle.truffle.llvm.nodes.func.LLVMInvokeNode)1