use of org.graalvm.compiler.nodes.AbstractMergeNode in project graal by oracle.
the class BytecodeParser method afterInvocationPluginExecution.
/**
* Performs any action required after execution of an invocation plugin. This includes
* {@linkplain InvocationPluginAssertions#check checking} invocation plugin invariants as well
* as weaving the {@code else} branch of the code woven by {@link #guardIntrinsic} if
* {@code guard != null}.
*/
protected void afterInvocationPluginExecution(boolean pluginHandledInvoke, InvocationPluginAssertions assertions, IntrinsicGuard intrinsicGuard, InvokeKind invokeKind, ValueNode[] args, ResolvedJavaMethod targetMethod, JavaKind resultType, JavaType returnType) {
assert assertions.check(pluginHandledInvoke);
if (intrinsicGuard != null) {
if (pluginHandledInvoke) {
if (intrinsicGuard.nonIntrinsicBranch != null) {
// Intrinsic emitted: emit a virtual call to the target method and
// merge it with the intrinsic branch
EndNode intrinsicEnd = append(new EndNode());
FrameStateBuilder intrinsicState = null;
FrameStateBuilder nonIntrinisicState = null;
if (resultType != JavaKind.Void) {
intrinsicState = frameState.copy();
frameState.pop(resultType);
nonIntrinisicState = frameState;
}
lastInstr = intrinsicGuard.nonIntrinsicBranch;
createNonInlinedInvoke(getActionForInvokeExceptionEdge(null), bci(), args, targetMethod, invokeKind, resultType, returnType, intrinsicGuard.profile);
EndNode nonIntrinsicEnd = append(new EndNode());
AbstractMergeNode mergeNode = graph.add(new MergeNode());
mergeNode.addForwardEnd(intrinsicEnd);
if (intrinsicState != null) {
intrinsicState.merge(mergeNode, nonIntrinisicState);
frameState = intrinsicState;
}
mergeNode.addForwardEnd(nonIntrinsicEnd);
mergeNode.setStateAfter(frameState.create(stream.nextBCI(), mergeNode));
lastInstr = mergeNode;
}
} else {
// Intrinsic was not applied: remove intrinsic guard
// and restore the original receiver node in the arguments array
intrinsicGuard.lastInstr.setNext(null);
GraphUtil.removeNewNodes(graph, intrinsicGuard.mark);
lastInstr = intrinsicGuard.lastInstr;
args[0] = intrinsicGuard.receiver;
}
}
}
use of org.graalvm.compiler.nodes.AbstractMergeNode in project graal by oracle.
the class BytecodeParser method iterateBytecodesForBlock.
@SuppressWarnings("try")
protected void iterateBytecodesForBlock(BciBlock block) {
if (block.isLoopHeader) {
// Create the loop header block, which later will merge the backward branches of
// the loop.
controlFlowSplit = true;
LoopBeginNode loopBegin = appendLoopBegin(this.lastInstr, block.startBci);
lastInstr = loopBegin;
// Create phi functions for all local variables and operand stack slots.
frameState.insertLoopPhis(liveness, block.loopId, loopBegin, forceLoopPhis(), stampFromValueForForcedPhis());
loopBegin.setStateAfter(createFrameState(block.startBci, loopBegin));
/*
* We have seen all forward branches. All subsequent backward branches will merge to the
* loop header. This ensures that the loop header has exactly one non-loop predecessor.
*/
setFirstInstruction(block, loopBegin);
/*
* We need to preserve the frame state builder of the loop header so that we can merge
* values for phi functions, so make a copy of it.
*/
setEntryState(block, frameState.copy());
debug.log(" created loop header %s", loopBegin);
} else if (lastInstr instanceof MergeNode) {
/*
* All inputs of non-loop phi nodes are known by now. We can infer the stamp for the
* phi, so that parsing continues with more precise type information.
*/
frameState.inferPhiStamps((AbstractMergeNode) lastInstr);
}
assert lastInstr.next() == null : "instructions already appended at block " + block;
debug.log(" frameState: %s", frameState);
lastInstr = finishInstruction(lastInstr, frameState);
int endBCI = stream.endBCI();
stream.setBCI(block.startBci);
int bci = block.startBci;
BytecodesParsed.add(debug, block.endBci - bci);
/* Reset line number for new block */
if (graphBuilderConfig.insertFullInfopoints()) {
previousLineNumber = -1;
}
while (bci < endBCI) {
try (DebugCloseable context = openNodeContext()) {
if (graphBuilderConfig.insertFullInfopoints() && !parsingIntrinsic()) {
currentLineNumber = lnt != null ? lnt.getLineNumber(bci) : -1;
if (currentLineNumber != previousLineNumber) {
genInfoPointNode(InfopointReason.BYTECODE_POSITION, null);
previousLineNumber = currentLineNumber;
}
}
// read the opcode
int opcode = stream.currentBC();
assert traceState();
assert traceInstruction(bci, opcode, bci == block.startBci);
if (parent == null && bci == entryBCI) {
if (block.getJsrScope() != JsrScope.EMPTY_SCOPE) {
throw new JsrNotSupportedBailout("OSR into a JSR scope is not supported");
}
EntryMarkerNode x = append(new EntryMarkerNode());
frameState.insertProxies(value -> graph.unique(new EntryProxyNode(value, x)));
x.setStateAfter(createFrameState(bci, x));
}
processBytecode(bci, opcode);
} catch (BailoutException e) {
// Don't wrap bailouts as parser errors
throw e;
} catch (Throwable e) {
throw throwParserError(e);
}
if (lastInstr == null || lastInstr.next() != null) {
break;
}
stream.next();
bci = stream.currentBCI();
assert block == currentBlock;
assert checkLastInstruction();
lastInstr = finishInstruction(lastInstr, frameState);
if (bci < endBCI) {
if (bci > block.endBci) {
assert !block.getSuccessor(0).isExceptionEntry;
assert block.numNormalSuccessors() == 1;
// we fell through to the next block, add a goto and break
appendGoto(block.getSuccessor(0));
break;
}
}
}
}
use of org.graalvm.compiler.nodes.AbstractMergeNode in project graal by oracle.
the class BytecodeParser method setMergeStateAfter.
private void setMergeStateAfter(BciBlock block, FixedWithNextNode firstInstruction) {
AbstractMergeNode abstractMergeNode = (AbstractMergeNode) firstInstruction;
if (abstractMergeNode.stateAfter() == null) {
int bci = block.startBci;
if (block instanceof ExceptionDispatchBlock) {
bci = ((ExceptionDispatchBlock) block).deoptBci;
}
abstractMergeNode.setStateAfter(createFrameState(bci, abstractMergeNode));
}
}
use of org.graalvm.compiler.nodes.AbstractMergeNode in project graal by oracle.
the class BytecodeParser method processBlock.
@SuppressWarnings("try")
protected void processBlock(BciBlock block) {
// Ignore blocks that have no predecessors by the time their bytecodes are parsed
FixedWithNextNode firstInstruction = getFirstInstruction(block);
if (firstInstruction == null) {
debug.log("Ignoring block %s", block);
return;
}
try (Indent indent = debug.logAndIndent("Parsing block %s firstInstruction: %s loopHeader: %b", block, firstInstruction, block.isLoopHeader)) {
lastInstr = firstInstruction;
frameState = getEntryState(block);
setCurrentFrameState(frameState);
currentBlock = block;
if (block != blockMap.getUnwindBlock() && !(block instanceof ExceptionDispatchBlock)) {
frameState.setRethrowException(false);
}
if (firstInstruction instanceof AbstractMergeNode) {
setMergeStateAfter(block, firstInstruction);
}
if (block == blockMap.getUnwindBlock()) {
handleUnwindBlock((ExceptionDispatchBlock) block);
} else if (block instanceof ExceptionDispatchBlock) {
createExceptionDispatch((ExceptionDispatchBlock) block);
} else {
iterateBytecodesForBlock(block);
}
}
}
use of org.graalvm.compiler.nodes.AbstractMergeNode in project graal by oracle.
the class NodeLIRBuilder method isPhiInputFromBackedge.
private static boolean isPhiInputFromBackedge(PhiNode phi, int index) {
AbstractMergeNode merge = phi.merge();
AbstractEndNode end = merge.phiPredecessorAt(index);
return end instanceof LoopEndNode && ((LoopEndNode) end).loopBegin().equals(merge);
}
Aggregations