use of com.oracle.truffle.llvm.runtime.nodes.base.LLVMBasicBlockNode in project graal by oracle.
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 LLVMInstrumentableNode) {
location = ((LLVMInstrumentableNode) 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.runtime.nodes.base.LLVMBasicBlockNode in project graal by oracle.
the class LLVMRuntimeDebugInformation method initializePredecessors.
@SuppressWarnings({ "unchecked", "rawtypes" })
private void initializePredecessors() {
if (predecessors == null) {
ArrayList<Integer>[] result = new ArrayList[infos.length];
for (int i = 0; i < infos.length; i++) {
result[i] = new ArrayList<>(2);
}
for (LLVMBasicBlockNode b : blocks) {
for (int successor : b.getTerminatingInstruction().getSuccessors()) {
if (successor >= 0) {
result[successor].add(b.getBlockId());
}
}
}
predecessors = result;
}
}
use of com.oracle.truffle.llvm.runtime.nodes.base.LLVMBasicBlockNode 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.base.LLVMBasicBlockNode in project graal by oracle.
the class LazyToTruffleConverterImpl method generateCallTarget.
private RootCallTarget generateCallTarget() {
LLVMContext context = LLVMLanguage.getContext();
NodeFactory nodeFactory = runtime.getNodeFactory();
OptionValues options = context.getEnv().getOptions();
boolean printAST = false;
if (LLVMContext.printAstEnabled()) {
String printASTOption = options.get(SulongEngineOption.PRINT_AST_FILTER);
if (!printASTOption.isEmpty()) {
String[] regexes = printASTOption.split(",");
for (String regex : regexes) {
if (method.getName().matches(regex)) {
printAST = true;
LLVMContext.printAstLog("========== " + method.getName());
break;
}
}
}
}
doParse();
// prepare the phis
final Map<InstructionBlock, List<Phi>> phis = LLVMPhiManager.getPhis(method);
LLVMLivenessAnalysisResult liveness = LLVMLivenessAnalysis.computeLiveness(phis, method);
// setup the frameDescriptor
FrameDescriptor.Builder builder = FrameDescriptor.newBuilder();
nodeFactory.addStackSlots(builder);
UniquesRegion uniquesRegion = new UniquesRegion();
GetStackSpaceFactory getStackSpaceFactory = GetStackSpaceFactory.createGetUniqueStackSpaceFactory(uniquesRegion);
LLVMSymbolReadResolver symbols = new LLVMSymbolReadResolver(runtime, builder, getStackSpaceFactory, dataLayout, options.get(SulongEngineOption.LL_DEBUG));
int exceptionSlot = builder.addSlot(FrameSlotKind.Object, null, null);
for (FunctionParameter parameter : method.getParameters()) {
symbols.findOrAddFrameSlot(parameter);
}
HashSet<SSAValue> neededForDebug = getDebugValues();
// create blocks and translate instructions
boolean initDebugValues = true;
LLVMRuntimeDebugInformation info = new LLVMRuntimeDebugInformation(method.getBlocks().size());
LLVMBasicBlockNode[] blockNodes = new LLVMBasicBlockNode[method.getBlocks().size()];
for (InstructionBlock block : method.getBlocks()) {
List<Phi> blockPhis = phis.get(block);
ArrayList<LLVMLivenessAnalysis.NullerInformation> blockNullerInfos = liveness.getNullableWithinBlock()[block.getBlockIndex()];
LLVMBitcodeInstructionVisitor visitor = new LLVMBitcodeInstructionVisitor(exceptionSlot, uniquesRegion, blockPhis, method.getParameters().size(), symbols, context, blockNullerInfos, neededForDebug, dataLayout, nodeFactory);
if (initDebugValues) {
for (SourceVariable variable : method.getSourceFunction().getVariables()) {
if (variable.hasFragments()) {
visitor.initializeAggregateLocalVariable(variable);
}
}
initDebugValues = false;
}
for (int i = 0; i < block.getInstructionCount(); i++) {
visitor.setInstructionIndex(i);
block.getInstruction(i).accept(visitor);
}
LLVMStatementNode[] nodes = visitor.finish();
info.setBlockDebugInfo(block.getBlockIndex(), visitor.getDebugInfo());
blockNodes[block.getBlockIndex()] = LLVMBasicBlockNode.createBasicBlockNode(options, nodes, visitor.getControlFlowNode(), block.getBlockIndex(), block.getName());
}
for (int j = 0; j < blockNodes.length; j++) {
int[] nullableBeforeBlock = getNullableFrameSlots(liveness.getFrameSlots(), liveness.getNullableBeforeBlock()[j]);
int[] nullableAfterBlock = getNullableFrameSlots(liveness.getFrameSlots(), liveness.getNullableAfterBlock()[j]);
blockNodes[j].setNullableFrameSlots(nullableBeforeBlock, nullableAfterBlock);
}
info.setBlocks(blockNodes);
int loopSuccessorSlot = -1;
if (options.get(SulongEngineOption.OSR_MODE) == SulongEngineOption.OSRMode.CFG && !options.get(SulongEngineOption.AOTCacheStore)) {
LLVMControlFlowGraph cfg = new LLVMControlFlowGraph(method.getBlocks().toArray(FunctionDefinition.EMPTY));
cfg.build();
if (cfg.isReducible() && cfg.getCFGLoops().size() > 0) {
loopSuccessorSlot = builder.addSlot(FrameSlotKind.Int, null, null);
resolveLoops(blockNodes, cfg, loopSuccessorSlot, exceptionSlot, info, options);
}
}
LLVMSourceLocation location = method.getLexicalScope();
rootFunction.setSourceLocation(LLVMSourceLocation.orDefault(location));
LLVMStatementNode[] copyArgumentsToFrameArray = copyArgumentsToFrame(symbols).toArray(LLVMStatementNode.NO_STATEMENTS);
FrameDescriptor frame = builder.build();
RootNode rootNode = nodeFactory.createFunction(exceptionSlot, blockNodes, uniquesRegion, copyArgumentsToFrameArray, frame, loopSuccessorSlot, info, method.getName(), method.getSourceName(), method.getParameters().size(), source, location, rootFunction);
method.onAfterParse();
if (printAST) {
printCompactTree(rootNode);
LLVMContext.printAstLog("");
}
return rootNode.getCallTarget();
}
use of com.oracle.truffle.llvm.runtime.nodes.base.LLVMBasicBlockNode in project graal by oracle.
the class LazyToTruffleConverterImpl method resolveLoops.
private void resolveLoops(LLVMBasicBlockNode[] nodes, LLVMControlFlowGraph cfg, int loopSuccessorSlot, int exceptionSlot, LLVMRuntimeDebugInformation info, OptionValues options) {
// The original array is needed to access the frame nuller information for outgoing control
// flow egdes
LLVMBasicBlockNode[] originalBodyNodes = nodes.clone();
info.setBlocks(originalBodyNodes);
for (CFGLoop loop : cfg.getCFGLoops()) {
int headerId = loop.getHeader().id;
int[] indexMapping = new int[nodes.length];
Arrays.fill(indexMapping, -1);
List<LLVMStatementNode> bodyNodes = new ArrayList<>();
// add header to body nodes
LLVMBasicBlockNode header = nodes[headerId];
bodyNodes.add(header);
indexMapping[headerId] = 0;
// add body nodes
int i = 1;
for (CFGBlock block : loop.getBody()) {
bodyNodes.add(nodes[block.id]);
indexMapping[block.id] = i++;
}
int[] loopSuccessors = loop.getSuccessorIDs();
RepeatingNode loopBody = runtime.getNodeFactory().createLoopDispatchNode(exceptionSlot, Collections.unmodifiableList(bodyNodes), originalBodyNodes, headerId, indexMapping, loopSuccessors, loopSuccessorSlot);
LLVMControlFlowNode loopNode = runtime.getNodeFactory().createLoop(loopBody, loopSuccessors);
// replace header block with loop node
nodes[headerId] = LLVMBasicBlockNode.createBasicBlockNode(options, new LLVMStatementNode[0], loopNode, headerId, "loopAt" + headerId);
nodes[headerId].setNullableFrameSlots(header.nullableBefore, header.nullableAfter);
// remove inner loops to reduce number of nodes
for (CFGLoop innerLoop : loop.getInnerLoops()) {
nodes[innerLoop.getHeader().id] = null;
}
}
}
Aggregations