use of org.graalvm.compiler.nodes.spi.Lowerable in project graal by oracle.
the class MacroNode method lower.
@Override
public void lower(LoweringTool tool) {
StructuredGraph replacementGraph = getLoweredSnippetGraph(tool);
InvokeNode invoke = replaceWithInvoke();
assert invoke.verify();
if (replacementGraph != null) {
// receiver can be lowered if necessary
if (!targetMethod.isStatic()) {
ValueNode nonNullReceiver = InliningUtil.nonNullReceiver(invoke);
if (nonNullReceiver instanceof Lowerable) {
((Lowerable) nonNullReceiver).lower(tool);
}
}
InliningUtil.inline(invoke, replacementGraph, false, targetMethod);
replacementGraph.getDebug().dump(DebugContext.DETAILED_LEVEL, graph(), "After inlining replacement %s", replacementGraph);
} else {
if (isPlaceholderBci(invoke.bci())) {
throw new GraalError("%s: cannot lower to invoke with placeholder BCI: %s", graph(), this);
}
if (invoke.stateAfter() == null) {
ResolvedJavaMethod method = graph().method();
if (method.getAnnotation(MethodSubstitution.class) != null || method.getAnnotation(Snippet.class) != null) {
// implementation in JDK9.
throw new GraalError("%s macro created for call to %s in %s must be lowerable to a snippet or intrinsic graph. " + "Maybe a macro node is not needed for this method in the current JDK?", getClass().getSimpleName(), targetMethod.format("%h.%n(%p)"), graph());
}
throw new GraalError("%s: cannot lower to invoke without state: %s", graph(), this);
}
invoke.lower(tool);
}
}
use of org.graalvm.compiler.nodes.spi.Lowerable in project graal by oracle.
the class LoweringPhase method checkPostNodeLowering.
/**
* Checks that lowering of a given node did not introduce any new {@link Lowerable} nodes that
* could be lowered in the current {@link LoweringPhase}. Such nodes must be recursively lowered
* as part of lowering {@code node}.
*
* @param node a node that was just lowered
* @param preLoweringMark the graph mark before {@code node} was lowered
* @param unscheduledUsages set of {@code node}'s usages that were unscheduled before it was
* lowered
* @throws AssertionError if the check fails
*/
private static boolean checkPostNodeLowering(Node node, LoweringToolImpl loweringTool, Mark preLoweringMark, Collection<Node> unscheduledUsages) {
StructuredGraph graph = (StructuredGraph) node.graph();
Mark postLoweringMark = graph.getMark();
NodeIterable<Node> newNodesAfterLowering = graph.getNewNodes(preLoweringMark);
if (node instanceof FloatingNode) {
if (!unscheduledUsages.isEmpty()) {
for (Node n : newNodesAfterLowering) {
assert !(n instanceof FixedNode) : node.graph() + ": cannot lower floatable node " + node + " as it introduces fixed node(s) but has the following unscheduled usages: " + unscheduledUsages;
}
}
}
for (Node n : newNodesAfterLowering) {
if (n instanceof Lowerable) {
((Lowerable) n).lower(loweringTool);
Mark mark = graph.getMark();
assert postLoweringMark.equals(mark) : graph + ": lowering of " + node + " produced lowerable " + n + " that should have been recursively lowered as it introduces these new nodes: " + graph.getNewNodes(postLoweringMark).snapshot();
}
if (graph.isAfterFloatingReadPhase() && n instanceof MemoryCheckpoint && !(node instanceof MemoryCheckpoint) && !(node instanceof ControlSinkNode)) {
/*
* The lowering introduced a MemoryCheckpoint but the current node isn't a
* checkpoint. This is only OK if the locations involved don't affect the memory
* graph or if the new kill location doesn't connect into the existing graph.
*/
boolean isAny = false;
if (n instanceof MemoryCheckpoint.Single) {
isAny = ((MemoryCheckpoint.Single) n).getLocationIdentity().isAny();
} else {
for (LocationIdentity ident : ((MemoryCheckpoint.Multi) n).getLocationIdentities()) {
if (ident.isAny()) {
isAny = true;
}
}
}
if (isAny && n instanceof FixedWithNextNode) {
/*
* Check if the next kill location leads directly to a ControlSinkNode in the
* new part of the graph. This is a fairly conservative test that could be made
* more general if required.
*/
FixedWithNextNode cur = (FixedWithNextNode) n;
while (cur != null && graph.isNew(preLoweringMark, cur)) {
if (cur.next() instanceof ControlSinkNode) {
isAny = false;
break;
}
if (cur.next() instanceof FixedWithNextNode) {
cur = (FixedWithNextNode) cur.next();
} else {
break;
}
}
}
assert !isAny : node + " " + n;
}
}
return true;
}
Aggregations