use of org.graalvm.compiler.nodes.FrameState in project graal by oracle.
the class PEGraphDecoder method ensureExceptionStateDecoded.
protected void ensureExceptionStateDecoded(PEMethodScope methodScope) {
if (methodScope.exceptionState == null && methodScope.caller != null && methodScope.invokeData.invoke instanceof InvokeWithExceptionNode) {
ensureStateAfterDecoded(methodScope);
assert methodScope.exceptionPlaceholderNode == null;
methodScope.exceptionPlaceholderNode = graph.add(new ExceptionPlaceholderNode());
registerNode(methodScope.callerLoopScope, methodScope.invokeData.exceptionOrderId, methodScope.exceptionPlaceholderNode, false, false);
FrameState exceptionState = (FrameState) ensureNodeCreated(methodScope.caller, methodScope.callerLoopScope, methodScope.invokeData.exceptionStateOrderId);
if (exceptionState.outerFrameState() == null && methodScope.caller != null) {
ensureOuterStateDecoded(methodScope.caller);
exceptionState.setOuterFrameState(methodScope.caller.outerState);
}
methodScope.exceptionState = exceptionState;
}
}
use of org.graalvm.compiler.nodes.FrameState in project graal by oracle.
the class PEGraphDecoder method deleteInvoke.
private static void deleteInvoke(Invoke invoke) {
/*
* Clean up unused nodes. We cannot just call killCFG on the invoke node because that can
* kill too much: nodes that are decoded later can use values that appear unused by now.
*/
FrameState frameState = invoke.stateAfter();
invoke.asNode().safeDelete();
assert invoke.callTarget() == null : "must not have been added to the graph yet";
if (frameState != null && frameState.hasNoUsages()) {
frameState.safeDelete();
}
}
use of org.graalvm.compiler.nodes.FrameState in project graal by oracle.
the class PEGraphDecoder method finishInlining.
@Override
protected void finishInlining(MethodScope is) {
PEMethodScope inlineScope = (PEMethodScope) is;
ResolvedJavaMethod inlineMethod = inlineScope.method;
PEMethodScope methodScope = inlineScope.caller;
LoopScope loopScope = inlineScope.callerLoopScope;
InvokeData invokeData = inlineScope.invokeData;
Invoke invoke = invokeData.invoke;
FixedNode invokeNode = invoke.asNode();
ValueNode exceptionValue = null;
int returnNodeCount = 0;
int unwindNodeCount = 0;
List<ControlSinkNode> returnAndUnwindNodes = inlineScope.returnAndUnwindNodes;
for (int i = 0; i < returnAndUnwindNodes.size(); i++) {
FixedNode fixedNode = returnAndUnwindNodes.get(i);
if (fixedNode instanceof ReturnNode) {
returnNodeCount++;
} else if (fixedNode.isAlive()) {
assert fixedNode instanceof UnwindNode;
unwindNodeCount++;
}
}
if (unwindNodeCount > 0) {
FixedNode unwindReplacement;
if (invoke instanceof InvokeWithExceptionNode) {
/* Decoding continues for the exception handler. */
unwindReplacement = makeStubNode(methodScope, loopScope, invokeData.exceptionNextOrderId);
} else {
/* No exception handler available, so the only thing we can do is deoptimize. */
unwindReplacement = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler));
}
if (unwindNodeCount == 1) {
/* Only one UnwindNode, we can use the exception directly. */
UnwindNode unwindNode = getSingleMatchingNode(returnAndUnwindNodes, returnNodeCount > 0, UnwindNode.class);
exceptionValue = unwindNode.exception();
unwindNode.replaceAndDelete(unwindReplacement);
} else {
/*
* More than one UnwindNode. This can happen with the loop explosion strategy
* FULL_EXPLODE_UNTIL_RETURN, where we keep exploding after the loop and therefore
* also explode exception paths. Merge the exception in a similar way as multiple
* return values.
*/
MergeNode unwindMergeNode = graph.add(new MergeNode());
exceptionValue = InliningUtil.mergeValueProducers(unwindMergeNode, getMatchingNodes(returnAndUnwindNodes, returnNodeCount > 0, UnwindNode.class, unwindNodeCount), null, unwindNode -> unwindNode.exception());
unwindMergeNode.setNext(unwindReplacement);
ensureExceptionStateDecoded(inlineScope);
unwindMergeNode.setStateAfter(inlineScope.exceptionState.duplicateModified(JavaKind.Object, JavaKind.Object, exceptionValue));
}
}
assert invoke.next() == null;
assert !(invoke instanceof InvokeWithExceptionNode) || ((InvokeWithExceptionNode) invoke).exceptionEdge() == null;
ValueNode returnValue;
if (returnNodeCount == 0) {
returnValue = null;
} else if (returnNodeCount == 1) {
ReturnNode returnNode = getSingleMatchingNode(returnAndUnwindNodes, unwindNodeCount > 0, ReturnNode.class);
returnValue = returnNode.result();
FixedNode n = nodeAfterInvoke(methodScope, loopScope, invokeData, AbstractBeginNode.prevBegin(returnNode));
returnNode.replaceAndDelete(n);
} else {
AbstractMergeNode merge = graph.add(new MergeNode());
merge.setStateAfter((FrameState) ensureNodeCreated(methodScope, loopScope, invokeData.stateAfterOrderId));
returnValue = InliningUtil.mergeReturns(merge, getMatchingNodes(returnAndUnwindNodes, unwindNodeCount > 0, ReturnNode.class, returnNodeCount));
FixedNode n = nodeAfterInvoke(methodScope, loopScope, invokeData, merge);
merge.setNext(n);
}
invokeNode.replaceAtUsages(returnValue);
/*
* Usage the handles that we have on the return value and the exception to update the
* orderId->Node table.
*/
registerNode(loopScope, invokeData.invokeOrderId, returnValue, true, true);
if (invoke instanceof InvokeWithExceptionNode) {
registerNode(loopScope, invokeData.exceptionOrderId, exceptionValue, true, true);
}
if (inlineScope.exceptionPlaceholderNode != null) {
inlineScope.exceptionPlaceholderNode.replaceAtUsagesAndDelete(exceptionValue);
}
deleteInvoke(invoke);
for (InlineInvokePlugin plugin : inlineInvokePlugins) {
plugin.notifyAfterInline(inlineMethod);
}
}
use of org.graalvm.compiler.nodes.FrameState in project graal by oracle.
the class PEGraphDecoder method cleanupGraph.
@Override
protected void cleanupGraph(MethodScope methodScope) {
super.cleanupGraph(methodScope);
for (FrameState frameState : graph.getNodes(FrameState.TYPE)) {
if (frameState.bci == BytecodeFrame.UNWIND_BCI) {
/*
* handleMissingAfterExceptionFrameState is called during graph decoding from
* InliningUtil.processFrameState - but during graph decoding it does not do
* anything because the usages of the frameState are not available yet. So we need
* to call it again.
*/
PEMethodScope peMethodScope = (PEMethodScope) methodScope;
Invoke invoke = peMethodScope.invokeData != null ? peMethodScope.invokeData.invoke : null;
InliningUtil.handleMissingAfterExceptionFrameState(frameState, invoke, null, true);
/*
* The frameState must be gone now, because it is not a valid deoptimization point.
*/
assert frameState.isDeleted();
}
}
}
use of org.graalvm.compiler.nodes.FrameState in project graal by oracle.
the class PEGraphDecoder method handleFloatingNodeAfterAdd.
@Override
protected Node handleFloatingNodeAfterAdd(MethodScope s, LoopScope loopScope, Node node) {
PEMethodScope methodScope = (PEMethodScope) s;
if (methodScope.isInlinedMethod()) {
if (node instanceof FrameState) {
FrameState frameState = (FrameState) node;
ensureOuterStateDecoded(methodScope);
if (frameState.bci < 0) {
ensureExceptionStateDecoded(methodScope);
}
List<ValueNode> invokeArgsList = null;
if (frameState.bci == BytecodeFrame.BEFORE_BCI) {
/*
* We know that the argument list is only used in this case, so avoid the List
* allocation for "normal" bcis.
*/
invokeArgsList = Arrays.asList(methodScope.arguments);
}
return InliningUtil.processFrameState(frameState, methodScope.invokeData.invoke, null, methodScope.method, methodScope.exceptionState, methodScope.outerState, true, methodScope.method, invokeArgsList);
} else if (node instanceof MonitorIdNode) {
ensureOuterStateDecoded(methodScope);
InliningUtil.processMonitorId(methodScope.outerState, (MonitorIdNode) node);
return node;
}
}
return node;
}
Aggregations