# HG changeset patch # User Doug Simon # Date 1403710465 -7200 # Node ID e34bb128f22758cadecd55b18178527ac462e5ba # Parent a47528fb2ea09eebc24628d988ad0a8f36b71177# Parent cc4b4fd5c484513f74f72acfeb19085636761cc4 Merge. diff -r cc4b4fd5c484 -r e34bb128f227 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java Wed Jun 25 16:55:01 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java Wed Jun 25 17:34:25 2014 +0200 @@ -85,9 +85,11 @@ private StructuredGraph parseAndProcess(String snippet) { StructuredGraph graph = parse(snippet); ParameterNode param = graph.getNodes(ParameterNode.class).first(); - ConstantNode constant = ConstantNode.forInt(0, graph); - for (Node n : param.usages().filter(isNotA(FrameState.class)).snapshot()) { - n.replaceFirstInput(param, constant); + if (param != null) { + ConstantNode constant = ConstantNode.forInt(0, graph); + for (Node n : param.usages().filter(isNotA(FrameState.class)).snapshot()) { + n.replaceFirstInput(param, constant); + } } Map hints = new HashMap<>(); for (Invoke invoke : graph.getInvokes()) { diff -r cc4b4fd5c484 -r e34bb128f227 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeInputList.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeInputList.java Wed Jun 25 16:55:01 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeInputList.java Wed Jun 25 17:34:25 2014 +0200 @@ -49,6 +49,12 @@ this.self = self; } + public NodeInputList(Node self, Collection elements) { + super(elements); + assert self.usages().isEmpty(); + this.self = self; + } + @Override protected void update(T oldNode, T newNode) { self.updateUsages(oldNode, newNode); diff -r cc4b4fd5c484 -r e34bb128f227 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java Wed Jun 25 16:55:01 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java Wed Jun 25 17:34:25 2014 +0200 @@ -77,6 +77,24 @@ } } + protected NodeList(Collection elements) { + if (elements == null || elements.isEmpty()) { + this.size = 0; + this.nodes = EMPTY_NODE_ARRAY; + this.initialSize = 0; + } else { + this.size = elements.size(); + this.initialSize = elements.size(); + this.nodes = new Node[elements.size()]; + int i = 0; + for (NodeInterface n : elements) { + this.nodes[i] = n.asNode(); + assert this.nodes[i] == null || !this.nodes[i].isDeleted(); + i++; + } + } + } + protected abstract void update(T oldNode, T newNode); @Override diff -r cc4b4fd5c484 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMap.java Wed Jun 25 17:34:25 2014 +0200 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, 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.nodes; + +import java.util.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.extended.*; + +/** + * Maps a {@linkplain LocationIdentity location} to the last node that (potentially) wrote to the + * location. + */ +public interface MemoryMap { + + /** + * Gets the last node that that (potentially) wrote to {@code locationIdentity}. + */ + MemoryNode getLastLocationAccess(LocationIdentity locationIdentity); + + /** + * Gets the location identities in the domain of this map. + */ + Collection getLocations(); +} diff -r cc4b4fd5c484 -r e34bb128f227 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 Wed Jun 25 16:55:01 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java Wed Jun 25 17:34:25 2014 +0200 @@ -1,27 +1,7 @@ -/* - * Copyright (c) 2013, 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.nodes; +import static com.oracle.graal.api.meta.LocationIdentity.*; + import java.util.*; import com.oracle.graal.api.meta.*; @@ -29,17 +9,68 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; @NodeInfo(allowedUsageTypes = {InputType.Extension}) -public abstract class MemoryMapNode extends FloatingNode { +public class MemoryMapNode extends FloatingNode implements MemoryMap, LIRLowerable { + + private final List locationIdentities; + @Input(InputType.Memory) private final NodeInputList nodes; - public MemoryMapNode() { + private boolean checkOrder(Map mmap) { + for (int i = 0; i < locationIdentities.size(); i++) { + LocationIdentity locationIdentity = locationIdentities.get(i); + ValueNode n = nodes.get(i); + assertTrue(mmap.get(locationIdentity) == n, "iteration order of keys differs from values in input map"); + } + return true; + } + + public MemoryMapNode(Map mmap) { super(StampFactory.forVoid()); + locationIdentities = new ArrayList<>(mmap.keySet()); + nodes = new NodeInputList<>(this, mmap.values()); + assert checkOrder(mmap); } - public abstract MemoryNode getLastLocationAccess(LocationIdentity locationIdentity); + public boolean isEmpty() { + if (locationIdentities.isEmpty()) { + return true; + } + if (locationIdentities.size() == 1) { + if (nodes.get(0) instanceof StartNode) { + return true; + } + } + return false; + } - public abstract Set getLocations(); + public MemoryNode getLastLocationAccess(LocationIdentity locationIdentity) { + if (locationIdentity == FINAL_LOCATION) { + return null; + } else { + int index = locationIdentities.indexOf(locationIdentity); + if (index == -1) { + index = locationIdentities.indexOf(ANY_LOCATION); + } + assert index != -1; + return (MemoryNode) nodes.get(index); + } + } - public abstract boolean replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode); + public Collection getLocations() { + return locationIdentities; + } + + public Map toMap() { + HashMap res = new HashMap<>(locationIdentities.size()); + for (int i = 0; i < nodes.size(); i++) { + res.put(locationIdentities.get(i), (MemoryNode) nodes.get(i)); + } + return res; + } + + public void generate(NodeLIRBuilderTool generator) { + // nothing to do... + } } diff -r cc4b4fd5c484 -r e34bb128f227 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java diff -r cc4b4fd5c484 -r e34bb128f227 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 Wed Jun 25 16:55:01 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Wed Jun 25 17:34:25 2014 +0200 @@ -42,7 +42,7 @@ CREATE_FLOATING_READS } - public static class MemoryMapImpl extends MemoryMapNode { + public static class MemoryMapImpl implements MemoryMap { private final Map lastMemorySnapshot; @@ -74,33 +74,13 @@ } } - public boolean isEmpty() { - if (lastMemorySnapshot.size() == 0) { - return true; - } - if (lastMemorySnapshot.size() == 1) { - if (lastMemorySnapshot.get(ANY_LOCATION) instanceof StartNode) { - return true; - } - } - return false; - } - @Override - public Set getLocations() { + public Collection getLocations() { return lastMemorySnapshot.keySet(); } - @Override - public boolean replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode) { - boolean replaced = false; - for (Map.Entry entry : lastMemorySnapshot.entrySet()) { - if (entry.getValue() == oldNode) { - entry.setValue(newNode); - replaced = true; - } - } - return replaced; + public Map getMap() { + return lastMemorySnapshot; } } @@ -125,11 +105,11 @@ } } - public static MemoryMapImpl mergeMemoryMaps(MergeNode merge, List states) { + public static MemoryMapImpl mergeMemoryMaps(MergeNode merge, List states) { MemoryMapImpl newState = new MemoryMapImpl(); Set keys = new HashSet<>(); - for (MemoryMapNode other : states) { + for (MemoryMap other : states) { keys.addAll(other.getLocations()); } assert !keys.contains(FINAL_LOCATION); @@ -138,7 +118,7 @@ int mergedStatesCount = 0; boolean isPhi = false; MemoryNode merged = null; - for (MemoryMapNode state : states) { + for (MemoryMap state : states) { MemoryNode last = state.getLastLocationAccess(key); if (isPhi) { merged.asMemoryPhi().addInput(ValueNodeUtil.asNode(last)); @@ -243,7 +223,7 @@ assert MemoryCheckpoint.TypeAssertion.correctType(node) : node; if (execmode == ExecutionMode.ANALYSIS_ONLY && node instanceof ReturnNode) { - ((ReturnNode) node).setMemoryMap(node.graph().unique(new MemoryMapImpl(state))); + ((ReturnNode) node).setMemoryMap(node.graph().unique(new MemoryMapNode(state.lastMemorySnapshot))); } return state; } diff -r cc4b4fd5c484 -r e34bb128f227 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/NoDeadCodeVerifyHandler.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/NoDeadCodeVerifyHandler.java Wed Jun 25 16:55:01 2014 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/NoDeadCodeVerifyHandler.java Wed Jun 25 17:34:25 2014 +0200 @@ -42,19 +42,22 @@ // The options below will be removed once all phases clean up their own dead code. + private static final int OFF = 0; + private static final int INFO = 1; + private static final int VERBOSE = 2; + private static final int FATAL = 3; + static class Options { // @formatter:off - @Option(help = "Enable NoDeadCodeVerifyHandler") - public static final OptionValue NDCV = new OptionValue<>(false); - @Option(help = "Issues caught by NoDeadCodeVerifyHandler raise an error") - public static final OptionValue NDCVFatal = new OptionValue<>(false); + @Option(help = "Run level for NoDeadCodeVerifyHandler (0 = off, 1 = info, 2 = verbose, 3 = fatal)") + public static final OptionValue NDCV = new OptionValue<>(0); // @formatter:on } private static final Map, Boolean> discovered = new ConcurrentHashMap<>(); public void verify(Object object, Object... context) { - if (NDCV.getValue()) { + if (NDCV.getValue() != OFF) { StructuredGraph graph = extract(StructuredGraph.class, object); BasePhase phase = extract(BasePhase.class, context); if (graph != null) { @@ -64,15 +67,19 @@ assert after.size() <= before.size(); if (before.size() != after.size()) { before.removeAll(after); - if (NDCVFatal.getValue() || discovered.put(phase.getClass(), Boolean.TRUE) == null) { + if (discovered.put(phase.getClass(), Boolean.TRUE) == null) { String message = extract(String.class, context); String prefix = message == null ? "" : message + ": "; String phaseClass = phase == null ? null : phase.getClass().getName(); GraalInternalError error = new GraalInternalError("%sfound dead nodes in %s (phase class=%s): %s", prefix, graph, phaseClass, before); - if (NDCVFatal.getValue()) { + if (NDCV.getValue() == INFO) { + System.out.println(error.getMessage()); + } else if (NDCV.getValue() == VERBOSE) { + error.printStackTrace(System.out); + } else { + assert NDCV.getValue() == FATAL; throw error; } - error.printStackTrace(System.out); } } } diff -r cc4b4fd5c484 -r e34bb128f227 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Wed Jun 25 16:55:01 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Wed Jun 25 17:34:25 2014 +0200 @@ -208,7 +208,7 @@ } @Override - public void replace(ValueNode oldNode, ValueNode newNode, MemoryMapNode mmap) { + public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap mmap) { assert newNode instanceof PhiNode; assert oldNode == instanceOf; newNode.inferStamp(); @@ -239,7 +239,7 @@ } @Override - public void replace(ValueNode oldNode, ValueNode newNode, MemoryMapNode mmap) { + public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap mmap) { assert newNode instanceof PhiNode; assert oldNode == instanceOf; newNode.inferStamp(); diff -r cc4b4fd5c484 -r e34bb128f227 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 Wed Jun 25 16:55:01 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Wed Jun 25 17:34:25 2014 +0200 @@ -35,6 +35,7 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; +import java.util.stream.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; @@ -677,38 +678,33 @@ Debug.dump(snippet, "SnippetTemplate after fixing memory anchoring"); - List returnNodes = new ArrayList<>(4); - List memMaps = new ArrayList<>(4); StartNode entryPointNode = snippet.start(); - boolean anchorUsed = false; - for (ReturnNode retNode : snippet.getNodes(ReturnNode.class)) { - MemoryMapNode memMap = retNode.getMemoryMap(); - anchorUsed |= memMap.replaceLastLocationAccess(snippetCopy.start(), memoryAnchor); - memMaps.add(memMap); - retNode.setMemoryMap(null); - returnNodes.add(retNode); - if (memMap.usages().isEmpty()) { - memMap.safeDelete(); - } - } - if (memoryAnchor.usages().isEmpty() && !anchorUsed) { + if (memoryAnchor.usages().isEmpty()) { memoryAnchor.safeDelete(); } else { snippetCopy.addAfterFixed(snippetCopy.start(), memoryAnchor); } - assert snippet.getNodes().filter(MemoryMapNode.class).isEmpty(); + List returnNodes = snippet.getNodes(ReturnNode.class).snapshot(); if (returnNodes.isEmpty()) { this.returnNode = null; this.memoryMap = null; } else if (returnNodes.size() == 1) { this.returnNode = returnNodes.get(0); - this.memoryMap = memMaps.get(0); + this.memoryMap = returnNode.getMemoryMap(); } else { MergeNode merge = snippet.add(new MergeNode()); + List memMaps = returnNodes.stream().map(n -> n.getMemoryMap()).collect(Collectors.toList()); ValueNode returnValue = InliningUtil.mergeReturns(merge, returnNodes, null); this.returnNode = snippet.add(new ReturnNode(returnValue)); - this.memoryMap = FloatingReadPhase.mergeMemoryMaps(merge, memMaps); + MemoryMapImpl mmap = FloatingReadPhase.mergeMemoryMaps(merge, memMaps); + this.memoryMap = snippet.unique(new MemoryMapNode(mmap.getMap())); merge.setNext(this.returnNode); + + for (MemoryMapNode mm : memMaps) { + if (mm.isAlive()) { + mm.safeDelete(); + } + } } this.sideEffectNodes = curSideEffectNodes; @@ -798,7 +794,7 @@ private final ArrayList nodes; /** - * map of killing locations to memory checkpoints (nodes). + * Map of killing locations to memory checkpoints (nodes). */ private final MemoryMapNode memoryMap; @@ -897,7 +893,7 @@ /** * Replaces all usages of {@code oldNode} with direct or indirect usages of {@code newNode}. */ - void replace(ValueNode oldNode, ValueNode newNode, MemoryMapNode mmap); + void replace(ValueNode oldNode, ValueNode newNode, MemoryMap mmap); } /** @@ -919,7 +915,7 @@ } @Override - public void replace(ValueNode oldNode, ValueNode newNode, MemoryMapNode mmap) { + public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap mmap) { if (mmap != null) { for (Node usage : oldNode.usages().snapshot()) { LocationIdentity identity = getLocationIdentity(usage); @@ -961,12 +957,12 @@ // no floating reads yet, ignore locations created while lowering return true; } - if (memoryMap == null || ((MemoryMapImpl) memoryMap).isEmpty()) { - // there're no kills in the snippet graph + if (memoryMap == null || memoryMap.isEmpty()) { + // there are no kills in the snippet graph return true; } - Set kills = new HashSet<>(((MemoryMapImpl) memoryMap).getLocations()); + Set kills = new HashSet<>(memoryMap.getLocations()); if (replacee instanceof MemoryCheckpoint.Single) { // check if some node in snippet graph also kills the same location @@ -1010,10 +1006,10 @@ return true; } - private class DuplicateMapper extends MemoryMapNode { + private class DuplicateMapper implements MemoryMap { private final Map duplicates; - @Input private StartNode replaceeStart; + private StartNode replaceeStart; public DuplicateMapper(Map duplicates, StartNode replaceeStart) { this.duplicates = duplicates; @@ -1033,14 +1029,9 @@ } @Override - public Set getLocations() { + public Collection getLocations() { return memoryMap.getLocations(); } - - @Override - public boolean replaceLastLocationAccess(MemoryNode oldNode, MemoryNode newNode) { - throw GraalInternalError.shouldNotReachHere(); - } } /** @@ -1134,7 +1125,7 @@ if (returnNode != null && !(replacee instanceof ControlSinkNode)) { ReturnNode returnDuplicate = (ReturnNode) duplicates.get(returnNode); returnValue = returnDuplicate.result(); - MemoryMapNode mmap = new DuplicateMapper(duplicates, replaceeGraph.start()); + MemoryMap mmap = new DuplicateMapper(duplicates, replaceeGraph.start()); if (returnValue == null && replacee.usages().isNotEmpty() && replacee instanceof MemoryCheckpoint) { replacer.replace(replacee, null, mmap); } else {