use of com.oracle.truffle.llvm.runtime.nodes.func.LLVMInvokeNode 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;
}
use of com.oracle.truffle.llvm.runtime.nodes.func.LLVMInvokeNode in project graal by oracle.
the class LLVMLoopDispatchNode method executeRepeatingWithValue.
/**
* The code in this function is mirrored from {@link LLVMDispatchBasicBlockNode}, any changes
* need to be done in both places. The block id of the successor block (where to continue after
* the loop) is stored in a frame slot.
*/
@ExplodeLoop(kind = LoopExplosionKind.MERGE_EXPLODE)
@Override
public Object executeRepeatingWithValue(VirtualFrame frame) {
CompilerAsserts.partialEvaluationConstant(bodyNodes.length);
int basicBlockIndex = headerId;
// do-while loop fails at PE
outer: while (true) {
CompilerAsserts.partialEvaluationConstant(basicBlockIndex);
LLVMBasicBlockNode bb = bodyNodes[indexMapping[basicBlockIndex]];
// lazily insert the basic block into the AST
bb.initialize();
// the newly inserted block may have been instrumented
bb = bodyNodes[indexMapping[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);
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, bb.nullableAfter);
LLVMDispatchBasicBlockNode.executePhis(frame, conditionalBranchNode, LLVMConditionalBranchNode.TRUE_SUCCESSOR);
basicBlockIndex = conditionalBranchNode.getTrueSuccessor();
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, originalBodyNodes[basicBlockIndex].nullableBefore);
if (basicBlockIndex == headerId) {
return RepeatingNode.CONTINUE_LOOP_STATUS;
}
if (!isInLoop(basicBlockIndex)) {
frame.setInt(successorSlot, basicBlockIndex);
return RepeatingNode.BREAK_LOOP_STATUS;
}
continue outer;
} else {
bb.enterSuccessor(LLVMConditionalBranchNode.FALSE_SUCCESSOR);
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, bb.nullableAfter);
LLVMDispatchBasicBlockNode.executePhis(frame, conditionalBranchNode, LLVMConditionalBranchNode.FALSE_SUCCESSOR);
basicBlockIndex = conditionalBranchNode.getFalseSuccessor();
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, originalBodyNodes[basicBlockIndex].nullableBefore);
if (basicBlockIndex == headerId) {
return RepeatingNode.CONTINUE_LOOP_STATUS;
}
if (!isInLoop(basicBlockIndex)) {
frame.setInt(successorSlot, basicBlockIndex);
return RepeatingNode.BREAK_LOOP_STATUS;
}
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++) {
if (CompilerDirectives.injectBranchProbability(bb.getBranchProbability(i), switchNode.checkCase(frame, i, condition))) {
bb.enterSuccessor(i);
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, bb.nullableAfter);
LLVMDispatchBasicBlockNode.executePhis(frame, switchNode, i);
basicBlockIndex = successors[i];
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, originalBodyNodes[basicBlockIndex].nullableBefore);
if (basicBlockIndex == headerId) {
return RepeatingNode.CONTINUE_LOOP_STATUS;
}
if (!isInLoop(basicBlockIndex)) {
frame.setInt(successorSlot, basicBlockIndex);
return RepeatingNode.BREAK_LOOP_STATUS;
}
continue outer;
}
}
int i = successors.length - 1;
bb.enterSuccessor(i);
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, bb.nullableAfter);
LLVMDispatchBasicBlockNode.executePhis(frame, switchNode, i);
basicBlockIndex = successors[i];
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, originalBodyNodes[basicBlockIndex].nullableBefore);
if (basicBlockIndex == headerId) {
return RepeatingNode.CONTINUE_LOOP_STATUS;
}
if (!isInLoop(basicBlockIndex)) {
frame.setInt(successorSlot, basicBlockIndex);
return RepeatingNode.BREAK_LOOP_STATUS;
}
continue outer;
} else if (controlFlowNode instanceof LLVMLoopNode) {
LLVMLoopNode loop = (LLVMLoopNode) controlFlowNode;
loop.executeLoop(frame);
int successorBasicBlockIndex = frame.getInt(successorSlot);
// null frame
frame.setInt(successorSlot, 0);
int[] successors = loop.getSuccessors();
for (int i = 0; i < successors.length - 1; i++) {
if (successorBasicBlockIndex == successors[i]) {
basicBlockIndex = successors[i];
if (basicBlockIndex == headerId) {
return RepeatingNode.CONTINUE_LOOP_STATUS;
}
if (!isInLoop(basicBlockIndex)) {
frame.setInt(successorSlot, basicBlockIndex);
return RepeatingNode.BREAK_LOOP_STATUS;
}
continue outer;
}
}
int i = successors.length - 1;
assert successors[i] == successorBasicBlockIndex : "Could not find loop successor!";
basicBlockIndex = successors[i];
if (basicBlockIndex == headerId) {
return RepeatingNode.CONTINUE_LOOP_STATUS;
}
if (!isInLoop(basicBlockIndex)) {
frame.setInt(successorSlot, basicBlockIndex);
return RepeatingNode.BREAK_LOOP_STATUS;
}
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)) {
bb.enterSuccessor(i);
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, bb.nullableAfter);
LLVMDispatchBasicBlockNode.executePhis(frame, indirectBranchNode, i);
basicBlockIndex = successors[i];
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, originalBodyNodes[basicBlockIndex].nullableBefore);
if (basicBlockIndex == headerId) {
return RepeatingNode.CONTINUE_LOOP_STATUS;
}
if (!isInLoop(basicBlockIndex)) {
frame.setInt(successorSlot, basicBlockIndex);
return RepeatingNode.BREAK_LOOP_STATUS;
}
continue outer;
}
}
int i = successors.length - 1;
assert successorBasicBlockIndex == successors[i];
bb.enterSuccessor(i);
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, bb.nullableAfter);
LLVMDispatchBasicBlockNode.executePhis(frame, indirectBranchNode, i);
basicBlockIndex = successors[i];
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, originalBodyNodes[basicBlockIndex].nullableBefore);
if (basicBlockIndex == headerId) {
return RepeatingNode.CONTINUE_LOOP_STATUS;
}
if (!isInLoop(basicBlockIndex)) {
frame.setInt(successorSlot, basicBlockIndex);
return RepeatingNode.BREAK_LOOP_STATUS;
}
continue outer;
} else if (controlFlowNode instanceof LLVMBrUnconditionalNode) {
LLVMBrUnconditionalNode unconditionalNode = (LLVMBrUnconditionalNode) controlFlowNode;
// required for instrumentation
unconditionalNode.execute(frame);
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, bb.nullableAfter);
LLVMDispatchBasicBlockNode.executePhis(frame, unconditionalNode, 0);
basicBlockIndex = unconditionalNode.getSuccessor();
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, originalBodyNodes[basicBlockIndex].nullableBefore);
if (basicBlockIndex == headerId) {
return RepeatingNode.CONTINUE_LOOP_STATUS;
}
if (!isInLoop(basicBlockIndex)) {
frame.setInt(successorSlot, basicBlockIndex);
return RepeatingNode.BREAK_LOOP_STATUS;
}
continue outer;
} else if (controlFlowNode instanceof LLVMInvokeNode) {
LLVMInvokeNode invokeNode = (LLVMInvokeNode) controlFlowNode;
try {
invokeNode.execute(frame);
bb.enterSuccessor(LLVMInvokeNode.NORMAL_SUCCESSOR);
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, bb.nullableAfter);
LLVMDispatchBasicBlockNode.executePhis(frame, invokeNode, LLVMInvokeNode.NORMAL_SUCCESSOR);
basicBlockIndex = invokeNode.getNormalSuccessor();
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, originalBodyNodes[basicBlockIndex].nullableBefore);
if (basicBlockIndex == headerId) {
return RepeatingNode.CONTINUE_LOOP_STATUS;
}
if (!isInLoop(basicBlockIndex)) {
frame.setInt(successorSlot, basicBlockIndex);
return RepeatingNode.BREAK_LOOP_STATUS;
}
continue outer;
} catch (LLVMUserException e) {
bb.enterSuccessor(LLVMInvokeNode.UNWIND_SUCCESSOR);
frame.setObject(exceptionValueSlot, e);
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, bb.nullableAfter);
LLVMDispatchBasicBlockNode.executePhis(frame, invokeNode, LLVMInvokeNode.UNWIND_SUCCESSOR);
basicBlockIndex = invokeNode.getUnwindSuccessor();
LLVMDispatchBasicBlockNode.nullDeadSlots(frame, originalBodyNodes[basicBlockIndex].nullableBefore);
if (basicBlockIndex == headerId) {
return RepeatingNode.CONTINUE_LOOP_STATUS;
}
if (!isInLoop(basicBlockIndex)) {
frame.setInt(successorSlot, basicBlockIndex);
return RepeatingNode.BREAK_LOOP_STATUS;
}
continue outer;
}
} else {
// some control flow nodes should be never part of a loop
CompilerDirectives.transferToInterpreterAndInvalidate();
throw new UnsupportedOperationException("unexpected controlFlowNode type: " + controlFlowNode);
}
}
}
Aggregations