package org.graalvm.compiler.phases.common;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.PrefetchAllocateNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.extended.JavaReadNode;
import org.graalvm.compiler.nodes.memory.AbstractWriteNode;
import org.graalvm.compiler.nodes.memory.FloatingReadNode;
import org.graalvm.compiler.nodes.memory.ReadNode;
import org.graalvm.compiler.nodes.memory.address.AddressNode;
import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.phases.Phase;
import jdk.vm.ci.meta.JavaKind;
public class AddressLoweringByUsePhase extends Phase {
public abstract static class AddressLoweringByUse {
public abstract AddressNode lower(ValueNode use, Stamp stamp, AddressNode address);
public abstract AddressNode lower(AddressNode address);
}
private final AddressLoweringByUse lowering;
public AddressLoweringByUsePhase(AddressLoweringByUse lowering) {
this.lowering = lowering;
assert lowering != null;
}
@Override
protected void run(StructuredGraph graph) {
for (Node node : graph.getNodes()) {
AddressNode address;
AddressNode lowered;
if (node instanceof ReadNode) {
ReadNode readNode = (ReadNode) node;
Stamp stamp = readNode.getAccessStamp(NodeView.DEFAULT);
address = readNode.getAddress();
lowered = lowering.lower(readNode, stamp, address);
} else if (node instanceof JavaReadNode) {
JavaReadNode javaReadNode = (JavaReadNode) node;
Stamp stamp = javaReadNode.stamp(NodeView.DEFAULT);
address = javaReadNode.getAddress();
lowered = lowering.lower(javaReadNode, stamp, address);
} else if (node instanceof FloatingReadNode) {
FloatingReadNode floatingReadNode = (FloatingReadNode) node;
Stamp stamp = floatingReadNode.getAccessStamp(NodeView.DEFAULT);
address = floatingReadNode.getAddress();
lowered = lowering.lower(floatingReadNode, stamp, address);
} else if (node instanceof AbstractWriteNode) {
AbstractWriteNode abstractWriteNode = (AbstractWriteNode) node;
Stamp stamp = abstractWriteNode.value().stamp(NodeView.DEFAULT);
address = abstractWriteNode.getAddress();
lowered = lowering.lower(abstractWriteNode, stamp, address);
} else if (node instanceof PrefetchAllocateNode) {
PrefetchAllocateNode prefetchAllocateNode = (PrefetchAllocateNode) node;
Stamp stamp = StampFactory.forKind(JavaKind.Object);
address = (AddressNode) prefetchAllocateNode.inputs().first();
lowered = lowering.lower(prefetchAllocateNode, stamp, address);
} else {
continue;
}
if (lowered != address) {
node.replaceFirstInput(address, lowered);
if (address.hasNoUsages()) {
GraphUtil.killWithUnusedFloatingInputs(address);
}
}
}
for (Node node : graph.getNodes()) {
AddressNode lowered;
if (node instanceof OffsetAddressNode) {
AddressNode address = (AddressNode) node;
lowered = lowering.lower(address);
} else {
continue;
}
node.replaceAtUsages(lowered);
GraphUtil.killWithUnusedFloatingInputs(node);
}
}
}