use of org.graalvm.compiler.nodes.DeoptimizingNode.DeoptBefore in project graal by oracle.
the class PlaceholderLogicNode method rewireFrameStatesAfterFSA.
private void rewireFrameStatesAfterFSA(ValueNode replacee, UnmodifiableEconomicMap<Node, Node> duplicates) {
DeoptimizingNode replaceeDeopt = (DeoptimizingNode) replacee;
GraalError.guarantee(replaceeDeopt.canDeoptimize(), "Method expects the replacee to have deopt state");
FrameState stateBefore = null;
FrameState stateDuring = null;
FrameState stateAfter = null;
if (replaceeDeopt instanceof DeoptimizingNode.DeoptBefore) {
stateBefore = ((DeoptimizingNode.DeoptBefore) replaceeDeopt).stateBefore();
}
if (replaceeDeopt instanceof DeoptimizingNode.DeoptDuring) {
stateDuring = ((DeoptimizingNode.DeoptDuring) replaceeDeopt).stateDuring();
}
if (replaceeDeopt instanceof DeoptimizingNode.DeoptAfter) {
stateAfter = ((DeoptimizingNode.DeoptAfter) replaceeDeopt).stateAfter();
}
if (stateAfter == null && stateDuring == null && stateBefore == null) {
/*
* There should only be no state available to transfer during testing or if the
* replacee's graph itself is a substitution.
*/
StructuredGraph graph = replacee.graph();
boolean condition = graph.isStateAfterClearedForTesting() || graph.isSubstitution();
GraalError.guarantee(condition, "No state available to transfer");
return;
}
final ExceptionObjectNode exceptionObject;
if (replacee instanceof WithExceptionNode) {
WithExceptionNode withExceptionNode = (WithExceptionNode) replacee;
if (withExceptionNode.exceptionEdge() instanceof ExceptionObjectNode) {
exceptionObject = (ExceptionObjectNode) withExceptionNode.exceptionEdge();
} else {
GraalError.guarantee(withExceptionNode.exceptionEdge() instanceof UnreachableBeginNode, "Unexpected exception edge %s", withExceptionNode.exceptionEdge());
exceptionObject = null;
}
} else {
exceptionObject = null;
}
for (DeoptimizingNode deoptNode : deoptNodes) {
DeoptimizingNode deoptDup = (DeoptimizingNode) duplicates.get(deoptNode.asNode());
if (deoptDup.canDeoptimize()) {
if (deoptDup instanceof ExceptionObjectNode) {
ExceptionObjectNode newExceptionObject = (ExceptionObjectNode) deoptDup;
rewireExceptionFrameState(exceptionObject, newExceptionObject, newExceptionObject);
continue;
}
if (deoptDup instanceof DeoptimizingNode.DeoptBefore) {
GraalError.guarantee(stateBefore != null, "Invalid stateBefore being transferred.");
((DeoptimizingNode.DeoptBefore) deoptDup).setStateBefore(stateBefore);
}
if (deoptDup instanceof DeoptimizingNode.DeoptDuring) {
// compute a state "during" for a DeoptDuring inside the snippet depending
// on what kind of states we had on the node we are replacing.
// If the original node had a state "during" already, we just use that,
// otherwise we need to find a strategy to compute a state during based on
// some other state (before or after).
DeoptimizingNode.DeoptDuring deoptDupDuring = (DeoptimizingNode.DeoptDuring) deoptDup;
if (stateDuring != null) {
deoptDupDuring.setStateDuring(stateDuring);
} else if (stateAfter != null) {
deoptDupDuring.computeStateDuring(stateAfter);
} else if (stateBefore != null) {
boolean guarantee = ((DeoptBefore) replaceeDeopt).canUseAsStateDuring() || !deoptDupDuring.hasSideEffect();
GraalError.guarantee(guarantee, "Can't use stateBefore as stateDuring for state split %s", deoptDupDuring);
deoptDupDuring.setStateDuring(stateBefore);
} else {
throw GraalError.shouldNotReachHere("No stateDuring assigned.");
}
}
if (deoptDup instanceof DeoptimizingNode.DeoptAfter) {
DeoptimizingNode.DeoptAfter deoptDupAfter = (DeoptimizingNode.DeoptAfter) deoptDup;
if (stateAfter != null) {
deoptDupAfter.setStateAfter(stateAfter);
} else {
boolean guarantee = stateBefore != null && !deoptDupAfter.hasSideEffect();
GraalError.guarantee(guarantee, "Can't use stateBefore as stateAfter for state split %s", deoptDupAfter);
deoptDupAfter.setStateAfter(stateBefore);
}
}
}
}
}
Aggregations