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;
}
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);
}
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);
}
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);
}
}
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);
}
Aggregations