use of org.graalvm.compiler.nodes.PhiNode in project graal by oracle.
the class GraphUtil method checkRedundantProxy.
public static void checkRedundantProxy(ProxyNode vpn) {
if (vpn.isDeleted()) {
return;
}
AbstractBeginNode proxyPoint = vpn.proxyPoint();
if (proxyPoint instanceof LoopExitNode) {
LoopExitNode exit = (LoopExitNode) proxyPoint;
LoopBeginNode loopBegin = exit.loopBegin();
Node vpnValue = vpn.value();
for (ValueNode v : loopBegin.stateAfter().values()) {
ValueNode v2 = v;
if (loopBegin.isPhiAtMerge(v2)) {
v2 = ((PhiNode) v2).valueAt(loopBegin.forwardEnd());
}
if (vpnValue == v2) {
Collection<PhiNode> phiUsages = vpn.usages().filter(PhiNode.class).snapshot();
Collection<ProxyNode> proxyUsages = vpn.usages().filter(ProxyNode.class).snapshot();
vpn.replaceAtUsagesAndDelete(vpnValue);
for (PhiNode phi : phiUsages) {
checkRedundantPhi(phi);
}
for (ProxyNode proxy : proxyUsages) {
checkRedundantProxy(proxy);
}
return;
}
}
}
}
use of org.graalvm.compiler.nodes.PhiNode in project graal by oracle.
the class GraphUtil method killWithUnusedFloatingInputs.
public static void killWithUnusedFloatingInputs(Node node, boolean mayKillGuard) {
assert checkKill(node, mayKillGuard);
node.markDeleted();
outer: for (Node in : node.inputs()) {
if (in.isAlive()) {
in.removeUsage(node);
if (in.hasNoUsages()) {
node.maybeNotifyZeroUsages(in);
}
if (isFloatingNode(in)) {
if (in.hasNoUsages()) {
if (in instanceof GuardNode) {
// Guard nodes are only killed if their anchor dies.
} else {
killWithUnusedFloatingInputs(in);
}
} else if (in instanceof PhiNode) {
for (Node use : in.usages()) {
if (use != in) {
continue outer;
}
}
in.replaceAtUsages(null);
killWithUnusedFloatingInputs(in);
}
}
}
}
}
use of org.graalvm.compiler.nodes.PhiNode in project graal by oracle.
the class GraphUtil method originalValueSimple.
private static ValueNode originalValueSimple(ValueNode value) {
/* The very simple case: look through proxies. */
ValueNode cur = originalValueForProxy(value);
while (cur instanceof PhiNode) {
/*
* We found a phi function. Check if we can analyze it without allocating temporary data
* structures.
*/
PhiNode phi = (PhiNode) cur;
ValueNode phiSingleValue = null;
int count = phi.valueCount();
for (int i = 0; i < count; ++i) {
ValueNode phiCurValue = originalValueForProxy(phi.valueAt(i));
if (phiCurValue == phi) {
/* Simple cycle, we can ignore the input value. */
} else if (phiSingleValue == null) {
/* The first input. */
phiSingleValue = phiCurValue;
} else if (phiSingleValue != phiCurValue) {
if (phiSingleValue instanceof PhiNode || phiCurValue instanceof PhiNode) {
/*
* We have two different input values for the phi function, and at least one
* of the inputs is another phi function. We need to do a complicated
* exhaustive check.
*/
return originalValueForComplicatedPhi(phi, new NodeBitMap(value.graph()));
} else {
/*
* We have two different input values for the phi function, but none of them
* is another phi function. This phi function cannot be reduce any further,
* so the phi function is the original value.
*/
return phi;
}
}
}
/*
* Successfully reduced the phi function to a single input value. The single input value
* can itself be a phi function again, so we might take another loop iteration.
*/
assert phiSingleValue != null;
cur = phiSingleValue;
}
/* We reached a "normal" node, which is the original value. */
assert !(cur instanceof LimitedValueProxy) && !(cur instanceof PhiNode);
return cur;
}
use of org.graalvm.compiler.nodes.PhiNode in project graal by oracle.
the class GraphUtil method originalValueForComplicatedPhi.
/**
* Handling for complicated nestings of phi functions. We need to reduce phi functions
* recursively, and need a temporary map of visited nodes to avoid endless recursion of cycles.
*/
private static ValueNode originalValueForComplicatedPhi(PhiNode phi, NodeBitMap visited) {
if (visited.isMarked(phi)) {
/*
* Found a phi function that was already seen. Either a cycle, or just a second phi
* input to a path we have already processed.
*/
return null;
}
visited.mark(phi);
ValueNode phiSingleValue = null;
int count = phi.valueCount();
for (int i = 0; i < count; ++i) {
ValueNode phiCurValue = originalValueForProxy(phi.valueAt(i));
if (phiCurValue instanceof PhiNode) {
/* Recursively process a phi function input. */
phiCurValue = originalValueForComplicatedPhi((PhiNode) phiCurValue, visited);
}
if (phiCurValue == null) {
/* Cycle to a phi function that was already seen. We can ignore this input. */
} else if (phiSingleValue == null) {
/* The first input. */
phiSingleValue = phiCurValue;
} else if (phiCurValue != phiSingleValue) {
/*
* Another input that is different from the first input. Since we already
* recursively looked through other phi functions, we now know that this phi
* function cannot be reduce any further, so the phi function is the original value.
*/
return phi;
}
}
return phiSingleValue;
}
use of org.graalvm.compiler.nodes.PhiNode in project graal by oracle.
the class LoadFieldNode method asPhi.
private static PhiNode asPhi(ConstantFieldProvider constantFields, ConstantReflectionProvider constantReflection, MetaAccessProvider metaAcccess, OptionValues options, ValueNode forObject, ResolvedJavaField field, Stamp stamp) {
if (!field.isStatic() && field.isFinal() && forObject instanceof ValuePhiNode && ((ValuePhiNode) forObject).values().filter(isNotA(ConstantNode.class)).isEmpty()) {
PhiNode phi = (PhiNode) forObject;
ConstantNode[] constantNodes = new ConstantNode[phi.valueCount()];
for (int i = 0; i < phi.valueCount(); i++) {
ConstantNode constant = ConstantFoldUtil.tryConstantFold(constantFields, constantReflection, metaAcccess, field, phi.valueAt(i).asJavaConstant(), options);
if (constant == null) {
return null;
}
constantNodes[i] = constant;
}
return new ValuePhiNode(stamp, phi.merge(), constantNodes);
}
return null;
}
Aggregations