use of org.graalvm.compiler.nodes.ValueNode in project graal by oracle.
the class MethodCallTargetNode method simplify.
@Override
public void simplify(SimplifierTool tool) {
// attempt to devirtualize the call
if (invoke().getContextMethod() == null) {
// avoid invokes that have placeholder bcis: they do not have a valid contextType
assert (invoke().stateAfter() != null && BytecodeFrame.isPlaceholderBci(invoke().stateAfter().bci)) || BytecodeFrame.isPlaceholderBci(invoke().stateDuring().bci);
return;
}
ResolvedJavaType contextType = (invoke().stateAfter() == null && invoke().stateDuring() == null) ? null : invoke().getContextType();
ResolvedJavaMethod specialCallTarget = findSpecialCallTarget(invokeKind, receiver(), targetMethod, contextType);
if (specialCallTarget != null) {
this.setTargetMethod(specialCallTarget);
setInvokeKind(InvokeKind.Special);
return;
}
Assumptions assumptions = graph().getAssumptions();
/*
* Even though we are not registering an assumption (see comment below), the optimization is
* only valid when speculative optimizations are enabled.
*/
if (invokeKind().isIndirect() && invokeKind().isInterface() && assumptions != null) {
// check if the type of the receiver can narrow the result
ValueNode receiver = receiver();
// try to turn a interface call into a virtual call
ResolvedJavaType declaredReceiverType = targetMethod().getDeclaringClass();
/*
* We need to check the invoke kind to avoid recursive simplification for virtual
* interface methods calls.
*/
if (declaredReceiverType.isInterface()) {
ResolvedJavaType singleImplementor = declaredReceiverType.getSingleImplementor();
if (singleImplementor != null && !singleImplementor.equals(declaredReceiverType)) {
TypeReference speculatedType = TypeReference.createTrusted(assumptions, singleImplementor);
if (tryCheckCastSingleImplementor(receiver, speculatedType)) {
return;
}
}
}
if (receiver instanceof UncheckedInterfaceProvider) {
UncheckedInterfaceProvider uncheckedInterfaceProvider = (UncheckedInterfaceProvider) receiver;
Stamp uncheckedStamp = uncheckedInterfaceProvider.uncheckedStamp();
if (uncheckedStamp != null) {
TypeReference speculatedType = StampTool.typeReferenceOrNull(uncheckedStamp);
if (speculatedType != null) {
tryCheckCastSingleImplementor(receiver, speculatedType);
}
}
}
}
}
use of org.graalvm.compiler.nodes.ValueNode in project graal by oracle.
the class MonitorExitNode method virtualize.
@Override
public void virtualize(VirtualizerTool tool) {
ValueNode alias = tool.getAlias(object());
if (alias instanceof VirtualObjectNode) {
VirtualObjectNode virtual = (VirtualObjectNode) alias;
if (virtual.hasIdentity()) {
MonitorIdNode removedLock = tool.removeLock(virtual);
assert removedLock == getMonitorId() : "mismatch at " + this + ": " + removedLock + " vs. " + getMonitorId();
tool.delete();
}
}
}
use of org.graalvm.compiler.nodes.ValueNode in project graal by oracle.
the class IntegerSwitchNode method doReplace.
private void doReplace(ValueNode newValue, List<KeyData> newKeyDatas, ArrayList<AbstractBeginNode> newSuccessors, int newDefaultSuccessor, double newDefaultProbability) {
/* Sort the new keys (invariant of the IntegerSwitchNode). */
newKeyDatas.sort(Comparator.comparingInt(k -> k.key));
/* Create the final data arrays. */
int newKeyCount = newKeyDatas.size();
int[] newKeys = new int[newKeyCount];
double[] newKeyProbabilities = new double[newKeyCount + 1];
int[] newKeySuccessors = new int[newKeyCount + 1];
for (int i = 0; i < newKeyCount; i++) {
KeyData keyData = newKeyDatas.get(i);
newKeys[i] = keyData.key;
newKeyProbabilities[i] = keyData.keyProbability;
newKeySuccessors[i] = keyData.keySuccessor;
}
newKeySuccessors[newKeyCount] = newDefaultSuccessor;
newKeyProbabilities[newKeyCount] = newDefaultProbability;
/* Normalize new probabilities so that they sum up to 1. */
double totalProbability = 0;
for (double probability : newKeyProbabilities) {
totalProbability += probability;
}
if (totalProbability > 0) {
for (int i = 0; i < newKeyProbabilities.length; i++) {
newKeyProbabilities[i] /= totalProbability;
}
} else {
for (int i = 0; i < newKeyProbabilities.length; i++) {
newKeyProbabilities[i] = 1.0 / newKeyProbabilities.length;
}
}
/*
* Collect dead successors. Successors have to be cleaned before adding the new node to the
* graph.
*/
List<AbstractBeginNode> deadSuccessors = successors.filter(s -> !newSuccessors.contains(s)).snapshot();
successors.clear();
/*
* Create the new switch node. This is done before removing dead successors as `killCFG`
* could edit some of the inputs (e.g., if `newValue` is a loop-phi of the loop that dies
* while removing successors).
*/
AbstractBeginNode[] successorsArray = newSuccessors.toArray(new AbstractBeginNode[newSuccessors.size()]);
SwitchNode newSwitch = graph().add(new IntegerSwitchNode(newValue, successorsArray, newKeys, newKeyProbabilities, newKeySuccessors));
/* Remove dead successors. */
for (AbstractBeginNode successor : deadSuccessors) {
GraphUtil.killCFG(successor);
}
/* Replace ourselves with the new switch */
((FixedWithNextNode) predecessor()).setNext(newSwitch);
GraphUtil.killWithUnusedFloatingInputs(this);
}
use of org.graalvm.compiler.nodes.ValueNode in project graal by oracle.
the class StoreFieldNode method virtualize.
@Override
public void virtualize(VirtualizerTool tool) {
ValueNode alias = tool.getAlias(object());
if (alias instanceof VirtualObjectNode) {
VirtualInstanceNode virtual = (VirtualInstanceNode) alias;
int fieldIndex = virtual.fieldIndex(field());
if (fieldIndex != -1) {
tool.setVirtualEntry(virtual, fieldIndex, value());
tool.delete();
}
}
}
use of org.graalvm.compiler.nodes.ValueNode in project graal by oracle.
the class ArrayLengthNode method virtualize.
@Override
public void virtualize(VirtualizerTool tool) {
ValueNode alias = tool.getAlias(array());
if (alias instanceof VirtualArrayNode) {
VirtualArrayNode virtualArray = (VirtualArrayNode) alias;
tool.replaceWithValue(ConstantNode.forInt(virtualArray.entryCount(), graph()));
}
}
Aggregations