use of org.graalvm.compiler.nodes.virtual.VirtualObjectNode in project graal by oracle.
the class PartialEscapeClosure method stripKilledLoopLocations.
@Override
protected BlockT stripKilledLoopLocations(Loop<Block> loop, BlockT originalInitialState) {
BlockT initialState = super.stripKilledLoopLocations(loop, originalInitialState);
if (loop.getDepth() > GraalOptions.EscapeAnalysisLoopCutoff.getValue(cfg.graph.getOptions())) {
/*
* After we've reached the maximum loop nesting, we'll simply materialize everything we
* can to make sure that the loops only need to be iterated one time. Care is taken here
* to not materialize virtual objects that have the "ensureVirtualized" flag set.
*/
LoopBeginNode loopBegin = (LoopBeginNode) loop.getHeader().getBeginNode();
AbstractEndNode end = loopBegin.forwardEnd();
Block loopPredecessor = loop.getHeader().getFirstPredecessor();
assert loopPredecessor.getEndNode() == end;
int length = initialState.getStateCount();
boolean change;
BitSet ensureVirtualized = new BitSet(length);
for (int i = 0; i < length; i++) {
ObjectState state = initialState.getObjectStateOptional(i);
if (state != null && state.isVirtual() && state.getEnsureVirtualized()) {
ensureVirtualized.set(i);
}
}
do {
// propagate "ensureVirtualized" flag
change = false;
for (int i = 0; i < length; i++) {
if (!ensureVirtualized.get(i)) {
ObjectState state = initialState.getObjectStateOptional(i);
if (state != null && state.isVirtual()) {
for (ValueNode entry : state.getEntries()) {
if (entry instanceof VirtualObjectNode) {
if (ensureVirtualized.get(((VirtualObjectNode) entry).getObjectId())) {
change = true;
ensureVirtualized.set(i);
break;
}
}
}
}
}
}
} while (change);
for (int i = 0; i < length; i++) {
ObjectState state = initialState.getObjectStateOptional(i);
if (state != null && state.isVirtual() && !ensureVirtualized.get(i)) {
initialState.materializeBefore(end, virtualObjects.get(i), blockEffects.get(loopPredecessor));
}
}
}
return initialState;
}
use of org.graalvm.compiler.nodes.virtual.VirtualObjectNode in project graal by oracle.
the class PartialEscapeClosure method processInitialLoopState.
@Override
protected void processInitialLoopState(Loop<Block> loop, BlockT initialState) {
for (PhiNode phi : ((LoopBeginNode) loop.getHeader().getBeginNode()).phis()) {
if (phi.valueAt(0) != null) {
ValueNode alias = getAliasAndResolve(initialState, phi.valueAt(0));
if (alias instanceof VirtualObjectNode) {
VirtualObjectNode virtual = (VirtualObjectNode) alias;
addVirtualAlias(virtual, phi);
} else {
aliases.set(phi, null);
}
}
}
}
use of org.graalvm.compiler.nodes.virtual.VirtualObjectNode in project graal by oracle.
the class PartialEscapeClosure method processVirtualAtLoopExit.
private static void processVirtualAtLoopExit(LoopExitNode exitNode, GraphEffectList effects, int object, ObjectState exitObjState, ObjectState initialObjState, PartialEscapeBlockState<?> exitState) {
for (int i = 0; i < exitObjState.getEntries().length; i++) {
ValueNode value = exitState.getObjectState(object).getEntry(i);
if (!(value instanceof VirtualObjectNode || value.isConstant())) {
if (exitNode.loopBegin().isPhiAtMerge(value) || initialObjState == null || !initialObjState.isVirtual() || initialObjState.getEntry(i) != value) {
ProxyNode proxy = new ValueProxyNode(value, exitNode);
exitState.setEntry(object, i, proxy);
effects.addFloatingNode(proxy, "virtualProxy");
}
}
}
}
use of org.graalvm.compiler.nodes.virtual.VirtualObjectNode in project graal by oracle.
the class PartialEscapeClosure method processLoopExit.
@Override
protected void processLoopExit(LoopExitNode exitNode, BlockT initialState, BlockT exitState, GraphEffectList effects) {
if (exitNode.graph().hasValueProxies()) {
EconomicMap<Integer, ProxyNode> proxies = EconomicMap.create(Equivalence.DEFAULT);
for (ProxyNode proxy : exitNode.proxies()) {
ValueNode alias = getAlias(proxy.value());
if (alias instanceof VirtualObjectNode) {
VirtualObjectNode virtual = (VirtualObjectNode) alias;
proxies.put(virtual.getObjectId(), proxy);
}
}
for (int i = 0; i < exitState.getStateCount(); i++) {
ObjectState exitObjState = exitState.getObjectStateOptional(i);
if (exitObjState != null) {
ObjectState initialObjState = initialState.getObjectStateOptional(i);
if (exitObjState.isVirtual()) {
processVirtualAtLoopExit(exitNode, effects, i, exitObjState, initialObjState, exitState);
} else {
processMaterializedAtLoopExit(exitNode, effects, proxies, i, exitObjState, initialObjState, exitState);
}
}
}
}
}
use of org.graalvm.compiler.nodes.virtual.VirtualObjectNode in project graal by oracle.
the class PartialEscapeClosure method processNodeWithScalarReplacedInputs.
/**
* This tries to canonicalize the node based on improved (replaced) inputs.
*/
@SuppressWarnings("unchecked")
private boolean processNodeWithScalarReplacedInputs(ValueNode node, FixedNode insertBefore, BlockT state, GraphEffectList effects) {
ValueNode canonicalizedValue = node;
if (node instanceof Canonicalizable.Unary<?>) {
Canonicalizable.Unary<ValueNode> canonicalizable = (Canonicalizable.Unary<ValueNode>) node;
ObjectState valueObj = getObjectState(state, canonicalizable.getValue());
ValueNode valueAlias = valueObj != null ? valueObj.getMaterializedValue() : getScalarAlias(canonicalizable.getValue());
if (valueAlias != canonicalizable.getValue()) {
canonicalizedValue = (ValueNode) canonicalizable.canonical(tool, valueAlias);
}
} else if (node instanceof Canonicalizable.Binary<?>) {
Canonicalizable.Binary<ValueNode> canonicalizable = (Canonicalizable.Binary<ValueNode>) node;
ObjectState xObj = getObjectState(state, canonicalizable.getX());
ValueNode xAlias = xObj != null ? xObj.getMaterializedValue() : getScalarAlias(canonicalizable.getX());
ObjectState yObj = getObjectState(state, canonicalizable.getY());
ValueNode yAlias = yObj != null ? yObj.getMaterializedValue() : getScalarAlias(canonicalizable.getY());
if (xAlias != canonicalizable.getX() || yAlias != canonicalizable.getY()) {
canonicalizedValue = (ValueNode) canonicalizable.canonical(tool, xAlias, yAlias);
}
} else {
return false;
}
if (canonicalizedValue != node && canonicalizedValue != null) {
if (canonicalizedValue.isAlive()) {
ValueNode alias = getAliasAndResolve(state, canonicalizedValue);
if (alias instanceof VirtualObjectNode) {
addVirtualAlias((VirtualObjectNode) alias, node);
effects.deleteNode(node);
} else {
effects.replaceAtUsages(node, alias, insertBefore);
addScalarAlias(node, alias);
}
} else {
if (!prepareCanonicalNode(canonicalizedValue, state, effects)) {
VirtualUtil.trace(node.getOptions(), debug, "replacement via canonicalization too complex: %s -> %s", node, canonicalizedValue);
return false;
}
if (canonicalizedValue instanceof ControlSinkNode) {
effects.replaceWithSink((FixedWithNextNode) node, (ControlSinkNode) canonicalizedValue);
state.markAsDead();
} else {
effects.replaceAtUsages(node, canonicalizedValue, insertBefore);
addScalarAlias(node, canonicalizedValue);
}
}
VirtualUtil.trace(node.getOptions(), debug, "replaced via canonicalization: %s -> %s", node, canonicalizedValue);
return true;
}
return false;
}
Aggregations