# HG changeset patch # User Lukas Stadler # Date 1396863128 -7200 # Node ID 4b1f128a3d45da84041071a0df22b352d06354c7 # Parent 06e50d290784c3686c70458e6b6b2a194e24bca9 create memory anchor for snippet StartNodes diff -r 06e50d290784 -r 4b1f128a3d45 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java Mon Apr 07 11:32:08 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java Mon Apr 07 11:32:08 2014 +0200 @@ -25,10 +25,12 @@ import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.type.*; +@NodeInfo(allowedUsageTypes = {InputType.Association}) public abstract class MemoryMapNode extends FloatingNode { public MemoryMapNode() { @@ -38,4 +40,6 @@ public abstract MemoryNode getLastLocationAccess(LocationIdentity locationIdentity); public abstract Set getLocations(); + + public abstract void replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode); } diff -r 06e50d290784 -r 4b1f128a3d45 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Mon Apr 07 11:32:08 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Mon Apr 07 11:32:08 2014 +0200 @@ -90,6 +90,14 @@ return lastMemorySnapshot.keySet(); } + @Override + public void replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode) { + for (Map.Entry entry : lastMemorySnapshot.entrySet()) { + if (entry.getValue() == oldNode) { + entry.setValue(newNode); + } + } + } } private final ExecutionMode execmode; diff -r 06e50d290784 -r 4b1f128a3d45 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Mon Apr 07 11:32:08 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Mon Apr 07 11:32:08 2014 +0200 @@ -61,7 +61,7 @@ /** * A snippet template is a graph created by parsing a snippet method and then specialized by binding * constants to the snippet's {@link ConstantParameter} parameters. - * + * * Snippet templates can be managed in a cache maintained by {@link AbstractTemplates}. */ public class SnippetTemplate { @@ -79,14 +79,14 @@ /** * Times instantiations of all templates derived form this snippet. - * + * * @see SnippetTemplate#instantiationTimer */ private final DebugTimer instantiationTimer; /** * Counts instantiations of all templates derived from this snippet. - * + * * @see SnippetTemplate#instantiationCounter */ private final DebugMetric instantiationCounter; @@ -627,12 +627,24 @@ new FloatingReadPhase(FloatingReadPhase.ExecutionMode.ANALYSIS_ONLY).apply(snippetCopy); + MemoryAnchorNode memoryAnchor = snippetCopy.add(new MemoryAnchorNode()); + snippetCopy.start().replaceAtUsages(InputType.Memory, memoryAnchor); + if (memoryAnchor.usages().isEmpty()) { + memoryAnchor.safeDelete(); + } else { + snippetCopy.addAfterFixed(snippetCopy.start(), memoryAnchor); + } + this.snippet = snippetCopy; + + Debug.dump(snippet, "SnippetTemplate after fixing memory anchoring"); + List returnNodes = new ArrayList<>(4); List memMaps = new ArrayList<>(4); StartNode entryPointNode = snippet.start(); for (ReturnNode retNode : snippet.getNodes(ReturnNode.class)) { MemoryMapNode memMap = retNode.getMemoryMap(); + memMap.replaceLastLocationAccess(snippetCopy.start(), memoryAnchor); memMaps.add(memMap); retNode.setMemoryMap(null); returnNodes.add(retNode); @@ -750,21 +762,21 @@ /** * Times instantiations of this template. - * + * * @see SnippetInfo#instantiationTimer */ private final DebugTimer instantiationTimer; /** * Counts instantiations of this template. - * + * * @see SnippetInfo#instantiationCounter */ private final DebugMetric instantiationCounter; /** * Gets the instantiation-time bindings to this template's parameters. - * + * * @return the map that will be used to bind arguments to parameters when inlining this template */ private IdentityHashMap bind(StructuredGraph replaceeGraph, MetaAccessProvider metaAccess, Arguments args) { @@ -821,7 +833,7 @@ * Converts a Java boxed value to a {@link Constant} of the right kind. This adjusts for the * limitation that a {@link Local}'s kind is a {@linkplain Kind#getStackKind() stack kind} and * so cannot be used for re-boxing primitives smaller than an int. - * + * * @param argument a Java boxed value * @param localKind the kind of the {@link Local} to which {@code argument} will be bound */ @@ -929,7 +941,7 @@ // check if some node in snippet graph also kills the same location LocationIdentity locationIdentity = ((MemoryCheckpoint.Single) replacee).getLocationIdentity(); if (locationIdentity == ANY_LOCATION) { - assert !(memoryMap.getLastLocationAccess(ANY_LOCATION) instanceof StartNode) : replacee + " kills ANY_LOCATION, but snippet does not"; + assert !(memoryMap.getLastLocationAccess(ANY_LOCATION) instanceof MemoryAnchorNode) : replacee + " kills ANY_LOCATION, but snippet does not"; } assert kills.contains(locationIdentity) : replacee + " kills " + locationIdentity + ", but snippet doesn't contain a kill to this location"; return true; @@ -939,7 +951,7 @@ Debug.log("WARNING: %s is not a MemoryCheckpoint, but the snippet graph contains kills (%s). You might want %s to be a MemoryCheckpoint", replacee, kills, replacee); // remove ANY_LOCATION if it's just a kill by the start node - if (memoryMap.getLastLocationAccess(ANY_LOCATION) instanceof StartNode) { + if (memoryMap.getLastLocationAccess(ANY_LOCATION) instanceof MemoryAnchorNode) { kills.remove(ANY_LOCATION); } @@ -985,11 +997,16 @@ public Set getLocations() { return memoryMap.getLocations(); } + + @Override + public void replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode) { + throw GraalInternalError.shouldNotReachHere(); + } } /** * Replaces a given fixed node with this specialized snippet. - * + * * @param metaAccess * @param replacee the node that will be replaced * @param replacer object that replaces the usages of {@code replacee} @@ -1140,7 +1157,7 @@ /** * Replaces a given floating node with this specialized snippet. - * + * * @param metaAccess * @param replacee the node that will be replaced * @param replacer object that replaces the usages of {@code replacee} diff -r 06e50d290784 -r 4b1f128a3d45 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MemoryAnchorNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MemoryAnchorNode.java Mon Apr 07 11:32:08 2014 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.replacements.nodes; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +@NodeInfo(allowedUsageTypes = {InputType.Memory}) +public class MemoryAnchorNode extends FixedWithNextNode implements LIRLowerable, MemoryNode { + + public MemoryAnchorNode() { + super(StampFactory.forVoid()); + } + + public void generate(NodeLIRBuilderTool generator) { + // Nothing to emit, since this node is used for structural purposes only. + } + + public MemoryCheckpoint asMemoryCheckpoint() { + return null; + } + + public MemoryPhiNode asMemoryPhi() { + return null; + } +}