Search in sources :

Example 16 with VirtualObjectNode

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;
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) VirtualObjectState(org.graalvm.compiler.virtual.nodes.VirtualObjectState) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) BitSet(java.util.BitSet) ValueNode(org.graalvm.compiler.nodes.ValueNode) Block(org.graalvm.compiler.nodes.cfg.Block)

Example 17 with VirtualObjectNode

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);
            }
        }
    }
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Example 18 with VirtualObjectNode

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");
            }
        }
    }
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) ValueProxyNode(org.graalvm.compiler.nodes.ValueProxyNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) ValueProxyNode(org.graalvm.compiler.nodes.ValueProxyNode) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Example 19 with VirtualObjectNode

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);
                }
            }
        }
    }
}
Also used : ValueProxyNode(org.graalvm.compiler.nodes.ValueProxyNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) VirtualObjectState(org.graalvm.compiler.virtual.nodes.VirtualObjectState) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Example 20 with VirtualObjectNode

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;
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) VirtualObjectState(org.graalvm.compiler.virtual.nodes.VirtualObjectState) Canonicalizable(org.graalvm.compiler.graph.spi.Canonicalizable) ValueNode(org.graalvm.compiler.nodes.ValueNode) ControlSinkNode(org.graalvm.compiler.nodes.ControlSinkNode)

Aggregations

VirtualObjectNode (org.graalvm.compiler.nodes.virtual.VirtualObjectNode)42 ValueNode (org.graalvm.compiler.nodes.ValueNode)38 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)8 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)7 Node (org.graalvm.compiler.graph.Node)7 ProxyNode (org.graalvm.compiler.nodes.ProxyNode)7 VirtualObjectState (org.graalvm.compiler.virtual.nodes.VirtualObjectState)6 FixedNode (org.graalvm.compiler.nodes.FixedNode)5 PhiNode (org.graalvm.compiler.nodes.PhiNode)5 Block (org.graalvm.compiler.nodes.cfg.Block)5 ArrayList (java.util.ArrayList)4 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)4 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)4 ValueProxyNode (org.graalvm.compiler.nodes.ValueProxyNode)4 VirtualArrayNode (org.graalvm.compiler.nodes.virtual.VirtualArrayNode)4 VirtualInstanceNode (org.graalvm.compiler.nodes.virtual.VirtualInstanceNode)4 JavaKind (jdk.vm.ci.meta.JavaKind)3 FrameState (org.graalvm.compiler.nodes.FrameState)3 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)3 BitSet (java.util.BitSet)2