use of org.graalvm.compiler.nodes.WithExceptionNode in project graal by oracle.
the class BytecodeParser method replacePluginWithException.
@Override
public void replacePluginWithException(GeneratedInvocationPlugin plugin, ResolvedJavaMethod targetMethod, ValueNode[] args, PluginReplacementWithExceptionNode.ReplacementWithExceptionFunction replacementFunction) {
assert replacementFunction != null;
JavaType returnType = maybeEagerlyResolve(targetMethod.getSignature().getReturnType(method.getDeclaringClass()), targetMethod.getDeclaringClass());
StampPair returnStamp = getReplacements().getGraphBuilderPlugins().getOverridingStamp(this, returnType, false);
if (returnStamp == null) {
returnStamp = StampFactory.forDeclaredType(getAssumptions(), returnType, false);
}
WithExceptionNode node = new PluginReplacementWithExceptionNode(returnStamp.getTrustedStamp(), args, replacementFunction, plugin.getClass().getSimpleName());
if (returnType.getJavaKind() == JavaKind.Void) {
add(node);
} else {
addPush(returnType.getJavaKind(), node);
}
}
use of org.graalvm.compiler.nodes.WithExceptionNode in project graal by oracle.
the class BytecodeParser method updateLastInstruction.
private <T extends ValueNode> void updateLastInstruction(T v) {
if (v instanceof FixedNode) {
FixedNode fixedNode = (FixedNode) v;
if (lastInstr != null) {
lastInstr.setNext(fixedNode);
}
if (fixedNode instanceof FixedWithNextNode) {
FixedWithNextNode fixedWithNextNode = (FixedWithNextNode) fixedNode;
assert fixedWithNextNode.next() == null : "cannot append instruction to instruction which isn't end";
lastInstr = fixedWithNextNode;
} else if (fixedNode instanceof WithExceptionNode) {
lastInstr = updateWithExceptionNode((WithExceptionNode) fixedNode);
} else {
lastInstr = null;
}
}
}
use of org.graalvm.compiler.nodes.WithExceptionNode in project graal by oracle.
the class PlaceholderLogicNode method verifyWithExceptionNode.
/**
* Verifies that a {@link WithExceptionNode} has only memory usages via the
* {@link WithExceptionNode#next()} edge. On the {@link WithExceptionNode#exceptionEdge()} there
* must be a {@link MemoryKill} (or an {@link UnreachableBeginNode}), otherwise we would not
* know from which edge a memory usage is coming from.
*/
private static void verifyWithExceptionNode(ValueNode node) {
if (node instanceof WithExceptionNode && node instanceof MemoryKill) {
WithExceptionNode withExceptionNode = (WithExceptionNode) node;
AbstractBeginNode exceptionEdge = withExceptionNode.exceptionEdge();
if (exceptionEdge instanceof UnreachableBeginNode) {
// exception edge is unreachable - we are good
return;
}
GraalError.guarantee(exceptionEdge instanceof MemoryKill, "The exception edge of %s is not a memory kill %s", node, exceptionEdge);
if (exceptionEdge instanceof SingleMemoryKill) {
SingleMemoryKill exceptionEdgeKill = (SingleMemoryKill) exceptionEdge;
if (exceptionEdgeKill.getKilledLocationIdentity().isAny()) {
// exception edge kills any - we are good
return;
}
// if the exception edge does not kill any, it must kill the same location
GraalError.guarantee(withExceptionNode instanceof SingleMemoryKill, "Not a single memory kill: %s", withExceptionNode);
SingleMemoryKill withExceptionKill = (SingleMemoryKill) withExceptionNode;
GraalError.guarantee(withExceptionKill.getKilledLocationIdentity().equals(exceptionEdgeKill.getKilledLocationIdentity()), "Kill locations do not match: %s (%s) vs %s (%s)", withExceptionKill, withExceptionKill.getKilledLocationIdentity(), exceptionEdgeKill, exceptionEdgeKill.getKilledLocationIdentity());
} else if (exceptionEdge instanceof MultiMemoryKill) {
// for multi memory kills the locations must match
MultiMemoryKill exceptionEdgeKill = (MultiMemoryKill) exceptionEdge;
GraalError.guarantee(withExceptionNode instanceof MultiMemoryKill, "Not a single memory kill: %s", withExceptionNode);
MultiMemoryKill withExceptionKill = (MultiMemoryKill) withExceptionNode;
GraalError.guarantee(Arrays.equals(withExceptionKill.getKilledLocationIdentities(), exceptionEdgeKill.getKilledLocationIdentities()), "Kill locations do not match: %s (%s) vs %s (%s)", withExceptionKill, withExceptionKill.getKilledLocationIdentities(), exceptionEdgeKill, exceptionEdgeKill.getKilledLocationIdentities());
} else {
GraalError.shouldNotReachHere("Unexpected exception edge: " + exceptionEdge);
}
}
}
use of org.graalvm.compiler.nodes.WithExceptionNode in project graal by oracle.
the class PlaceholderLogicNode method markExceptionsUnreachable.
/**
* Searches for {@link WithExceptionNode} reachable from the {@link UnwindNode} and marks them
* as {@linkplain WithExceptionNode#replaceWithNonThrowing() non-throwing}.
*/
private static void markExceptionsUnreachable(ValueNode snippetExceptionValue, EconomicMap<Node, Node> duplicates) {
assert snippetExceptionValue.graph().isSubstitution() : "search should be done in the snippet graph";
if (snippetExceptionValue instanceof ValuePhiNode) {
for (ValueNode phiInput : ((PhiNode) snippetExceptionValue).values().snapshot()) {
markExceptionsUnreachable(phiInput, duplicates);
}
} else {
// snippetExceptionValue is a (lowered) ExceptionObjectNode
Node snippetUnwindPred = snippetExceptionValue.predecessor();
// the exception node might have been lowered to a memory anchor and a begin node
while (snippetUnwindPred instanceof AbstractBeginNode || snippetUnwindPred instanceof MemoryAnchorNode) {
snippetUnwindPred = snippetUnwindPred.predecessor();
}
GraalError.guarantee(snippetUnwindPred instanceof WithExceptionNode, "Unexpected exception producer: %s", snippetUnwindPred);
WithExceptionNode snippetWithException = (WithExceptionNode) duplicates.get(snippetUnwindPred);
snippetWithException.replaceWithNonThrowing();
}
}
use of org.graalvm.compiler.nodes.WithExceptionNode in project graal by oracle.
the class GraphEffectList method deleteNode.
/**
* Removes the given fixed node from the control flow and deletes it.
*
* @param node The fixed node that should be deleted.
*/
public void deleteNode(Node node) {
add("delete fixed node", new Effect() {
@Override
public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) {
if (node instanceof FixedWithNextNode) {
GraphUtil.unlinkFixedNode((FixedWithNextNode) node);
} else if (node instanceof WithExceptionNode && node.isAlive()) {
WithExceptionNode withExceptionNode = (WithExceptionNode) node;
AbstractBeginNode next = withExceptionNode.next();
GraphUtil.unlinkAndKillExceptionEdge(withExceptionNode);
if (next.hasNoUsages() && next instanceof MemoryKill) {
// This is a killing begin which is no longer needed.
graph.replaceFixedWithFixed(next, graph.add(new BeginNode()));
}
obsoleteNodes.add(withExceptionNode);
}
obsoleteNodes.add(node);
}
@Override
public boolean isCfgKill() {
return node instanceof WithExceptionNode;
}
});
}
Aggregations