Search in sources :

Example 6 with MultiMemoryKill

use of org.graalvm.compiler.nodes.memory.MultiMemoryKill in project graal by oracle.

the class PEReadEliminationClosure method processNode.

@Override
protected boolean processNode(Node node, PEReadEliminationBlockState state, GraphEffectList effects, FixedWithNextNode lastFixedNode) {
    if (super.processNode(node, state, effects, lastFixedNode)) {
        return true;
    }
    if (currentMode != EffectsClosureMode.REGULAR_VIRTUALIZATION) {
        /*
             * PEA closure decided it has to give up for this loop nest, do the same and stop
             * processing nodes.
             */
        return false;
    }
    if (node instanceof LoadFieldNode) {
        return processLoadField((LoadFieldNode) node, state, effects);
    } else if (node instanceof StoreFieldNode) {
        return processStoreField((StoreFieldNode) node, state, effects);
    } else if (node instanceof LoadIndexedNode) {
        return processLoadIndexed((LoadIndexedNode) node, state, effects);
    } else if (node instanceof StoreIndexedNode) {
        return processStoreIndexed((StoreIndexedNode) node, state, effects);
    } else if (node instanceof ArrayLengthNode) {
        return processArrayLength((ArrayLengthNode) node, state, effects);
    } else if (node instanceof UnboxNode) {
        return processUnbox((UnboxNode) node, state, effects);
    } else if (node instanceof RawLoadNode) {
        return processUnsafeLoad((RawLoadNode) node, state, effects);
    } else if (node instanceof RawStoreNode) {
        return processUnsafeStore((RawStoreNode) node, state, effects);
    } else if (node instanceof SingleMemoryKill) {
        COUNTER_MEMORYCHECKPOINT.increment(node.getDebug());
        LocationIdentity identity = ((SingleMemoryKill) node).getKilledLocationIdentity();
        processIdentity(state, identity);
    } else if (node instanceof MultiMemoryKill) {
        COUNTER_MEMORYCHECKPOINT.increment(node.getDebug());
        for (LocationIdentity identity : ((MultiMemoryKill) node).getKilledLocationIdentities()) {
            processIdentity(state, identity);
        }
    }
    return false;
}
Also used : RawStoreNode(org.graalvm.compiler.nodes.extended.RawStoreNode) StoreIndexedNode(org.graalvm.compiler.nodes.java.StoreIndexedNode) UnboxNode(org.graalvm.compiler.nodes.extended.UnboxNode) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) MultiMemoryKill(org.graalvm.compiler.nodes.memory.MultiMemoryKill) LocationIdentity(org.graalvm.word.LocationIdentity) FieldLocationIdentity(org.graalvm.compiler.nodes.FieldLocationIdentity) NamedLocationIdentity(org.graalvm.compiler.nodes.NamedLocationIdentity) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) ArrayLengthNode(org.graalvm.compiler.nodes.java.ArrayLengthNode) RawLoadNode(org.graalvm.compiler.nodes.extended.RawLoadNode) SingleMemoryKill(org.graalvm.compiler.nodes.memory.SingleMemoryKill)

Example 7 with MultiMemoryKill

use of org.graalvm.compiler.nodes.memory.MultiMemoryKill in project graal by oracle.

the class LoweringPhase method checkPostNodeLowering.

/**
 * Checks that lowering of a given node did not introduce any new {@link Lowerable} nodes that
 * could be lowered in the current {@link LoweringPhase}. Such nodes must be recursively lowered
 * as part of lowering {@code node}.
 *
 * @param node a node that was just lowered
 * @param preLoweringMark the graph mark before {@code node} was lowered
 * @param unscheduledUsages set of {@code node}'s usages that were unscheduled before it was
 *            lowered
 * @throws AssertionError if the check fails
 */
private static boolean checkPostNodeLowering(Node node, LoweringToolImpl loweringTool, Mark preLoweringMark, Collection<Node> unscheduledUsages) {
    StructuredGraph graph = (StructuredGraph) node.graph();
    Mark postLoweringMark = graph.getMark();
    NodeIterable<Node> newNodesAfterLowering = graph.getNewNodes(preLoweringMark);
    if (node instanceof FloatingNode) {
        if (!unscheduledUsages.isEmpty()) {
            for (Node n : newNodesAfterLowering) {
                assert !(n instanceof FixedNode) : node.graph() + ": cannot lower floatable node " + node + " as it introduces fixed node(s) but has the following unscheduled usages: " + unscheduledUsages;
            }
        }
    }
    for (Node n : newNodesAfterLowering) {
        if (n instanceof Lowerable) {
            ((Lowerable) n).lower(loweringTool);
            Mark mark = graph.getMark();
            assert postLoweringMark.equals(mark) : graph + ": lowering of " + node + " produced lowerable " + n + " that should have been recursively lowered as it introduces these new nodes: " + graph.getNewNodes(postLoweringMark).snapshot();
        }
        if (graph.isAfterStage(StageFlag.FLOATING_READS) && n instanceof MemoryKill && !(node instanceof MemoryKill) && !(node instanceof ControlSinkNode)) {
            /*
                 * The lowering introduced a MemoryCheckpoint but the current node isn't a
                 * checkpoint. This is only OK if the locations involved don't affect the memory
                 * graph or if the new kill location doesn't connect into the existing graph.
                 */
            boolean isAny = false;
            if (n instanceof SingleMemoryKill) {
                isAny = ((SingleMemoryKill) n).getKilledLocationIdentity().isAny();
            } else if (n instanceof MultiMemoryKill) {
                for (LocationIdentity ident : ((MultiMemoryKill) n).getKilledLocationIdentities()) {
                    if (ident.isAny()) {
                        isAny = true;
                    }
                }
            } else {
                throw GraalError.shouldNotReachHere("Unknown type of memory kill " + n);
            }
            if (isAny && n instanceof FixedWithNextNode) {
                /*
                     * Check if the next kill location leads directly to a ControlSinkNode in the
                     * new part of the graph. This is a fairly conservative test that could be made
                     * more general if required.
                     */
                FixedWithNextNode cur = (FixedWithNextNode) n;
                while (cur != null && graph.isNew(preLoweringMark, cur)) {
                    if (cur.next() instanceof ControlSinkNode) {
                        isAny = false;
                        break;
                    }
                    if (cur.next() instanceof FixedWithNextNode) {
                        cur = (FixedWithNextNode) cur.next();
                    } else {
                        break;
                    }
                }
            }
            assert !isAny : node + " " + n;
        }
    }
    return true;
}
Also used : SingleMemoryKill(org.graalvm.compiler.nodes.memory.SingleMemoryKill) MultiMemoryKill(org.graalvm.compiler.nodes.memory.MultiMemoryKill) MemoryKill(org.graalvm.compiler.nodes.memory.MemoryKill) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) GuardedNode(org.graalvm.compiler.nodes.extended.GuardedNode) GuardingNode(org.graalvm.compiler.nodes.extended.GuardingNode) ControlSinkNode(org.graalvm.compiler.nodes.ControlSinkNode) GuardNode(org.graalvm.compiler.nodes.GuardNode) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) AnchoringNode(org.graalvm.compiler.nodes.extended.AnchoringNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) Mark(org.graalvm.compiler.graph.Graph.Mark) FixedNode(org.graalvm.compiler.nodes.FixedNode) ControlSinkNode(org.graalvm.compiler.nodes.ControlSinkNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) MultiMemoryKill(org.graalvm.compiler.nodes.memory.MultiMemoryKill) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) LocationIdentity(org.graalvm.word.LocationIdentity) Lowerable(org.graalvm.compiler.nodes.spi.Lowerable) SingleMemoryKill(org.graalvm.compiler.nodes.memory.SingleMemoryKill)

Example 8 with MultiMemoryKill

use of org.graalvm.compiler.nodes.memory.MultiMemoryKill in project graal by oracle.

the class VarHandleTest method countAnyKill.

private static int countAnyKill(StructuredGraph graph) {
    int anyKillCount = 0;
    int startNodes = 0;
    for (Node n : graph.getNodes()) {
        if (n instanceof StartNode) {
            startNodes++;
        } else if (n instanceof SingleMemoryKill) {
            SingleMemoryKill single = (SingleMemoryKill) n;
            if (single.getKilledLocationIdentity().isAny()) {
                anyKillCount++;
            }
        } else if (n instanceof MultiMemoryKill) {
            MultiMemoryKill multi = (MultiMemoryKill) n;
            for (LocationIdentity loc : multi.getKilledLocationIdentities()) {
                if (loc.isAny()) {
                    anyKillCount++;
                    break;
                }
            }
        }
    }
    // Ignore single StartNode.
    Assert.assertEquals(1, startNodes);
    return anyKillCount;
}
Also used : StartNode(org.graalvm.compiler.nodes.StartNode) MultiMemoryKill(org.graalvm.compiler.nodes.memory.MultiMemoryKill) WriteNode(org.graalvm.compiler.nodes.memory.WriteNode) StartNode(org.graalvm.compiler.nodes.StartNode) ReadNode(org.graalvm.compiler.nodes.memory.ReadNode) MembarNode(org.graalvm.compiler.nodes.extended.MembarNode) Node(org.graalvm.compiler.graph.Node) LocationIdentity(org.graalvm.word.LocationIdentity) SingleMemoryKill(org.graalvm.compiler.nodes.memory.SingleMemoryKill)

Example 9 with MultiMemoryKill

use of org.graalvm.compiler.nodes.memory.MultiMemoryKill in project graal by oracle.

the class PlaceholderLogicNode method assertSnippetKills.

private boolean assertSnippetKills(ValueNode replacee) {
    if (replacee.graph().isBeforeStage(StageFlag.FLOATING_READS)) {
        // no floating reads yet, ignore locations created while lowering
        return true;
    }
    if (returnNode == null) {
        // The snippet terminates control flow
        return true;
    }
    MemoryMapNode memoryMap = returnNode.getMemoryMap();
    if (memoryMap == null || memoryMap.isEmpty()) {
        // there are no kills in the snippet graph
        return true;
    }
    EconomicSet<LocationIdentity> kills = EconomicSet.create(Equivalence.DEFAULT);
    kills.addAll(memoryMap.getLocations());
    if (replacee instanceof SingleMemoryKill) {
        // check if some node in snippet graph also kills the same location
        LocationIdentity locationIdentity = ((SingleMemoryKill) replacee).getKilledLocationIdentity();
        if (locationIdentity.isAny()) {
            // if the replacee kills ANY_LOCATION, the snippet can kill arbitrary locations
            return true;
        }
        assert kills.contains(locationIdentity) : replacee + " kills " + locationIdentity + ", but snippet doesn't contain a kill to this location";
        kills.remove(locationIdentity);
    }
    assert !(replacee instanceof MultiMemoryKill) : replacee + " multi not supported (yet)";
    // remove ANY_LOCATION if it's just a kill by the start node
    if (memoryMap.getLastLocationAccess(any()) instanceof MemoryAnchorNode) {
        kills.remove(any());
    }
    // node can only lower to a ANY_LOCATION kill if the replacee also kills ANY_LOCATION
    assert !kills.contains(any()) : "snippet graph contains a kill to ANY_LOCATION, but replacee (" + replacee + ") doesn't kill ANY_LOCATION.  kills: " + kills;
    /*
         * Kills to private locations are safe, since there can be no floating read to these
         * locations except reads that are introduced by the snippet itself or related snippets in
         * the same lowering round. These reads are anchored to a MemoryAnchor at the beginning of
         * their snippet, so they can not float above a kill in another instance of the same
         * snippet.
         */
    for (LocationIdentity p : this.info.privateLocations) {
        kills.remove(p);
    }
    assert kills.isEmpty() : "snippet graph kills non-private locations " + kills + " that replacee (" + replacee + ") doesn't kill";
    return true;
}
Also used : MultiMemoryKill(org.graalvm.compiler.nodes.memory.MultiMemoryKill) MemoryMapNode(org.graalvm.compiler.nodes.memory.MemoryMapNode) LocationIdentity(org.graalvm.word.LocationIdentity) MemoryAnchorNode(org.graalvm.compiler.nodes.memory.MemoryAnchorNode) SingleMemoryKill(org.graalvm.compiler.nodes.memory.SingleMemoryKill)

Aggregations

MultiMemoryKill (org.graalvm.compiler.nodes.memory.MultiMemoryKill)9 SingleMemoryKill (org.graalvm.compiler.nodes.memory.SingleMemoryKill)9 LocationIdentity (org.graalvm.word.LocationIdentity)7 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)4 Node (org.graalvm.compiler.graph.Node)3 FixedNode (org.graalvm.compiler.nodes.FixedNode)3 PhiNode (org.graalvm.compiler.nodes.PhiNode)3 ProxyNode (org.graalvm.compiler.nodes.ProxyNode)3 MemoryKill (org.graalvm.compiler.nodes.memory.MemoryKill)3 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)2 ControlSinkNode (org.graalvm.compiler.nodes.ControlSinkNode)2 FieldLocationIdentity (org.graalvm.compiler.nodes.FieldLocationIdentity)2 GuardNode (org.graalvm.compiler.nodes.GuardNode)2 LogicNode (org.graalvm.compiler.nodes.LogicNode)2 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)2 NamedLocationIdentity (org.graalvm.compiler.nodes.NamedLocationIdentity)2 ValueNode (org.graalvm.compiler.nodes.ValueNode)2 VirtualState (org.graalvm.compiler.nodes.VirtualState)2 FloatingNode (org.graalvm.compiler.nodes.calc.FloatingNode)2 Block (org.graalvm.compiler.nodes.cfg.Block)2