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