Search in sources :

Example 1 with MemoryMapNode

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

the class SnippetTemplate method rewireMemoryGraph.

private void rewireMemoryGraph(ValueNode replacee, UnmodifiableEconomicMap<Node, Node> duplicates) {
    if (replacee.graph().isAfterFloatingReadPhase()) {
        // rewire outgoing memory edges
        replaceMemoryUsages(replacee, new MemoryOutputMap(replacee, duplicates));
        if (returnNode != null) {
            ReturnNode ret = (ReturnNode) duplicates.get(returnNode);
            if (ret != null) {
                MemoryMapNode memoryMap = ret.getMemoryMap();
                if (memoryMap != null) {
                    ret.setMemoryMap(null);
                    memoryMap.safeDelete();
                }
            }
        }
        if (memoryAnchor != null) {
            // rewire incoming memory edges
            MemoryAnchorNode memoryDuplicate = (MemoryAnchorNode) duplicates.get(memoryAnchor);
            replaceMemoryUsages(memoryDuplicate, new MemoryInputMap(replacee));
            if (memoryDuplicate.hasNoUsages()) {
                if (memoryDuplicate.next() != null) {
                    memoryDuplicate.graph().removeFixed(memoryDuplicate);
                } else {
                    // this was a dummy memory node used when instantiating pure data-flow
                    // snippets: it was not attached to the control flow.
                    memoryDuplicate.safeDelete();
                }
            }
        }
    }
}
Also used : ReturnNode(org.graalvm.compiler.nodes.ReturnNode) MemoryMapNode(org.graalvm.compiler.nodes.memory.MemoryMapNode) MemoryAnchorNode(org.graalvm.compiler.nodes.memory.MemoryAnchorNode)

Example 2 with MemoryMapNode

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

the class SnippetTemplate method assertSnippetKills.

private boolean assertSnippetKills(ValueNode replacee) {
    if (!replacee.graph().isAfterFloatingReadPhase()) {
        // 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 MemoryCheckpoint.Single) {
        // check if some node in snippet graph also kills the same location
        LocationIdentity locationIdentity = ((MemoryCheckpoint.Single) replacee).getLocationIdentity();
        if (locationIdentity.isAny()) {
            assert !(memoryMap.getLastLocationAccess(any()) instanceof MemoryAnchorNode) : replacee + " kills ANY_LOCATION, but snippet does not";
            // 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 MemoryCheckpoint.Multi) : 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 : MemoryMapNode(org.graalvm.compiler.nodes.memory.MemoryMapNode) LocationIdentity(org.graalvm.word.LocationIdentity) MemoryAnchorNode(org.graalvm.compiler.nodes.memory.MemoryAnchorNode)

Aggregations

MemoryAnchorNode (org.graalvm.compiler.nodes.memory.MemoryAnchorNode)2 MemoryMapNode (org.graalvm.compiler.nodes.memory.MemoryMapNode)2 ReturnNode (org.graalvm.compiler.nodes.ReturnNode)1 LocationIdentity (org.graalvm.word.LocationIdentity)1