# HG changeset patch # User Thomas Wuerthinger # Date 1308918072 -7200 # Node ID 6202a6bb6726188994a51a2efa3472d228951c31 # Parent ea778c37bdae800ddbc5ca82dfcca8c4de96828d Restructure memory lowering code. diff -r ea778c37bdae -r 6202a6bb6726 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Thu Jun 23 16:40:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Fri Jun 24 14:21:12 2011 +0200 @@ -101,6 +101,7 @@ public static boolean TraceAssembler = ____; public static boolean TraceInlining = ____; public static boolean TraceDeadCodeElimination = ____; + public static boolean TraceMemoryMaps = ____; public static int TraceBytecodeParserLevel = 0; public static boolean QuietBailout = ____; diff -r ea778c37bdae -r 6202a6bb6726 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Thu Jun 23 16:40:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Fri Jun 24 14:21:12 2011 +0200 @@ -1372,7 +1372,9 @@ } LIRGeneratorOp op = instr.lookup(LIRGeneratorOp.class); - op.generate(instr, this); + if (op != null) { + op.generate(instr, this); + } if (GraalOptions.TraceLIRVisit) { TTY.println("Operand for " + instr + " = " + instr.operand()); @@ -1443,14 +1445,14 @@ } @Override - public void visitMemoryRead(MemoryRead memRead) { - lir.move(new CiAddress(memRead.valueKind(), load(memRead.location()), memRead.displacement()), createResultVariable(memRead), memRead.valueKind()); + public void visitMemoryRead(ReadNode memRead) { + lir.move(memRead.location().createAddress(this, memRead.object()), createResultVariable(memRead), memRead.valueKind()); } @Override public void visitMemoryWrite(MemoryWrite memWrite) { - lir.move(load(memWrite.value()), new CiAddress(memWrite.valueKind(), load(memWrite.location()), memWrite.displacement()), memWrite.valueKind()); + lir.move(load(memWrite.value()), memWrite.location().createAddress(this, memWrite.object()), memWrite.valueKind()); } diff -r ea778c37bdae -r 6202a6bb6726 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/PhiSimplifier.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/PhiSimplifier.java Thu Jun 23 16:40:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/PhiSimplifier.java Fri Jun 24 14:21:12 2011 +0200 @@ -51,7 +51,9 @@ Phi phi = (Phi) x; if (phi.valueCount() == 1 && !cannotSimplify.isMarked(phi)) { - return (Value) phi.replace(phi.valueAt(0)); + Value result = phi.valueAt(0); + phi.replace(result); + return result; } if (cannotSimplify.isMarked(phi)) { diff -r ea778c37bdae -r 6202a6bb6726 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AbstractMemoryMergeNode.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/AbstractMemoryMergeNode.java Fri Jun 24 14:21:12 2011 +0200 @@ -0,0 +1,48 @@ +/* + * 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.compiler.gen.*; +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 ea778c37bdae -r 6202a6bb6726 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 Thu Jun 23 16:40:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessMonitor.java Fri Jun 24 14:21:12 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 StateSplit { +public abstract class AccessMonitor extends AbstractMemoryMergeNode { private static final int INPUT_COUNT = 2; private static final int INPUT_OBJECT = 0; diff -r ea778c37bdae -r 6202a6bb6726 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessNode.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/AccessNode.java Fri Jun 24 14:21:12 2011 +0200 @@ -0,0 +1,89 @@ +/* + * 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.debug.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public abstract class AccessNode extends StateSplit { + 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_MEMORY_STATE = 2; + + private static final int SUCCESSOR_COUNT = 0; + + private LocationNode location; + private CiKind valueKind; + + @Override + protected int inputCount() { + return super.inputCount() + INPUT_COUNT; + } + + public Value object() { + return (Value) inputs().get(super.inputCount() + INPUT_NODE); + } + + public Value setObject(Value n) { + return (Value) inputs().set(super.inputCount() + INPUT_NODE, n); + } + + public GuardNode guard() { + return (GuardNode) inputs().get(super.inputCount() + INPUT_GUARD); + } + + public void setGuard(GuardNode n) { + inputs().set(super.inputCount() + INPUT_GUARD, n); + } + + public GuardNode memoryState() { + return (GuardNode) inputs().get(super.inputCount() + INPUT_MEMORY_STATE); + } + + public void setMemoryState(GuardNode n) { + inputs().set(super.inputCount() + INPUT_MEMORY_STATE, n); + } + + public LocationNode location() { + return location; + } + + public CiKind valueKind() { + return valueKind; + } + + public AccessNode(CiKind kind, Value object, LocationNode location, int inputCount, int successorCount, Graph graph) { + super(kind.stackKind(), INPUT_COUNT + inputCount, SUCCESSOR_COUNT + successorCount, graph); + this.location = location; + this.valueKind = kind; + setObject(object); + } + + @Override + public void print(LogStream out) { + out.print("mem read from ").print(object()); + } +} diff -r ea778c37bdae -r 6202a6bb6726 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 Thu Jun 23 16:40:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java Fri Jun 24 14:21:12 2011 +0200 @@ -34,7 +34,7 @@ /** * The {@code Invoke} instruction represents all kinds of method calls. */ -public final class Invoke extends StateSplit implements ExceptionEdgeInstruction { +public final class Invoke extends AbstractMemoryMergeNode implements ExceptionEdgeInstruction { private final int argumentCount; diff -r ea778c37bdae -r 6202a6bb6726 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.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/LocationNode.java Fri Jun 24 14:21:12 2011 +0200 @@ -0,0 +1,67 @@ +/* + * 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.debug.*; +import com.oracle.max.graal.compiler.gen.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public final class LocationNode extends FloatingNode { + private static final int INPUT_COUNT = 0; + private static final int SUCCESSOR_COUNT = 0; + + private int displacement; + private CiKind valueKind; + private Object identity; + + 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; + } + + @Override + public T lookup(Class clazz) { + if (clazz == LIRGenerator.LIRGeneratorOp.class) { + return null; + } + return super.lookup(clazz); + } + + @Override + public void print(LogStream out) { + out.print("mem location disp is ").print(displacement); + } + + @Override + public Node copy(Graph into) { + return new LocationNode(identity, valueKind, displacement, into); + } + + public CiValue createAddress(LIRGenerator lirGenerator, Value object) { + return new CiAddress(valueKind, lirGenerator.load(object), displacement); + } +} diff -r ea778c37bdae -r 6202a6bb6726 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryAccess.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryAccess.java Thu Jun 23 16:40:53 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +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.debug.*; -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; - - -public abstract class MemoryAccess extends StateSplit { - private static final int INPUT_COUNT = 2; - private static final int INPUT_NODE = 0; - private static final int INPUT_GUARD = 1; - - private static final int SUCCESSOR_COUNT = 0; - - private int displacement; - private CiKind valueKind; - - @Override - protected int inputCount() { - return super.inputCount() + INPUT_COUNT; - } - - /** - * The instruction that produces the object tested against null. - */ - public Value location() { - return (Value) inputs().get(super.inputCount() + INPUT_NODE); - } - - public Value setLocation(Value n) { - return (Value) inputs().set(super.inputCount() + INPUT_NODE, n); - } - - /** - * The instruction that produces the object tested against null. - */ - public GuardNode guard() { - return (GuardNode) inputs().get(super.inputCount() + INPUT_GUARD); - } - - public void setGuard(GuardNode n) { - inputs().set(super.inputCount() + INPUT_GUARD, n); - } - - public int displacement() { - return displacement; - } - - public CiKind valueKind() { - return valueKind; - } - - public MemoryAccess(CiKind kind, Value location, int displacement, int inputCount, int successorCount, Graph graph) { - super(kind.stackKind(), INPUT_COUNT + inputCount, SUCCESSOR_COUNT + successorCount, graph); - this.displacement = displacement; - this.valueKind = kind; - setLocation(location); - } - - @Override - public void print(LogStream out) { - out.print("mem read from ").print(location()); - } -} diff -r ea778c37bdae -r 6202a6bb6726 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryMergeNode.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/MemoryMergeNode.java Fri Jun 24 14:21:12 2011 +0200 @@ -0,0 +1,57 @@ +/* + * 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.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 ea778c37bdae -r 6202a6bb6726 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryRead.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryRead.java Thu Jun 23 16:40:53 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +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.debug.*; -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; - - -public final class MemoryRead extends MemoryAccess { - private static final int INPUT_COUNT = 0; - private static final int SUCCESSOR_COUNT = 0; - - - public MemoryRead(CiKind kind, Value location, int displacement, Graph graph) { - super(kind, location, displacement, INPUT_COUNT, SUCCESSOR_COUNT, graph); - } - - @Override - public void accept(ValueVisitor v) { - v.visitMemoryRead(this); - } - - @Override - public void print(LogStream out) { - out.print("mem read from ").print(location()); - } - - @Override - public Node copy(Graph into) { - return new MemoryRead(super.kind, null, displacement(), into); - } -} diff -r ea778c37bdae -r 6202a6bb6726 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryWrite.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryWrite.java Thu Jun 23 16:40:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryWrite.java Fri Jun 24 14:21:12 2011 +0200 @@ -25,9 +25,10 @@ import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; +import com.sun.cri.ri.*; -public final class MemoryWrite extends MemoryAccess { +public final class MemoryWrite extends AccessNode { private static final int INPUT_COUNT = 1; private static final int INPUT_VALUE = 0; private static final int SUCCESSOR_COUNT = 0; @@ -45,8 +46,8 @@ inputs().set(super.inputCount() + INPUT_VALUE, v); } - public MemoryWrite(CiKind kind, Value object, Value value, int displacement, Graph graph) { - super(kind, object, displacement, INPUT_COUNT, SUCCESSOR_COUNT, graph); + public MemoryWrite(CiKind kind, Value object, Value value, LocationNode location, Graph graph) { + super(kind, object, location, INPUT_COUNT, SUCCESSOR_COUNT, graph); setValue(value); } @@ -57,11 +58,11 @@ @Override public void print(LogStream out) { - out.print("mem write to ").print(location()).print(" with value").print(value()); + out.print("mem write to ").print(object()).print(" with value").print(value()); } @Override public Node copy(Graph into) { - return new MemoryWrite(super.kind, null, null, displacement(), into); + return new MemoryWrite(super.kind, null, null, null, into); } } diff -r ea778c37bdae -r 6202a6bb6726 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ReadNode.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/ReadNode.java Fri Jun 24 14:21:12 2011 +0200 @@ -0,0 +1,53 @@ +/* + * 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.debug.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public final class ReadNode extends AccessNode { + private static final int INPUT_COUNT = 0; + private static final int SUCCESSOR_COUNT = 0; + + + public ReadNode(CiKind kind, Value object, LocationNode location, Graph graph) { + super(kind, object, location, INPUT_COUNT, SUCCESSOR_COUNT, graph); + } + + @Override + public void accept(ValueVisitor v) { + v.visitMemoryRead(this); + } + + @Override + public void print(LogStream out) { + out.print("mem read from ").print(object()); + } + + @Override + public Node copy(Graph into) { + return new ReadNode(super.kind, null, null, into); + } +} diff -r ea778c37bdae -r 6202a6bb6726 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Value.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Value.java Thu Jun 23 16:40:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Value.java Fri Jun 24 14:21:12 2011 +0200 @@ -157,7 +157,9 @@ throw new IllegalStateException("No visit method for this node"); } - public abstract void print(LogStream out); + public void print(LogStream out) { + out.print(this.getClass().toString()); + } @SuppressWarnings("unchecked") @Override diff -r ea778c37bdae -r 6202a6bb6726 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java Thu Jun 23 16:40:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java Fri Jun 24 14:21:12 2011 +0200 @@ -51,7 +51,7 @@ public abstract void visitLocal(Local i); public abstract void visitLogic(Logic i); public abstract void visitLookupSwitch(LookupSwitch i); - public abstract void visitMemoryRead(MemoryRead i); + public abstract void visitMemoryRead(ReadNode i); public abstract void visitMemoryWrite(MemoryWrite i); public abstract void visitMonitorAddress(MonitorAddress monitorAddress); public abstract void visitMonitorEnter(MonitorEnter i); diff -r ea778c37bdae -r 6202a6bb6726 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java Thu Jun 23 16:40:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java Fri Jun 24 14:21:12 2011 +0200 @@ -22,6 +22,11 @@ */ package com.oracle.max.graal.compiler.phases; +import java.util.*; +import java.util.Map.Entry; + +import com.oracle.max.graal.compiler.*; +import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.ir.*; import com.oracle.max.graal.compiler.schedule.*; import com.oracle.max.graal.graph.*; @@ -32,84 +37,201 @@ public static final LoweringOp DELEGATE_TO_RUNTIME = new LoweringOp() { @Override - public Node lower(Node n, CiLoweringTool tool) { - return tool.getRuntime().lower(n, tool); + public void lower(Node n, CiLoweringTool tool) { + tool.getRuntime().lower(n, tool); } }; private final RiRuntime runtime; + private Graph currentGraph; public LoweringPhase(RiRuntime runtime) { this.runtime = runtime; } + public static class MemoryMap { + + private final Block block; + private HashMap locationToWrite; + private HashMap> locationToReads; + + public MemoryMap(Block b, MemoryMap memoryMap) { + this(b); + } + + public MemoryMap(Block b) { + block = b; + locationToWrite = new HashMap(); + locationToReads = new HashMap>(); + if (GraalOptions.TraceMemoryMaps) { + TTY.println("Creating new memory map for block B" + b.blockID()); + } + } + + public void mergeWith(MemoryMap memoryMap) { + if (GraalOptions.TraceMemoryMaps) { + TTY.println("Merging with memory map of block B" + memoryMap.block.blockID()); + } + } + + public void createMemoryMerge(AbstractMemoryMergeNode memMerge) { + if (GraalOptions.TraceMemoryMaps) { + TTY.println("Creating memory merge at node " + memMerge.id()); + } + + for (Entry writeEntry : locationToWrite.entrySet()) { + memMerge.mergedNodes().add(writeEntry.getValue()); + } + + TTY.println("entrySet size" + locationToReads.entrySet()); + for (Entry> readEntry : locationToReads.entrySet()) { + TTY.println(readEntry.getValue().toString()); + memMerge.mergedNodes().addAll(readEntry.getValue()); + } + + locationToReads.clear(); + locationToWrite.clear(); + } + + public void registerWrite(Object location, Node node) { + 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); + } + + if (locationToReads.containsKey(location)) { + for (Node prevRead : locationToReads.get(location)) { + node.inputs().add(prevRead); + } + } + locationToWrite.put(location, node); + locationToReads.remove(location); + } + + public void registerRead(Object location, Node node) { + if (GraalOptions.TraceMemoryMaps) { + TTY.println("Register read to " + location + " at node " + node.id()); + } + + if (locationToWrite.containsKey(location)) { + Node prevWrite = locationToWrite.get(location); + node.inputs().add(prevWrite); + } + + if (!locationToReads.containsKey(location)) { + locationToReads.put(location, new ArrayList()); + } + locationToReads.get(location).add(node); + TTY.println("entrySet size" + locationToReads.entrySet()); + } + + public Node getMemoryState(Object location) { + return null; + } + } + @Override protected void run(final Graph graph) { + this.currentGraph = graph; final IdentifyBlocksPhase s = new IdentifyBlocksPhase(false); s.apply(graph); - for (Block b : s.getBlocks()) { - final Node[] firstNodeValue = new Node[]{b.firstNode()}; + List blocks = s.getBlocks(); + MemoryMap[] memoryMaps = new MemoryMap[blocks.size()]; + for (final Block b : blocks) { + process(b, memoryMaps); + } + } + + private void process(final Block b, MemoryMap[] memoryMaps) { + // Visit every block at most once. + if (memoryMaps[b.blockID()] != null) { + return; + } + + // Process predecessors before this block. + for (Block pred : b.getPredecessors()) { + process(pred, memoryMaps); + } - final CiLoweringTool loweringTool = new CiLoweringTool() { - @Override - public Node getGuardAnchor() { - Node firstNode = firstNodeValue[0]; - if (firstNode == firstNode.graph().start()) { - Anchor a = new Anchor(graph); - a.setNext((FixedNode) firstNode.graph().start().start()); - firstNode.graph().start().setStart(a); - firstNodeValue[0] = a; - return a; - } else if (firstNode instanceof Merge) { - Merge merge = (Merge) firstNode; - Anchor a = new Anchor(graph); - a.setNext(merge.next()); - merge.setNext(a); - firstNodeValue[0] = a; - return a; - } else if (!(firstNode instanceof Anchor)) { - Anchor a = new Anchor(graph); - assert firstNode.predecessors().size() == 1 : firstNode; - Node pred = firstNode.predecessors().get(0); - int predIndex = pred.successors().indexOf(firstNode); - pred.successors().set(predIndex, a); - a.setNext((FixedNode) firstNode); - firstNodeValue[0] = a; - return a; + // Create initial memory map for the block. + MemoryMap map = null; + if (b.getPredecessors().size() == 0) { + map = new MemoryMap(b); + } else { + map = new MemoryMap(b, memoryMaps[b.getPredecessors().get(0).blockID()]); + for (int i=1; i create a memory merge nevertheless. + if (n instanceof AbstractMemoryMergeNode) { + loweringTool.createMemoryMerge(n); } } } @@ -117,6 +239,6 @@ } public interface LoweringOp extends Op { - Node lower(Node n, CiLoweringTool tool); + void lower(Node n, CiLoweringTool tool); } } diff -r ea778c37bdae -r 6202a6bb6726 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java Thu Jun 23 16:40:53 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java Fri Jun 24 14:21:12 2011 +0200 @@ -37,6 +37,7 @@ private Block dominator; private Block javaBlock; private final List dominators = new ArrayList(); + private Anchor anchor; private Node firstNode; private Node lastNode; @@ -47,6 +48,7 @@ public void setFirstNode(Node node) { this.firstNode = node; + this.anchor = null; } public Block javaBlock() { @@ -61,6 +63,44 @@ return lastNode; } + public Anchor createAnchor() { + if (anchor == null) { + if (firstNode instanceof Anchor) { + this.anchor = (Anchor) firstNode; + } else if (firstNode == firstNode.graph().start()) { + StartNode start = (StartNode) firstNode; + if (start.start() instanceof Anchor) { + this.anchor = (Anchor) start.start(); + } else { + Anchor a = new Anchor(firstNode.graph()); + a.setNext((FixedNode) firstNode.graph().start().start()); + firstNode.graph().start().setStart(a); + this.anchor = a; + } + } else if (firstNode instanceof Merge) { + Merge merge = (Merge) firstNode; + if (merge.next() instanceof Anchor) { + this.anchor = (Anchor) merge.next(); + } else { + Anchor a = new Anchor(firstNode.graph()); + a.setNext(merge.next()); + merge.setNext(a); + this.anchor = a; + } + } else { + assert !(firstNode instanceof Anchor); + Anchor a = new Anchor(firstNode.graph()); + assert firstNode.predecessors().size() == 1 : firstNode; + Node pred = firstNode.predecessors().get(0); + int predIndex = pred.successors().indexOf(firstNode); + pred.successors().set(predIndex, a); + a.setNext((FixedNode) firstNode); + this.anchor = a; + } + } + return anchor; + } + public void setLastNode(Node node) { this.lastNode = node; } diff -r ea778c37bdae -r 6202a6bb6726 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java Thu Jun 23 16:40:53 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java Fri Jun 24 14:21:12 2011 +0200 @@ -242,29 +242,34 @@ } @Override - public Node lower(Node n, CiLoweringTool tool) { + public void lower(Node n, CiLoweringTool tool) { if (n instanceof LoadField) { LoadField field = (LoadField) n; if (field.isVolatile()) { - return null; + return; } Graph graph = field.graph(); int displacement = ((HotSpotField) field.field()).offset(); assert field.kind != CiKind.Illegal; - MemoryRead memoryRead = new MemoryRead(field.field().kind(), field.object(), displacement, graph); + ReadNode memoryRead = new ReadNode(field.field().kind(), field.object(), new LocationNode(field.field(), field.field().kind(), displacement, graph), graph); memoryRead.setGuard((GuardNode) tool.createGuard(new IsNonNull(field.object(), graph))); memoryRead.setNext(field.next()); - return memoryRead; + field.replace(memoryRead); } else if (n instanceof StoreField) { StoreField field = (StoreField) n; if (field.isVolatile()) { - return null; + return; } Graph graph = field.graph(); int displacement = ((HotSpotField) field.field()).offset(); - MemoryWrite memoryWrite = new MemoryWrite(field.field().kind(), field.object(), field.value(), displacement, graph); + MemoryWrite memoryWrite = new MemoryWrite(field.field().kind(), field.object(), field.value(), new LocationNode(field.field(), field.field().kind(), displacement, graph), graph); + memoryWrite.setGuard((GuardNode) tool.createGuard(new IsNonNull(field.object(), graph))); memoryWrite.setStateAfter(field.stateAfter()); - memoryWrite.setGuard((GuardNode) tool.createGuard(new IsNonNull(field.object(), graph))); + memoryWrite.setNext(field.next()); + + //MemoryMergeNode memoryMergeNode = new MemoryMergeNode(graph); + //memoryMergeNode.setStateAfter(field.stateAfter()); + //tool.createMemoryMerge(memoryMergeNode); if (field.field().kind() == CiKind.Object && !field.value().isNullConstant()) { FieldWriteBarrier writeBarrier = new FieldWriteBarrier(field.object(), graph); memoryWrite.setNext(writeBarrier); @@ -272,8 +277,7 @@ } else { memoryWrite.setNext(field.next()); } - return memoryWrite; + field.replace(memoryWrite); } - return null; } }