changeset 2827:bd17ac598c6e

Graph cloning, initial version (not completely working)
author Lukas Stadler <lukas.stadler@jku.at>
date Mon, 30 May 2011 18:46:57 +0200
parents 015be60afcf3
children d6f3dbb4e3b5
files graal/GraalCompiler/src/com/sun/c1x/C1XCompilation.java graal/GraalCompiler/src/com/sun/c1x/graph/IR.java graal/GraalCompiler/src/com/sun/c1x/ir/AccessField.java graal/GraalCompiler/src/com/sun/c1x/ir/AccessIndexed.java graal/GraalCompiler/src/com/sun/c1x/ir/Anchor.java graal/GraalCompiler/src/com/sun/c1x/ir/ArithmeticOp.java graal/GraalCompiler/src/com/sun/c1x/ir/ArrayLength.java graal/GraalCompiler/src/com/sun/c1x/ir/CheckCast.java graal/GraalCompiler/src/com/sun/c1x/ir/CompareOp.java graal/GraalCompiler/src/com/sun/c1x/ir/Constant.java graal/GraalCompiler/src/com/sun/c1x/ir/Convert.java graal/GraalCompiler/src/com/sun/c1x/ir/Deoptimize.java graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionDispatch.java graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionObject.java graal/GraalCompiler/src/com/sun/c1x/ir/If.java graal/GraalCompiler/src/com/sun/c1x/ir/IfOp.java graal/GraalCompiler/src/com/sun/c1x/ir/InstanceOf.java graal/GraalCompiler/src/com/sun/c1x/ir/Invoke.java graal/GraalCompiler/src/com/sun/c1x/ir/LoadField.java graal/GraalCompiler/src/com/sun/c1x/ir/LoadIndexed.java graal/GraalCompiler/src/com/sun/c1x/ir/Local.java graal/GraalCompiler/src/com/sun/c1x/ir/LogicOp.java graal/GraalCompiler/src/com/sun/c1x/ir/LookupSwitch.java graal/GraalCompiler/src/com/sun/c1x/ir/LoopBegin.java graal/GraalCompiler/src/com/sun/c1x/ir/LoopEnd.java graal/GraalCompiler/src/com/sun/c1x/ir/Merge.java graal/GraalCompiler/src/com/sun/c1x/ir/MonitorAddress.java graal/GraalCompiler/src/com/sun/c1x/ir/MonitorEnter.java graal/GraalCompiler/src/com/sun/c1x/ir/MonitorExit.java graal/GraalCompiler/src/com/sun/c1x/ir/NegateOp.java graal/GraalCompiler/src/com/sun/c1x/ir/NewInstance.java graal/GraalCompiler/src/com/sun/c1x/ir/NewMultiArray.java graal/GraalCompiler/src/com/sun/c1x/ir/NewObjectArray.java graal/GraalCompiler/src/com/sun/c1x/ir/NewTypeArray.java graal/GraalCompiler/src/com/sun/c1x/ir/NullCheck.java graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java graal/GraalCompiler/src/com/sun/c1x/ir/Placeholder.java graal/GraalCompiler/src/com/sun/c1x/ir/RegisterFinalizer.java graal/GraalCompiler/src/com/sun/c1x/ir/Return.java graal/GraalCompiler/src/com/sun/c1x/ir/ShiftOp.java graal/GraalCompiler/src/com/sun/c1x/ir/StoreField.java graal/GraalCompiler/src/com/sun/c1x/ir/StoreIndexed.java graal/GraalCompiler/src/com/sun/c1x/ir/TableSwitch.java graal/GraalCompiler/src/com/sun/c1x/ir/Throw.java graal/GraalCompiler/src/com/sun/c1x/ir/Unwind.java graal/GraalCompiler/src/com/sun/c1x/ir/Value.java graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java graal/GraalGraph/src/com/oracle/graal/graph/Graph.java
diffstat 48 files changed, 387 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/sun/c1x/C1XCompilation.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/C1XCompilation.java	Mon May 30 18:46:57 2011 +0200
@@ -55,7 +55,7 @@
     public final CiAssumptions assumptions = new CiAssumptions();
     public final FrameState placeholderState;
 
-    public final Graph graph = new Graph();
+    public Graph graph = new Graph();
 
     private boolean hasExceptionHandlers;
     private final C1XCompilation parent;
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Mon May 30 18:46:57 2011 +0200
@@ -159,6 +159,15 @@
     private void buildGraph() {
         // Graph builder must set the startBlock and the osrEntryBlock
         new GraphBuilder(compilation, this, compilation.graph).build();
+
+//        Graph newGraph = new Graph();
+//        HashMap<Node, Node> replacement = new HashMap<Node, Node>();
+//        replacement.put(compilation.graph.start(), newGraph.start());
+//        replacement.put(compilation.graph.end(), newGraph.end());
+//        newGraph.addDuplicate(compilation.graph.getNodes(), replacement);
+//
+//        compilation.graph = newGraph;
+
         verifyAndPrint("After graph building");
 
         if (C1XOptions.PrintCompilation) {
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/AccessField.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/AccessField.java	Mon May 30 18:46:57 2011 +0200
@@ -73,7 +73,7 @@
      */
     public AccessField(CiKind kind, Value object, RiField field, int inputCount, int successorCount, Graph graph) {
         super(kind, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph);
-        assert object != null : "every field access must reference some object";
+//        assert object != null : "every field access must reference some object";
         this.field = field;
         setObject(object);
     }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/AccessIndexed.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/AccessIndexed.java	Mon May 30 18:46:57 2011 +0200
@@ -77,17 +77,17 @@
      * @param array the instruction producing the array
      * @param index the instruction producing the index
      * @param length the instruction producing the length (used in bounds check elimination?)
-     * @param elementType the type of the elements of the array
+     * @param elementKind the type of the elements of the array
      * @param stateBefore the state before executing this instruction
      * @param inputCount
      * @param successorCount
      * @param graph
      */
-    AccessIndexed(CiKind kind, Value array, Value index, Value length, CiKind elementType, int inputCount, int successorCount, Graph graph) {
+    AccessIndexed(CiKind kind, Value array, Value index, Value length, CiKind elementKind, int inputCount, int successorCount, Graph graph) {
         super(kind, array, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph);
         setIndex(index);
         setLength(length);
-        this.elementType = elementType;
+        this.elementType = elementKind;
     }
 
     /**
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Anchor.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Anchor.java	Mon May 30 18:46:57 2011 +0200
@@ -54,4 +54,11 @@
     public void print(LogStream out) {
         out.print("goto ").print(defaultSuccessor());
     }
+
+    @Override
+    public Node copy(Graph into) {
+        Anchor x = new Anchor(null, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/ArithmeticOp.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ArithmeticOp.java	Mon May 30 18:46:57 2011 +0200
@@ -79,4 +79,11 @@
     public String shortName() {
         return Bytecodes.operator(opcode);
     }
+
+    @Override
+    public Node copy(Graph into) {
+        ArithmeticOp x = new ArithmeticOp(opcode, kind, null, null, isStrictFP, canTrap, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/ArrayLength.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ArrayLength.java	Mon May 30 18:46:57 2011 +0200
@@ -92,4 +92,11 @@
     public void print(LogStream out) {
         out.print(array()).print(".length");
     }
+
+    @Override
+    public Node copy(Graph into) {
+        ArrayLength x = new ArrayLength(null, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/CheckCast.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/CheckCast.java	Mon May 30 18:46:57 2011 +0200
@@ -95,4 +95,11 @@
         print(") ").
         print(CiUtil.toJavaName(targetClass()));
     }
+
+    @Override
+    public Node copy(Graph into) {
+        CheckCast x = new CheckCast(targetClass, null, null, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/CompareOp.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/CompareOp.java	Mon May 30 18:46:57 2011 +0200
@@ -59,4 +59,11 @@
             print(' ').
             print(y());
     }
+
+    @Override
+    public Node copy(Graph into) {
+        CompareOp x = new CompareOp(opcode, kind, null, null, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Constant.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Constant.java	Mon May 30 18:46:57 2011 +0200
@@ -192,4 +192,10 @@
         return value.name();
     }
 
+    @Override
+    public Node copy(Graph into) {
+        Constant x = new Constant(value, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Convert.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Convert.java	Mon May 30 18:46:57 2011 +0200
@@ -100,4 +100,11 @@
     public void print(LogStream out) {
         out.print(Bytecodes.nameOf(opcode)).print('(').print(value()).print(')');
     }
+
+    @Override
+    public Node copy(Graph into) {
+        Convert x = new Convert(opcode, null, kind, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Deoptimize.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Deoptimize.java	Mon May 30 18:46:57 2011 +0200
@@ -60,4 +60,11 @@
         return "Deopt " + message;
     }
 
+    @Override
+    public Node copy(Graph into) {
+        Deoptimize x = new Deoptimize(into);
+        x.setMessage(message);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionDispatch.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionDispatch.java	Mon May 30 18:46:57 2011 +0200
@@ -125,5 +125,10 @@
         return "Dispatch " + catchType().name();
     }
 
-
+    @Override
+    public Node copy(Graph into) {
+        ExceptionDispatch x = new ExceptionDispatch(null, null, null, catchType, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionObject.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionObject.java	Mon May 30 18:46:57 2011 +0200
@@ -53,4 +53,11 @@
     public void print(LogStream out) {
         out.print("incoming exception");
     }
+
+    @Override
+    public Node copy(Graph into) {
+        ExceptionObject x = new ExceptionObject(into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/If.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/If.java	Mon May 30 18:46:57 2011 +0200
@@ -84,7 +84,7 @@
      */
     public If(Value x, Condition cond, Value y, Graph graph) {
         super(CiKind.Illegal, 2, INPUT_COUNT, SUCCESSOR_COUNT, graph);
-        assert Util.archKindsEqual(x, y);
+        assert (x == null && y == null) || Util.archKindsEqual(x, y);
         condition = cond;
         setX(x);
         setY(y);
@@ -187,5 +187,11 @@
         return "If " + condition.operator;
     }
 
-
+    @Override
+    public Node copy(Graph into) {
+        If x = new If(null, condition, null, into);
+        x.unorderedIsTrue = unorderedIsTrue;
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/IfOp.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/IfOp.java	Mon May 30 18:46:57 2011 +0200
@@ -26,6 +26,7 @@
 import com.sun.c1x.debug.*;
 import com.sun.c1x.util.*;
 import com.sun.cri.bytecode.*;
+import com.sun.cri.ci.*;
 
 /**
  * The {@code IfOp} class represents a comparison that yields one of two values.
@@ -74,7 +75,7 @@
     }
 
 
-    Condition cond;
+    Condition condition;
 
     /**
      * Constructs a new IfOp.
@@ -87,17 +88,22 @@
     public IfOp(Value x, Condition cond, Value y, Value trueValue, Value falseValue, Graph graph) {
         // TODO: return the appropriate bytecode IF_ICMPEQ, etc
         super(trueValue.kind.meet(falseValue.kind), Bytecodes.ILLEGAL, x, y, INPUT_COUNT, SUCCESSOR_COUNT, graph);
-        this.cond = cond;
+        this.condition = cond;
         setTrueValue(trueValue);
         setFalseValue(falseValue);
     }
 
+    private IfOp(CiKind kind, Condition cond, Graph graph) {
+        super(kind, Bytecodes.ILLEGAL, null, null, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        this.condition = cond;
+    }
+
     /**
      * Gets the condition of this if operation.
      * @return the condition
      */
     public Condition condition() {
-        return cond;
+        return condition;
     }
 
     /**
@@ -105,7 +111,7 @@
      * @return {@code true} if this comparison is commutative
      */
     public boolean isCommutative() {
-        return cond == Condition.EQ || cond == Condition.NE;
+        return condition == Condition.EQ || condition == Condition.NE;
     }
 
     @Override
@@ -115,7 +121,7 @@
 
     @Override
     public int valueNumber() {
-        return Util.hash4(cond.hashCode(), x(), y(), trueValue(), falseValue());
+        return Util.hash4(condition.hashCode(), x(), y(), trueValue(), falseValue());
     }
 
     @Override
@@ -139,4 +145,11 @@
         print(" : ").
         print(falseValue());
     }
+
+    @Override
+    public Node copy(Graph into) {
+        IfOp x = new IfOp(kind, condition, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/InstanceOf.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/InstanceOf.java	Mon May 30 18:46:57 2011 +0200
@@ -71,4 +71,11 @@
     public void print(LogStream out) {
         out.print("instanceof(").print(object()).print(") ").print(CiUtil.toJavaName(targetClass()));
     }
+
+    @Override
+    public Node copy(Graph into) {
+        InstanceOf x = new InstanceOf(targetClass, null, null, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Invoke.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Invoke.java	Mon May 30 18:46:57 2011 +0200
@@ -180,4 +180,11 @@
         }
         out.print(CiUtil.format(") [method: %H.%n(%p):%r]", target, false));
     }
+
+    @Override
+    public Node copy(Graph into) {
+        Invoke x = new Invoke(opcode, kind, new Value[argumentCount], target, returnType, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/LoadField.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/LoadField.java	Mon May 30 18:46:57 2011 +0200
@@ -88,4 +88,11 @@
     public boolean needsStateAfter() {
         return false;
     }
+
+    @Override
+    public Node copy(Graph into) {
+        LoadField x = new LoadField(null, field, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/LoadIndexed.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/LoadIndexed.java	Mon May 30 18:46:57 2011 +0200
@@ -85,4 +85,11 @@
     public boolean needsStateAfter() {
         return false;
     }
+
+    @Override
+    public Node copy(Graph into) {
+        LoadIndexed x = new LoadIndexed(null, null, null, kind, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Local.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Local.java	Mon May 30 18:46:57 2011 +0200
@@ -95,6 +95,7 @@
     public Node copy(Graph into) {
         Local x = new Local(kind, index, into);
         x.setDeclaredType(declaredType());
+        x.setNonNull(isNonNull());
         return x;
     }
 
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/LogicOp.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/LogicOp.java	Mon May 30 18:46:57 2011 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.graph.*;
 import com.sun.c1x.debug.*;
 import com.sun.cri.bytecode.*;
+import com.sun.cri.ci.*;
 
 /**
  * The {@code LogicOp} class definition.
@@ -44,6 +45,10 @@
         super(x.kind, opcode, x, y, INPUT_COUNT, SUCCESSOR_COUNT, graph);
     }
 
+    public LogicOp(CiKind kind, int opcode, Graph graph) {
+        super(kind, opcode, null, null, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+    }
+
     @Override
     public void accept(ValueVisitor v) {
         v.visitLogicOp(this);
@@ -53,4 +58,11 @@
     public void print(LogStream out) {
         out.print(x()).print(' ').print(Bytecodes.operator(opcode)).print(' ').print(y());
     }
+
+    @Override
+    public Node copy(Graph into) {
+        LogicOp x = new LogicOp(kind, opcode, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/LookupSwitch.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/LookupSwitch.java	Mon May 30 18:46:57 2011 +0200
@@ -83,4 +83,11 @@
         INSTRUCTION.advance(out);
         out.print("default   : ").print(defaultSuccessor());
     }
+
+    @Override
+    public Node copy(Graph into) {
+        LookupSwitch x = new LookupSwitch(null, Arrays.asList(new Instruction[numberOfCases() + 1]), keys.clone(), into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/LoopBegin.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/LoopBegin.java	Mon May 30 18:46:57 2011 +0200
@@ -57,4 +57,10 @@
         out.print("loopBegin");
     }
 
+    @Override
+    public Node copy(Graph into) {
+        LoopBegin x = new LoopBegin(into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/LoopEnd.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/LoopEnd.java	Mon May 30 18:46:57 2011 +0200
@@ -68,5 +68,10 @@
         out.print("loopEnd ").print(loopBegin());
     }
 
-
+    @Override
+    public Node copy(Graph into) {
+        LoopEnd x = new LoopEnd(into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Merge.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Merge.java	Mon May 30 18:46:57 2011 +0200
@@ -254,4 +254,12 @@
         }
         return sb.toString();
     }
+
+    @Override
+    public Node copy(Graph into) {
+        assert getClass() == Merge.class : "copy of " + getClass();
+        Merge x = new Merge(into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/MonitorAddress.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/MonitorAddress.java	Mon May 30 18:46:57 2011 +0200
@@ -55,4 +55,11 @@
     public void print(LogStream out) {
         out.print("monitor_address (").print(monitor()).print(")");
     }
+
+    @Override
+    public Node copy(Graph into) {
+        MonitorAddress x = new MonitorAddress(monitor, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/MonitorEnter.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/MonitorEnter.java	Mon May 30 18:46:57 2011 +0200
@@ -61,4 +61,11 @@
     public void print(LogStream out) {
         out.print("enter monitor[").print(lockNumber).print("](").print(object()).print(')');
     }
+
+    @Override
+    public Node copy(Graph into) {
+        MonitorEnter x = new MonitorEnter(null, null, lockNumber, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/MonitorExit.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/MonitorExit.java	Mon May 30 18:46:57 2011 +0200
@@ -55,4 +55,11 @@
     public void print(LogStream out) {
         out.print("exit monitor[").print(lockNumber).print("](").print(object()).print(')');
     }
+
+    @Override
+    public Node copy(Graph into) {
+        MonitorExit x = new MonitorExit(null, null, lockNumber, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/NegateOp.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/NegateOp.java	Mon May 30 18:46:57 2011 +0200
@@ -26,6 +26,7 @@
 import com.sun.c1x.debug.*;
 import com.sun.c1x.util.*;
 import com.sun.cri.bytecode.*;
+import com.sun.cri.ci.*;
 
 /**
  * The {@code NegateOp} instruction negates its operand.
@@ -68,6 +69,10 @@
         setX(x);
     }
 
+    private NegateOp(CiKind kind, Graph graph) {
+        super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+    }
+
     @Override
     public void accept(ValueVisitor v) {
         v.visitNegateOp(this);
@@ -91,4 +96,11 @@
     public void print(LogStream out) {
         out.print("- ").print(x());
     }
+
+    @Override
+    public Node copy(Graph into) {
+        NegateOp x = new NegateOp(kind, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/NewInstance.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/NewInstance.java	Mon May 30 18:46:57 2011 +0200
@@ -81,4 +81,11 @@
     public void print(LogStream out) {
         out.print("new instance ").print(CiUtil.toJavaName(instanceClass()));
     }
+
+    @Override
+    public Node copy(Graph into) {
+        NewInstance x = new NewInstance(instanceClass, cpi, constantPool, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/NewMultiArray.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/NewMultiArray.java	Mon May 30 18:46:57 2011 +0200
@@ -116,4 +116,11 @@
         }
         out.print("] ").print(CiUtil.toJavaName(elementKind));
     }
+
+    @Override
+    public Node copy(Graph into) {
+        NewMultiArray x = new NewMultiArray(elementKind, new Value[dimensionCount], cpi, constantPool, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/NewObjectArray.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/NewObjectArray.java	Mon May 30 18:46:57 2011 +0200
@@ -76,4 +76,11 @@
     public void print(LogStream out) {
         out.print("new object array [").print(length()).print("] ").print(CiUtil.toJavaName(elementClass()));
     }
+
+    @Override
+    public Node copy(Graph into) {
+        NewObjectArray x = new NewObjectArray(elementClass, null, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/NewTypeArray.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/NewTypeArray.java	Mon May 30 18:46:57 2011 +0200
@@ -65,4 +65,11 @@
     public void print(LogStream out) {
         out.print("new ").print(elementKind().name()).print(" array [").print(length()).print(']');
     }
+
+    @Override
+    public Node copy(Graph into) {
+        NewTypeArray x = new NewTypeArray(null, elementType, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/NullCheck.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/NullCheck.java	Mon May 30 18:46:57 2011 +0200
@@ -106,4 +106,11 @@
     public void print(LogStream out) {
         out.print("null_check(").print(object()).print(')');
     }
+
+    @Override
+    public Node copy(Graph into) {
+        NullCheck x = new NullCheck(null, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java	Mon May 30 18:46:57 2011 +0200
@@ -37,12 +37,19 @@
     private static final int INPUT_COUNT = 1;
     private static final int INPUT_BLOCK = 0;
 
+    private final int maxValues;
+
     private static final int SUCCESSOR_COUNT = 0;
 
     private int usedInputCount;
     private boolean isDead;
 
     @Override
+    protected int inputCount() {
+        return super.inputCount() + INPUT_COUNT + maxValues;
+    }
+
+    @Override
     protected int successorCount() {
         return super.successorCount() + SUCCESSOR_COUNT;
     }
@@ -62,7 +69,6 @@
      * Create a new Phi for the specified join block and local variable (or operand stack) slot.
      * @param kind the type of the variable
      * @param block the join point
-     * @param index the index into the stack (if < 0) or local variables
      * @param graph
      */
     public Phi(CiKind kind, Merge block, Graph graph) {
@@ -71,6 +77,7 @@
 
     public Phi(CiKind kind, Merge block, int maxValues, Graph graph) {
         super(kind, INPUT_COUNT + maxValues, SUCCESSOR_COUNT, graph);
+        this.maxValues = maxValues;
         usedInputCount = 1;
         setBlock(block);
     }
@@ -160,4 +167,13 @@
         }
         usedInputCount--;
     }
+
+    @Override
+    public Node copy(Graph into) {
+        Phi x = new Phi(kind, null, maxValues, into);
+        x.usedInputCount = usedInputCount;
+        x.isDead = isDead;
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Placeholder.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Placeholder.java	Mon May 30 18:46:57 2011 +0200
@@ -61,4 +61,11 @@
     public String shortName() {
         return "Placeholder" + id();
     }
+
+    @Override
+    public Node copy(Graph into) {
+        Placeholder x = new Placeholder(into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/RegisterFinalizer.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/RegisterFinalizer.java	Mon May 30 18:46:57 2011 +0200
@@ -73,4 +73,11 @@
     public void print(LogStream out) {
         out.print("register finalizer ").print(object());
     }
+
+    @Override
+    public Node copy(Graph into) {
+        RegisterFinalizer x = new RegisterFinalizer(null, null, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Return.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Return.java	Mon May 30 18:46:57 2011 +0200
@@ -88,4 +88,11 @@
             out.print(kind.typeChar).print("return ").print(result());
         }
     }
+
+    @Override
+    public Node copy(Graph into) {
+        Return x = new Return(null, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/ShiftOp.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ShiftOp.java	Mon May 30 18:46:57 2011 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.graph.*;
 import com.sun.c1x.debug.*;
 import com.sun.cri.bytecode.*;
+import com.sun.cri.ci.*;
 
 /**
  * The {@code ShiftOp} class represents shift operations.
@@ -44,6 +45,10 @@
         super(x.kind, opcode, x, y, INPUT_COUNT, SUCCESSOR_COUNT, graph);
     }
 
+    private ShiftOp(CiKind kind, int opcode, Graph graph) {
+        super(kind, opcode, null, null, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+    }
+
     @Override
     public void accept(ValueVisitor v) {
         v.visitShiftOp(this);
@@ -53,4 +58,11 @@
     public void print(LogStream out) {
         out.print(x()).print(' ').print(Bytecodes.operator(opcode)).print(' ').print(y());
     }
+
+    @Override
+    public Node copy(Graph into) {
+        ShiftOp x = new ShiftOp(kind, opcode, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/StoreField.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/StoreField.java	Mon May 30 18:46:57 2011 +0200
@@ -86,4 +86,11 @@
         print(" [type: ").print(CiUtil.format("%h.%n:%t", field(), false)).
         print(']');
     }
+
+    @Override
+    public Node copy(Graph into) {
+        StoreField x = new StoreField(null, field, null, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/StoreIndexed.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/StoreIndexed.java	Mon May 30 18:46:57 2011 +0200
@@ -62,13 +62,13 @@
      * @param array the instruction producing the array
      * @param index the instruction producing the index
      * @param length the instruction producing the length
-     * @param elementType the element type
+     * @param elementKind the element type
      * @param value the value to store into the array
      * @param stateAfter the state after executing this instruction
      * @param graph
      */
-    public StoreIndexed(Value array, Value index, Value length, CiKind elementType, Value value, Graph graph) {
-        super(CiKind.Void, array, index, length, elementType, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+    public StoreIndexed(Value array, Value index, Value length, CiKind elementKind, Value value, Graph graph) {
+        super(CiKind.Void, array, index, length, elementKind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
         setValue(value);
     }
 
@@ -81,4 +81,11 @@
     public void print(LogStream out) {
         out.print(array()).print('[').print(index()).print("] := ").print(value()).print(" (").print(kind.typeChar).print(')');
     }
+
+    @Override
+    public Node copy(Graph into) {
+        StoreIndexed x = new StoreIndexed(null, null, null, elementKind(), null, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/TableSwitch.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/TableSwitch.java	Mon May 30 18:46:57 2011 +0200
@@ -85,4 +85,11 @@
         INSTRUCTION.advance(out);
         out.print("default   : ").print(defaultSuccessor());
     }
+
+    @Override
+    public Node copy(Graph into) {
+        TableSwitch x = new TableSwitch(null, Arrays.asList(new Instruction[numberOfCases() + 1]), lowKey, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Throw.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Throw.java	Mon May 30 18:46:57 2011 +0200
@@ -104,4 +104,11 @@
     public void print(LogStream out) {
         out.print("throw ").print(exception());
     }
+
+    @Override
+    public Node copy(Graph into) {
+        Throw x = new Throw(null, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Unwind.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Unwind.java	Mon May 30 18:46:57 2011 +0200
@@ -79,4 +79,11 @@
     public void print(LogStream out) {
         out.print(kind.typeChar).print("unwind ").print(exception());
     }
+
+    @Override
+    public Node copy(Graph into) {
+        Unwind x = new Unwind(null, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Value.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Value.java	Mon May 30 18:46:57 2011 +0200
@@ -60,11 +60,6 @@
     // TODO: remove when Value class changes are completed
 
     @Override
-    public Node copy(Graph into) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
     protected Object clone() throws CloneNotSupportedException {
         throw new CloneNotSupportedException();
     }
--- a/graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java	Mon May 30 18:46:57 2011 +0200
@@ -487,4 +487,11 @@
     public void setValueAt(int j, Value v) {
         inputs().set(j, v);
     }
+
+    @Override
+    public Node copy(Graph into) {
+        FrameState x = new FrameState(bci, localsSize, stackSize, locksSize, into);
+        x.setNonNull(isNonNull());
+        return x;
+    }
 }
--- a/graal/GraalGraph/src/com/oracle/graal/graph/Graph.java	Mon May 30 17:05:06 2011 +0200
+++ b/graal/GraalGraph/src/com/oracle/graal/graph/Graph.java	Mon May 30 18:46:57 2011 +0200
@@ -25,6 +25,9 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
 
 public class Graph {
 
@@ -68,4 +71,49 @@
     public <T> NodeMap<T> createNodeMap() {
         return new NodeMap<T>(this);
     }
+
+    public void addDuplicate(Collection<Node> nodes, Map<Node, Node> replacements) {
+        Map<Node, Node> newNodes = new HashMap<Node, Node>();
+        for (Node node : nodes) {
+            if (node != null && !replacements.containsKey(node)) {
+                newNodes.put(node, node.copy(this));
+            }
+        }
+        for (Entry<Node, Node> entry : newNodes.entrySet()) {
+            Node oldNode = entry.getKey();
+            Node node = entry.getValue();
+            for (int i = 0; i < oldNode.successors().size(); i++) {
+                Node succ = oldNode.successors().get(i);
+                Node target = replacements.get(succ);
+                if (target == null) {
+                    target = newNodes.get(succ);
+                }
+                node.successors().set(i, target);
+            }
+            for (int i = 0; i < oldNode.inputs().size(); i++) {
+                Node input = oldNode.inputs().get(i);
+                Node target = replacements.get(input);
+                if (target == null) {
+                    target = newNodes.get(input);
+                }
+                node.inputs().set(i, target);
+            }
+        }
+        for (Entry<Node, Node> entry : replacements.entrySet()) {
+            Node oldNode = entry.getKey();
+            Node node = entry.getValue();
+            for (int i = 0; i < oldNode.successors().size(); i++) {
+                Node succ = oldNode.successors().get(i);
+                if (newNodes.containsKey(succ)) {
+                    node.successors().set(i, newNodes.get(succ));
+                }
+            }
+            for (int i = 0; i < oldNode.inputs().size(); i++) {
+                Node input = oldNode.inputs().get(i);
+                if (newNodes.containsKey(input)) {
+                    node.inputs().set(i, newNodes.get(input));
+                }
+            }
+        }
+    }
 }