# HG changeset patch # User Thomas Wuerthinger # Date 1308922794 -7200 # Node ID 45ba159b4bd1d6d36dc4ec7d0e6e06c060f6bdb5 # Parent 33da84ebbe50b39409580f457289aabbd13c9f19 Added memory dependencies. diff -r 33da84ebbe50 -r 45ba159b4bd1 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AbstractMemoryCheckpointNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AbstractMemoryCheckpointNode.java Fri Jun 24 15:39:54 2011 +0200 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011, 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.max.graal.compiler.ir; + +import java.util.*; + +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public abstract class AbstractMemoryCheckpointNode extends StateSplit { + + private static final int SUCCESSOR_COUNT = 0; + private static final int INPUT_COUNT = 0; + + public AbstractMemoryCheckpointNode(Graph graph) { + this(CiKind.Illegal, 0, 0, graph); + } + + public AbstractMemoryCheckpointNode(CiKind result, int inputCount, int successorCount, Graph graph) { + super(result, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph); + } + + public List mergedNodes() { + return inputs().variablePart(); + } +} diff -r 33da84ebbe50 -r 45ba159b4bd1 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AbstractMemoryMergeNode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AbstractMemoryMergeNode.java Fri Jun 24 15:01:20 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2011, 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.max.graal.compiler.ir; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; - - -public abstract class AbstractMemoryMergeNode extends StateSplit { - - private static final int SUCCESSOR_COUNT = 0; - private static final int INPUT_COUNT = 0; - - public AbstractMemoryMergeNode(Graph graph) { - this(CiKind.Illegal, 0, 0, graph); - } - - public AbstractMemoryMergeNode(CiKind result, int inputCount, int successorCount, Graph graph) { - super(result, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph); - } - - public List mergedNodes() { - return inputs().variablePart(); - } -} diff -r 33da84ebbe50 -r 45ba159b4bd1 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessMonitor.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessMonitor.java Fri Jun 24 15:01:20 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessMonitor.java Fri Jun 24 15:39:54 2011 +0200 @@ -28,7 +28,7 @@ /** * The {@code AccessMonitor} instruction is the base class of both monitor acquisition and release. */ -public abstract class AccessMonitor extends AbstractMemoryMergeNode { +public abstract class AccessMonitor extends AbstractMemoryCheckpointNode { private static final int INPUT_COUNT = 2; private static final int INPUT_OBJECT = 0; diff -r 33da84ebbe50 -r 45ba159b4bd1 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessNode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessNode.java Fri Jun 24 15:01:20 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessNode.java Fri Jun 24 15:39:54 2011 +0200 @@ -28,9 +28,10 @@ public abstract class AccessNode extends StateSplit { - private static final int INPUT_COUNT = 2; + private static final int INPUT_COUNT = 3; private static final int INPUT_NODE = 0; - private static final int INPUT_GUARD = 1; + private static final int INPUT_LOCATION = 1; + private static final int INPUT_GUARD = 2; private static final int SUCCESSOR_COUNT = 0; @@ -58,12 +59,16 @@ } public LocationNode location() { - return location; + return (LocationNode) inputs().get(super.inputCount() + INPUT_LOCATION); + } + + public void setLocation(LocationNode n) { + inputs().set(super.inputCount() + INPUT_LOCATION, n); } public AccessNode(CiKind kind, Value object, LocationNode location, int inputCount, int successorCount, Graph graph) { super(kind, INPUT_COUNT + inputCount, SUCCESSOR_COUNT + successorCount, graph); - this.location = location; + setLocation(location); setObject(object); } diff -r 33da84ebbe50 -r 45ba159b4bd1 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java Fri Jun 24 15:01:20 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java Fri Jun 24 15:39:54 2011 +0200 @@ -34,7 +34,7 @@ /** * The {@code Invoke} instruction represents all kinds of method calls. */ -public final class Invoke extends AbstractMemoryMergeNode implements ExceptionEdgeInstruction { +public final class Invoke extends AbstractMemoryCheckpointNode implements ExceptionEdgeInstruction { private final int argumentCount; diff -r 33da84ebbe50 -r 45ba159b4bd1 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java Fri Jun 24 15:01:20 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java Fri Jun 24 15:39:54 2011 +0200 @@ -34,13 +34,13 @@ private int displacement; private CiKind valueKind; - private Object identity; + private Object locationIdentity; public LocationNode(Object identity, CiKind kind, int displacement, Graph graph) { super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph); this.displacement = displacement; this.valueKind = kind; - this.identity = identity; + this.locationIdentity = identity; } @Override @@ -62,10 +62,14 @@ @Override public Node copy(Graph into) { - return new LocationNode(identity, valueKind, displacement, into); + return new LocationNode(locationIdentity, valueKind, displacement, into); } public CiValue createAddress(LIRGenerator lirGenerator, Value object) { return new CiAddress(valueKind, lirGenerator.load(object), displacement); } + + public Object locationIdentity() { + return locationIdentity; + } } diff -r 33da84ebbe50 -r 45ba159b4bd1 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryCheckpointNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryCheckpointNode.java Fri Jun 24 15:39:54 2011 +0200 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011, 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.max.graal.compiler.ir; + +import com.oracle.max.graal.compiler.gen.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public final class MemoryCheckpointNode extends AbstractMemoryCheckpointNode { + + private static final int SUCCESSOR_COUNT = 0; + private static final int INPUT_COUNT = 0; + + public MemoryCheckpointNode(Graph graph) { + this(CiKind.Illegal, 0, 0, graph); + } + + public MemoryCheckpointNode(CiKind result, int inputCount, int successorCount, Graph graph) { + super(result, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph); + } + + @Override + public T lookup(Class clazz) { + if (clazz == LIRGenerator.LIRGeneratorOp.class) { + return null; + } + return super.lookup(clazz); + } + + @Override + public Node copy(Graph into) { + return new MemoryCheckpointNode(into); + } +} diff -r 33da84ebbe50 -r 45ba159b4bd1 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryMergeNode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryMergeNode.java Fri Jun 24 15:01:20 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2011, 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.max.graal.compiler.ir; - -import com.oracle.max.graal.compiler.gen.*; -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; - - -public final class MemoryMergeNode extends AbstractMemoryMergeNode { - - private static final int SUCCESSOR_COUNT = 0; - private static final int INPUT_COUNT = 0; - - public MemoryMergeNode(Graph graph) { - this(CiKind.Illegal, 0, 0, graph); - } - - public MemoryMergeNode(CiKind result, int inputCount, int successorCount, Graph graph) { - super(result, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph); - } - - @Override - public T lookup(Class clazz) { - if (clazz == LIRGenerator.LIRGeneratorOp.class) { - return null; - } - return super.lookup(clazz); - } - - @Override - public Node copy(Graph into) { - return new MemoryMergeNode(into); - } -} diff -r 33da84ebbe50 -r 45ba159b4bd1 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/MemoryPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/MemoryPhase.java Fri Jun 24 15:01:20 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/MemoryPhase.java Fri Jun 24 15:39:54 2011 +0200 @@ -38,6 +38,8 @@ private final Block block; private HashMap locationToWrite; private HashMap> locationToReads; + private Node lastReadWriteMerge; + private Node lastWriteMerge; public MemoryMap(Block b, MemoryMap memoryMap) { this(b); @@ -50,6 +52,9 @@ if (GraalOptions.TraceMemoryMaps) { TTY.println("Creating new memory map for block B" + b.blockID()); } + assert b.firstNode() == b.firstNode().graph().start(); + lastReadWriteMerge = b.firstNode(); + lastWriteMerge = b.firstNode(); } public void mergeWith(MemoryMap memoryMap) { @@ -58,57 +63,94 @@ } } - public void createMemoryMerge(AbstractMemoryMergeNode memMerge) { + public void createWriteMemoryMerge(AbstractMemoryCheckpointNode memMerge) { if (GraalOptions.TraceMemoryMaps) { - TTY.println("Creating memory merge at node " + memMerge.id()); + TTY.println("Creating write memory checkpoint at node " + memMerge.id()); } + // Merge in all writes. + for (Entry writeEntry : locationToWrite.entrySet()) { + memMerge.mergedNodes().add(writeEntry.getValue()); + + // Register the merge point as a read such that subsequent writes to this location will depend on it (but subsequent reads do not). + addRead(memMerge, writeEntry.getKey()); + } + lastWriteMerge = memMerge; + } + + public void createReadWriteMemoryCheckpoint(AbstractMemoryCheckpointNode memMerge) { + if (GraalOptions.TraceMemoryMaps) { + TTY.println("Creating readwrite memory checkpoint at node " + memMerge.id()); + } + + // Merge in all writes. for (Entry writeEntry : locationToWrite.entrySet()) { memMerge.mergedNodes().add(writeEntry.getValue()); } + locationToWrite.clear(); + // Merge in all reads. for (Entry> readEntry : locationToReads.entrySet()) { memMerge.mergedNodes().addAll(readEntry.getValue()); } - locationToReads.clear(); - locationToWrite.clear(); + lastWriteMerge = memMerge; + lastReadWriteMerge = memMerge; } - public void registerWrite(Object location, Node node) { + public void registerWrite(WriteNode node) { + Object location = node.location().locationIdentity(); if (GraalOptions.TraceMemoryMaps) { TTY.println("Register write to " + location + " at node " + node.id()); } - if (locationToWrite.containsKey(location)) { - Node prevWrite = locationToWrite.get(location); - node.inputs().add(prevWrite); - } - + boolean connectionAdded = false; if (locationToReads.containsKey(location)) { for (Node prevRead : locationToReads.get(location)) { node.inputs().add(prevRead); + connectionAdded = true; } } + + if (!connectionAdded) { + if (locationToWrite.containsKey(location)) { + Node prevWrite = locationToWrite.get(location); + node.inputs().variablePart().add(prevWrite); + connectionAdded = true; + } + } + + node.inputs().variablePart().add(lastWriteMerge); + locationToWrite.put(location, node); locationToReads.remove(location); } - public void registerRead(Object location, Node node) { + public void registerRead(ReadNode node) { + Object location = node.location().locationIdentity(); if (GraalOptions.TraceMemoryMaps) { TTY.println("Register read to " + location + " at node " + node.id()); } + boolean connectionAdded = false; if (locationToWrite.containsKey(location)) { Node prevWrite = locationToWrite.get(location); - node.inputs().add(prevWrite); + node.inputs().variablePart().add(prevWrite); + connectionAdded = true; } + if (!connectionAdded) { + node.inputs().variablePart().add(lastReadWriteMerge); + } + + addRead(node, location); + } + + private void addRead(Node node, Object location) { if (!locationToReads.containsKey(location)) { locationToReads.put(location, new ArrayList()); } locationToReads.get(location).add(node); - TTY.println("entrySet size" + locationToReads.entrySet()); } } @@ -149,14 +191,23 @@ // Lower the instructions of this block. for (final Node n : b.getInstructions()) { // This memory merge node is not lowered => create a memory merge nevertheless. - if (n instanceof AbstractMemoryMergeNode) { - map.createMemoryMerge((AbstractMemoryMergeNode) n); + if (n instanceof AbstractMemoryCheckpointNode) { + map.createReadWriteMemoryCheckpoint((AbstractMemoryCheckpointNode) n); } else if (n instanceof ReadNode) { ReadNode readNode = (ReadNode) n; - + readNode.replaceAtPredecessors(readNode.next()); + readNode.setNext(null); + map.registerRead(readNode); } else if (n instanceof WriteNode) { WriteNode writeNode = (WriteNode) n; - + MemoryCheckpointNode checkpoint = new MemoryCheckpointNode(writeNode.graph()); + checkpoint.setStateAfter(writeNode.stateAfter()); + writeNode.setStateAfter(null); + checkpoint.setNext(writeNode.next()); + writeNode.setNext(null); + writeNode.replaceAtPredecessors(checkpoint); + map.registerWrite(writeNode); + map.createWriteMemoryMerge(checkpoint); } }