use of org.graalvm.compiler.nodes.FixedWithNextNode 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;
}
use of org.graalvm.compiler.nodes.FixedWithNextNode in project graal by oracle.
the class ValueMergeUtil method mergeValueProducers.
public static <T> ValueNode mergeValueProducers(AbstractMergeNode merge, List<? extends T> valueProducers, Function<T, FixedWithNextNode> lastInstrFunction, Function<T, ValueNode> valueFunction) {
ValueNode singleResult = null;
PhiNode phiResult = null;
for (T valueProducer : valueProducers) {
ValueNode result = valueFunction.apply(valueProducer);
if (result != null) {
if (phiResult == null && (singleResult == null || singleResult == result)) {
/* Only one result value, so no need yet for a phi node. */
singleResult = result;
} else if (phiResult == null) {
/* Found a second result value, so create phi node. */
phiResult = merge.graph().addWithoutUnique(new ValuePhiNode(result.stamp(NodeView.DEFAULT).unrestricted(), merge));
for (int i = 0; i < merge.forwardEndCount(); i++) {
phiResult.addInput(singleResult);
}
phiResult.addInput(result);
} else {
/* Multiple return values, just add to existing phi node. */
phiResult.addInput(result);
}
}
// create and wire up a new EndNode
EndNode endNode = merge.graph().add(new EndNode());
merge.addForwardEnd(endNode);
if (lastInstrFunction == null) {
assert valueProducer instanceof ReturnNode || valueProducer instanceof UnwindNode;
((ControlSinkNode) valueProducer).replaceAndDelete(endNode);
} else {
FixedWithNextNode lastInstr = lastInstrFunction.apply(valueProducer);
lastInstr.setNext(endNode);
}
}
if (phiResult != null) {
assert phiResult.verify();
phiResult.inferStamp();
return phiResult;
} else {
return singleResult;
}
}
Aggregations