changeset 3492:e04e88087e98

Merga
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Fri, 05 Aug 2011 18:44:32 +0200
parents 2ae2861243b1 (diff) 66e8bde93b6d (current diff)
children faf60b7be40d
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/OperandPool.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/CFGPrinter.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ArrayLength.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Conditional.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MaterializeNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Negate.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NegateBooleanNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NormalizeCompare.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBlock.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRDebugInfo.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRInstruction.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ConvertConditionalPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/BitMap2D.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/GraphUtil.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FPConversionNode.java
diffstat 62 files changed, 774 insertions(+), 678 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Fri Aug 05 15:14:03 2011 +0200
+++ b/.hgignore	Fri Aug 05 18:44:32 2011 +0200
@@ -36,3 +36,4 @@
 ^src/share/tools/IdealGraphVisualizer/dist/
 ^.hgtip
 ^make/solaris/solaris_amd64_compiler1/
+^RemoteSystemsTempFiles/
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java	Fri Aug 05 18:44:32 2011 +0200
@@ -44,7 +44,6 @@
 import com.oracle.max.graal.compiler.value.FrameState.ValueProcedure;
 import com.oracle.max.graal.extensions.*;
 import com.oracle.max.graal.graph.*;
-import com.oracle.max.graal.graph.collections.*;
 import com.sun.cri.ci.*;
 import com.sun.cri.ri.*;
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/OperandPool.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/OperandPool.java	Fri Aug 05 18:44:32 2011 +0200
@@ -27,7 +27,6 @@
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.ir.*;
 import com.oracle.max.graal.graph.*;
-import com.oracle.max.graal.graph.collections.*;
 import com.sun.cri.ci.*;
 
 /**
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/CFGPrinter.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/CFGPrinter.java	Fri Aug 05 18:44:32 2011 +0200
@@ -27,18 +27,17 @@
 
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.alloc.*;
-import com.oracle.max.graal.compiler.alloc.Interval.*;
+import com.oracle.max.graal.compiler.alloc.Interval.UsePosList;
 import com.oracle.max.graal.compiler.graph.*;
 import com.oracle.max.graal.compiler.ir.*;
 import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.lir.LIRInstruction.*;
+import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandFormatter;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.compiler.value.*;
 import com.oracle.max.graal.graph.*;
-import com.oracle.max.graal.graph.collections.*;
 import com.sun.cri.ci.*;
-import com.sun.cri.ci.CiAddress.*;
+import com.sun.cri.ci.CiAddress.Scale;
 import com.sun.cri.ri.*;
 
 /**
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Fri Aug 05 18:44:32 2011 +0200
@@ -581,23 +581,11 @@
         LIRItem xin = xitem;
         LIRItem yin = yitem;
 
-        if (kind.isLong()) {
-            // for longs, only conditions "eql", "neq", "lss", "geq" are valid;
-            // mirror for other conditions
-            if (cond == Condition.GT || cond == Condition.LE) {
-                cond = cond.mirror();
-                xin = yitem;
-                yin = xitem;
-            }
-            xin.setDestroysRegister();
+        if (kind.isFloat() || kind.isDouble()) {
+            cond = floatingPointCondition(cond);
         }
+
         xin.loadItem();
-        if (kind.isLong() && yin.result().isConstant() && yin.instruction.asConstant().asLong() == 0 && (cond == Condition.EQ || cond == Condition.NE)) {
-            // dont load item
-        } else if (kind.isLong() || kind.isFloat() || kind.isDouble()) {
-            // longs cannot handle constants at right side
-            yin.loadItem();
-        }
 
         CiValue left = xin.result();
         CiValue right = yin.result();
@@ -618,32 +606,6 @@
         }
     }
 
-    @Override
-    public void visitIfOp(Conditional i) {
-        Value x = i.x();
-        Value y = i.y();
-        CiKind xtype = x.kind;
-        CiKind ttype = i.trueValue().kind;
-        assert xtype.isInt() || xtype.isObject() : "cannot handle others";
-        assert ttype.isInt() || ttype.isObject() || ttype.isLong() || ttype.isWord() : "cannot handle others";
-        assert ttype.equals(i.falseValue().kind) : "cannot handle others";
-
-        CiValue left = load(x);
-        CiValue right = null;
-        if (!canInlineAsConstant(y)) {
-            right = load(y);
-        } else {
-            right = makeOperand(y);
-        }
-
-        CiValue tVal = makeOperand(i.trueValue());
-        CiValue fVal = makeOperand(i.falseValue());
-        CiValue reg = createResultVariable(i);
-
-        lir.cmp(i.condition(), left, right);
-        lir.cmove(i.condition(), tVal, fVal, reg);
-    }
-
     protected FrameState stateBeforeInvokeReturn(Invoke invoke) {
         return invoke.stateAfter().duplicateModified(invoke.bci, invoke.stateAfter().rethrowException(), invoke.kind);
     }
@@ -1787,7 +1749,7 @@
         }
     }
 
-    protected abstract boolean canInlineAsConstant(Value i);
+    public abstract boolean canInlineAsConstant(Value i);
 
     protected abstract boolean canStoreAsConstant(Value i, CiKind kind);
 
@@ -1884,4 +1846,6 @@
             ((Value) n).accept(generator);
         }
     };
+
+    public abstract Condition floatingPointCondition(Condition cond);
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Fri Aug 05 18:44:32 2011 +0200
@@ -136,6 +136,8 @@
             graph.stopRecordModifications();
         }
 
+        new ConvertConditionalPhase().apply(graph);
+
         new LoweringPhase(compilation.runtime).apply(graph);
         if (GraalOptions.Lower) {
             new MemoryPhase().apply(graph);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/And.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/And.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -62,7 +63,7 @@
 
     private static class AndCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             assert node instanceof And;
             And and = (And) node;
             CiKind kind = and.kind;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ArrayLength.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ArrayLength.java	Fri Aug 05 18:44:32 2011 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.graph.*;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.graph.*;
@@ -95,7 +96,7 @@
 
     private static class ArrayLengthCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             ArrayLength arrayLength = (ArrayLength) node;
             Value array = arrayLength.array();
             if (array instanceof NewArray) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java	Fri Aug 05 18:44:32 2011 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
@@ -94,7 +95,7 @@
 
     private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             CheckCast checkCast = (CheckCast) node;
             Value object = checkCast.object();
             RiType exactType = object.exactType();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import java.util.*;
+
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.graph.*;
@@ -63,8 +65,8 @@
         this.y = x;
     }
 
-    Condition condition;
-    boolean unorderedIsTrue;
+    private Condition condition;
+    private boolean unorderedIsTrue;
 
     /**
      * Constructs a new Compare instruction.
@@ -117,6 +119,11 @@
         setY(t);
     }
 
+    public void negate() {
+        condition = condition.negate();
+        unorderedIsTrue = !unorderedIsTrue;
+    }
+
     @Override
     public void accept(ValueVisitor v) {
     }
@@ -146,6 +153,13 @@
     }
 
     @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> properties = super.getDebugProperties();
+        properties.put("unorderedIsTrue", unorderedIsTrue());
+        return properties;
+    }
+
+    @Override
     public Node copy(Graph into) {
         Compare x = new Compare(null, condition, null, into);
         x.unorderedIsTrue = unorderedIsTrue;
@@ -154,17 +168,14 @@
 
     private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             Compare compare = (Compare) node;
             if (compare.x().isConstant() && !compare.y().isConstant()) { // move constants to the left (y)
-                Value x = compare.x();
-                compare.setX(compare.y());
-                compare.setY(x);
-                compare.condition = compare.condition.mirror();
+                compare.swapOperands();
             } else if (compare.x().isConstant() && compare.y().isConstant()) {
                 CiConstant constX = compare.x().asConstant();
                 CiConstant constY = compare.y().asConstant();
-                Boolean result = compare.condition().foldCondition(constX, constY, ((CompilerGraph) node.graph()).runtime());
+                Boolean result = compare.condition().foldCondition(constX, constY, ((CompilerGraph) node.graph()).runtime(), compare.unorderedIsTrue());
                 if (result != null) {
                     if (GraalOptions.TraceCanonicalizer) {
                         TTY.println("folded condition " + constX + " " + compare.condition() + " " + constY);
@@ -205,6 +216,19 @@
                     }
                 }
             }
+            boolean allUsagesNegate = true;
+            for (Node usage : compare.usages()) {
+                if (!(usage instanceof NegateBooleanNode)) {
+                    allUsagesNegate = false;
+                    break;
+                }
+            }
+            if (allUsagesNegate) {
+                compare.negate();
+                for (Node usage : compare.usages().snapshot()) {
+                    usage.replaceAtUsages(compare);
+                }
+            }
             return compare;
         }
 
@@ -215,7 +239,7 @@
                     if (compare.condition == Condition.NE) {
                         isFalseCheck = !isFalseCheck;
                     }
-                    BooleanNode result = materializeNode.value();
+                    BooleanNode result = materializeNode.condition();
                     if (isFalseCheck) {
                         result = new NegateBooleanNode(result, compare.graph());
                     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Condition.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Condition.java	Fri Aug 05 18:44:32 2011 +0200
@@ -129,6 +129,8 @@
             case BE: return AT;
             case AT: return BE;
             case AE: return BT;
+            case OF: return NOF;
+            case NOF: return OF;
         }
         throw new IllegalArgumentException(this.toString());
     }
@@ -169,7 +171,7 @@
      * @return {@link Boolean#TRUE} if the comparison is known to be true,
      * {@link Boolean#FALSE} if the comparison is known to be false, {@code null} otherwise.
      */
-    public Boolean foldCondition(CiConstant lt, CiConstant rt, RiRuntime runtime) {
+    public Boolean foldCondition(CiConstant lt, CiConstant rt, RiRuntime runtime, boolean unorderedIsTrue) {
         switch (lt.kind) {
             case Boolean:
             case Int: {
@@ -209,7 +211,44 @@
                 }
                 break;
             }
-            // XXX: folding of floating comparisons should be possible
+            case Float: {
+                float x = lt.asFloat();
+                float y = rt.asFloat();
+                if (Float.isNaN(x) || Float.isNaN(y)) {
+                    return unorderedIsTrue;
+                }
+                switch (this) {
+                    case EQ: return x == y;
+                    case NE: return x != y;
+                    case BT:
+                    case LT: return x < y;
+                    case BE:
+                    case LE: return x <= y;
+                    case AT:
+                    case GT: return x > y;
+                    case AE:
+                    case GE: return x >= y;
+                }
+            }
+            case Double: {
+                double x = lt.asDouble();
+                double y = rt.asDouble();
+                if (Double.isNaN(x) || Double.isNaN(y)) {
+                    return unorderedIsTrue;
+                }
+                switch (this) {
+                    case EQ: return x == y;
+                    case NE: return x != y;
+                    case BT:
+                    case LT: return x < y;
+                    case BE:
+                    case LE: return x <= y;
+                    case AT:
+                    case GT: return x > y;
+                    case AE:
+                    case GE: return x >= y;
+                }
+            }
         }
         return null;
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Conditional.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Conditional.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,45 +22,45 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.gen.*;
+import com.oracle.max.graal.compiler.gen.LIRGenerator.LIRGeneratorOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.compiler.value.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 
 /**
- * The {@code IfOp} class represents a comparison that yields one of two values.
+ * The {@code Conditional} class represents a comparison that yields one of two values.
  * Note that these nodes are not built directly from the bytecode but are introduced
  * by conditional expression elimination.
  */
-public final class Conditional extends Binary {
-
-    @NodeInput
-    private Value trueValue;
+public class Conditional extends Binary {
+    @NodeInput private BooleanNode condition;
+    @NodeInput private FrameState stateDuring;
 
-    @NodeInput
-    private Value falseValue;
-
-    public Value trueValue() {
-        return trueValue;
+    public BooleanNode condition() {
+        return condition;
     }
 
-    public void setTrueValue(Value x) {
-        updateUsages(trueValue, x);
-        trueValue = x;
+    public void setCondition(BooleanNode n) {
+        updateUsages(condition, n);
+        condition = n;
     }
 
-    public Value falseValue() {
-        return falseValue;
+    public FrameState stateDuring() {
+        return stateDuring;
     }
 
-    public void setFalseValue(Value x) {
-        updateUsages(falseValue, x);
-        falseValue = x;
+    public void setStateDuring(FrameState n) {
+        updateUsages(stateDuring, n);
+        stateDuring = n;
     }
 
-    Condition condition;
-
     /**
      * Constructs a new IfOp.
      * @param x the instruction producing the first value to be compared
@@ -69,51 +69,37 @@
      * @param trueValue the value produced if the condition is true
      * @param falseValue the value produced if the condition is false
      */
-    public Conditional(Value x, Condition condition, Value y, Value trueValue, Value falseValue, Graph graph) {
+    public Conditional(BooleanNode condition, Value trueValue, Value falseValue, Graph graph) {
         // TODO: return the appropriate bytecode IF_ICMPEQ, etc
-        super(trueValue.kind.meet(falseValue.kind), Bytecodes.ILLEGAL, x, y, graph);
-        this.condition = condition;
-        setTrueValue(trueValue);
-        setFalseValue(falseValue);
+        super(trueValue.kind.meet(falseValue.kind), Bytecodes.ILLEGAL, trueValue, falseValue, graph);
+        setCondition(condition);
     }
 
     // for copying
-    private Conditional(CiKind kind, Condition cond, Graph graph) {
+    private Conditional(CiKind kind, Graph graph) {
         super(kind, Bytecodes.ILLEGAL, null, null, graph);
-        this.condition = cond;
     }
 
-    /**
-     * Gets the condition of this if operation.
-     * @return the condition
-     */
-    public Condition condition() {
-        return condition;
+    public Value trueValue() {
+        return x();
     }
 
-    /**
-     * Checks whether this comparison operator is commutative (i.e. it is either == or !=).
-     * @return {@code true} if this comparison is commutative
-     */
-    public boolean isCommutative() {
-        return condition == Condition.EQ || condition == Condition.NE;
+    public Value falseValue() {
+        return y();
     }
 
-    @Override
-    public void accept(ValueVisitor v) {
-        v.visitIfOp(this);
+    public void setTrueValue(Value value) {
+        setX(value);
     }
 
-    @Override
-    public int valueNumber() {
-        return Util.hash4(condition.hashCode(), x(), y(), trueValue(), falseValue());
+    public void setFalseValue(Value value) {
+        setY(value);
     }
 
     @Override
     public boolean valueEqual(Node i) {
         if (i instanceof Conditional) {
-            Conditional o = (Conditional) i;
-            return opcode == o.opcode && x() == o.x() && y() == o.y() && trueValue() == o.trueValue() && falseValue() == o.falseValue();
+            return super.valueEqual(i);
         }
         return false;
     }
@@ -122,7 +108,7 @@
     public void print(LogStream out) {
         out.print(x()).
         print(' ').
-        print(condition().operator).
+        print(condition()).
         print(' ').
         print(y()).
         print(" ? ").
@@ -133,7 +119,129 @@
 
     @Override
     public Node copy(Graph into) {
-        Conditional x = new Conditional(kind, condition, into);
+        Conditional x = new Conditional(kind, into);
         return x;
     }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == CanonicalizerOp.class) {
+            return (T) CANONICALIZER;
+        }
+        if (clazz == LIRGeneratorOp.class) {
+            return (T) LIRGEN;
+        }
+        return super.lookup(clazz);
+    }
+
+    private static final CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
+        @Override
+        public Node canonical(Node node, NotifyReProcess reProcess) {
+            Conditional conditional = (Conditional) node;
+            BooleanNode condition = conditional.condition();
+            Value trueValue = conditional.trueValue();
+            Value falseValue = conditional.falseValue();
+            if (condition instanceof Constant) {
+                Constant c = (Constant) condition;
+                if (c.asConstant().asBoolean()) {
+                    return trueValue;
+                } else {
+                    return falseValue;
+                }
+            }
+            if (trueValue == falseValue) {
+                return trueValue;
+            }
+            if (!(conditional instanceof MaterializeNode) && trueValue instanceof Constant && falseValue instanceof Constant
+                            && trueValue.kind == CiKind.Int && falseValue.kind == CiKind.Int) {
+                int trueInt = trueValue.asConstant().asInt();
+                int falseInt = falseValue.asConstant().asInt();
+                if (trueInt == 0 && falseInt == 1) {
+                    if (GraalOptions.TraceCanonicalizer) {
+                        TTY.println("> Conditional canon'ed to ~Materialize");
+                    }
+                    reProcess.reProccess(condition); // because we negate it
+                    MaterializeNode materializeNode = new MaterializeNode(new NegateBooleanNode(condition, node.graph()), node.graph());
+                    materializeNode.setStateDuring(conditional.stateDuring());
+                    return materializeNode;
+                } else if (trueInt == 1 && falseInt == 0) {
+                    if (GraalOptions.TraceCanonicalizer) {
+                        TTY.println("> Conditional canon'ed to Materialize");
+                    }
+                    MaterializeNode materializeNode = new MaterializeNode(condition, node.graph());
+                    materializeNode.setStateDuring(conditional.stateDuring());
+                    return materializeNode;
+                }
+            } else if (falseValue instanceof Constant && !(trueValue instanceof Constant)) {
+                conditional.setTrueValue(falseValue);
+                conditional.setFalseValue(trueValue);
+                condition = new NegateBooleanNode(condition, node.graph());
+                conditional.setCondition(condition);
+            }
+            return conditional;
+        }
+    };
+
+    private static final LIRGeneratorOp LIRGEN = new LIRGeneratorOp() {
+
+        @Override
+        public void generate(Node n, LIRGenerator generator) {
+            Conditional conditional = (Conditional) n;
+            BooleanNode condition = conditional.condition();
+
+            CiVariable result = generator.createResultVariable(conditional);
+            // try to use cmp + cmov first
+            Condition cond = null;
+            CiValue left = null;
+            CiValue right = null;
+            boolean floating = false;
+            boolean unOrderedIsSecond = false;
+            boolean negate = false;
+            while (condition instanceof NegateBooleanNode) {
+                negate = !negate;
+                condition = ((NegateBooleanNode) condition).value();
+            }
+            if (condition instanceof Compare) {
+                Compare compare = (Compare) condition;
+                Value x = compare.x();
+                Value y = compare.y();
+                cond = compare.condition();
+                if (x.kind.isFloatOrDouble()) {
+                    floating = true;
+                    unOrderedIsSecond = !compare.unorderedIsTrue();
+                    cond = generator.floatingPointCondition(cond);
+                }
+                left = generator.load(x);
+                if (!generator.canInlineAsConstant(y)) {
+                    right = generator.load(y);
+                } else {
+                    right = generator.makeOperand(y);
+                }
+            } else if (condition instanceof IsNonNull) {
+                IsNonNull isNonNull = (IsNonNull) condition;
+                left = generator.load(isNonNull.object());
+                right = CiConstant.NULL_OBJECT;
+                cond = Condition.NE;
+            } else if (condition instanceof Constant) {
+                generator.lir().move(result, condition.asConstant());
+            } else {
+                throw Util.shouldNotReachHere("Currently not implemented because we can not create blocks during LIRGen : " + condition);
+            }
+            CiValue tVal = generator.makeOperand(conditional.trueValue());
+            CiValue fVal = generator.makeOperand(conditional.falseValue());
+            if (cond != null) {
+                if (negate) {
+                    cond = cond.negate();
+                }
+                assert left != null && right != null;
+                generator.lir().cmp(cond, left, right);
+                if (floating) {
+                    generator.lir().fcmove(cond, tVal, fVal, result, unOrderedIsSecond);
+                } else {
+                    generator.lir().cmove(cond, tVal, fVal, result);
+                }
+            }
+        }
+    };
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java	Fri Aug 05 18:44:32 2011 +0200
@@ -26,6 +26,7 @@
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.ir.Deoptimize.DeoptAction;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 
@@ -76,7 +77,7 @@
 
     private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             FixedGuard fixedGuard = (FixedGuard) node;
             for (BooleanNode n : fixedGuard.conditions.snapshot()) {
                 if (n instanceof Constant) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatAdd.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatAdd.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -57,7 +58,7 @@
 
     private static class FloatAddCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             FloatAdd add = (FloatAdd) node;
             Value x = add.x();
             Value y = add.y();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatDiv.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatDiv.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -56,7 +57,7 @@
 
     private static class FloatDivCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             FloatDiv div = (FloatDiv) node;
             Value x = div.x();
             Value y = div.y();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatMul.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatMul.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -67,7 +68,7 @@
 
     private static class FloatMulCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             FloatMul mul = (FloatMul) node;
             Value x = mul.x();
             Value y = mul.y();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatRem.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatRem.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -56,7 +57,7 @@
 
     private static class FloatRemCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             FloatRem rem = (FloatRem) node;
             Value x = rem.x();
             Value y = rem.y();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatSub.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatSub.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -56,7 +57,7 @@
 
     private static class FloatSubCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             FloatSub sub = (FloatSub) node;
             Value x = sub.x();
             Value y = sub.y();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java	Fri Aug 05 18:44:32 2011 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
@@ -46,6 +47,9 @@
         anchor = x;
     }
 
+    /**
+     * The instruction that produces the tested boolean value.
+     */
     public BooleanNode node() {
         return node;
     }
@@ -91,7 +95,7 @@
 
     private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             GuardNode guard = (GuardNode) node;
             if (guard.node() instanceof Constant) {
                 Constant c = (Constant) guard.node();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java	Fri Aug 05 18:44:32 2011 +0200
@@ -25,6 +25,7 @@
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 
@@ -132,7 +133,7 @@
 
     private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             If ifNode = (If) node;
             if (ifNode.compare() instanceof Constant) {
                 Constant c = (Constant) ifNode.compare();
@@ -148,6 +149,28 @@
                     return ifNode.falseSuccessor();
                 }
             }
+            if (ifNode.trueSuccessor() instanceof EndNode && ifNode.falseSuccessor() instanceof EndNode) {
+                EndNode trueEnd = (EndNode) ifNode.trueSuccessor();
+                EndNode falseEnd = (EndNode) ifNode.falseSuccessor();
+                Merge merge = trueEnd.merge();
+                if (merge == falseEnd.merge() && merge.phis().size() == 0) {
+                    FixedNode next = merge.next();
+                    merge.setNext(null); //disconnect to avoid next from having 2 preds
+                    if (ifNode.compare().usages().size() == 1 && /*ifNode.compare().hasSideEffets()*/ true) { // TODO (gd) ifNode.compare().hasSideEffets() ?
+                        if (GraalOptions.TraceCanonicalizer) {
+                            TTY.println("> Useless if with side effects Canon'ed to guard");
+                        }
+                        ValueAnchor anchor = new ValueAnchor(ifNode.compare(), node.graph());
+                        anchor.setNext(next);
+                        return anchor;
+                    } else {
+                        if (GraalOptions.TraceCanonicalizer) {
+                            TTY.println("> Useless if Canon'ed away");
+                        }
+                        return next;
+                    }
+                }
+            }
             return ifNode;
         }
     };
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java	Fri Aug 05 18:44:32 2011 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -82,7 +83,7 @@
 
     private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             InstanceOf isInstance = (InstanceOf) node;
             Value object = isInstance.object();
             RiType exactType = object.exactType();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerAdd.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerAdd.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -56,7 +57,7 @@
 
     private static class IntegerAddCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             IntegerAdd add = (IntegerAdd) node;
             Value x = add.x();
             Value y = add.y();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerDiv.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerDiv.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -56,7 +57,7 @@
 
     private static class IntegerDivCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             IntegerDiv div = (IntegerDiv) node;
             Value x = div.x();
             Value y = div.y();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerMul.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerMul.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -56,7 +57,7 @@
 
     private static class IntegerMulCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             IntegerMul mul = (IntegerMul) node;
             Value x = mul.x();
             Value y = mul.y();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerRem.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerRem.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -56,7 +57,7 @@
 
     private static class IntegerRemCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             IntegerRem rem = (IntegerRem) node;
             Value x = rem.x();
             Value y = rem.y();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -56,7 +57,7 @@
 
     private static class IntegerSubCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             IntegerSub sub = (IntegerSub) node;
             Value x = sub.x();
             Value y = sub.y();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java	Fri Aug 05 18:44:32 2011 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -106,7 +107,7 @@
 
     private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             IsNonNull isNonNull = (IsNonNull) node;
             Value object = isNonNull.object();
             if (object instanceof NewInstance || object instanceof NewArray) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java	Fri Aug 05 18:44:32 2011 +0200
@@ -26,6 +26,7 @@
 
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -126,7 +127,7 @@
 
     private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             IsType isType = (IsType) node;
             Value object = isType.object();
             RiType exactType = object.exactType();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LeftShift.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LeftShift.java	Fri Aug 05 18:44:32 2011 +0200
@@ -23,6 +23,7 @@
 package com.oracle.max.graal.compiler.ir;
 
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
@@ -57,7 +58,7 @@
 
     private static class LeftShiftCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             LeftShift leftShift = (LeftShift) node;
             CiKind kind = leftShift.kind;
             Graph graph = leftShift.graph();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java	Fri Aug 05 18:44:32 2011 +0200
@@ -25,6 +25,7 @@
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
 import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.LoweringPhase.LoweringOp;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
@@ -124,7 +125,7 @@
 
     private static class LoadFieldCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             LoadField loadField = (LoadField) node;
             Graph graph = node.graph();
             CiConstant constant = null;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MaterializeNode.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MaterializeNode.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,34 +22,14 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
-import com.oracle.max.asm.*;
 import com.oracle.max.graal.compiler.debug.*;
-import com.oracle.max.graal.compiler.gen.*;
-import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.graph.*;
-import com.sun.cri.ci.*;
-
-public final class MaterializeNode extends FloatingNode {
 
-    @NodeInput
-    private BooleanNode value;
+public final class MaterializeNode extends Conditional {
 
-    public BooleanNode value() {
-        return value;
-    }
-
-    public void setValue(BooleanNode x) {
-        updateUsages(value, x);
-        value = x;
-    }
 
     public MaterializeNode(BooleanNode value, Graph graph) {
-        super(CiKind.Int, graph);
-        setValue(value);
-    }
-
-    @Override
-    public void accept(ValueVisitor v) {
+        super(value, Constant.forInt(1, graph), Constant.forInt(0, graph), graph);
     }
 
     @Override
@@ -57,35 +37,9 @@
         return (i instanceof MaterializeNode);
     }
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == LIRGenerator.LIRGeneratorOp.class) {
-            return (T) LIR_GENERATOR_OP;
-        }
-        return super.lookup(clazz);
-    }
-
-    public static final LIRGenerator.LIRGeneratorOp LIR_GENERATOR_OP = new LIRGenerator.LIRGeneratorOp() {
-
-        @Override
-        public void generate(Node n, LIRGenerator generator) {
-            LIRBlock trueSuccessor = new LIRBlock(new Label(), null);
-            generator.emitBooleanBranch(((MaterializeNode) n).value(), trueSuccessor, null, null);
-            CiValue result = generator.createResultVariable((Value) n);
-            LIRList lir = generator.lir();
-            lir.move(CiConstant.FALSE, result);
-            Label label = new Label();
-            lir.branch(Condition.TRUE, label);
-            lir.branchDestination(trueSuccessor.label);
-            lir.move(CiConstant.TRUE, result);
-            lir.branchDestination(label);
-        }
-    };
-
     @Override
     public void print(LogStream out) {
-        out.print("materialize(").print(value().toString()).print(')');
+        out.print("materialize(").print(condition().toString()).print(')');
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Negate.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Negate.java	Fri Aug 05 18:44:32 2011 +0200
@@ -23,6 +23,7 @@
 package com.oracle.max.graal.compiler.ir;
 
 import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.graph.*;
@@ -102,7 +103,7 @@
 
     private static class NegateCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             Negate negate = (Negate) node;
             Value x = negate.x();
             Graph graph = negate.graph();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NegateBooleanNode.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NegateBooleanNode.java	Fri Aug 05 18:44:32 2011 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 
@@ -76,7 +77,7 @@
 
     private static final CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             NegateBooleanNode negateNode = (NegateBooleanNode) node;
             Value value = negateNode.value();
             if (value instanceof NegateBooleanNode) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NormalizeCompare.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NormalizeCompare.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import java.util.*;
+
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -45,7 +47,7 @@
 
     @Override
     public void accept(ValueVisitor v) {
-        v.visitMaterialize(this);
+        v.visitNormalizeCompare(this);
     }
 
     @Override
@@ -62,6 +64,13 @@
         return new NormalizeCompare(opcode, kind, null, null, into);
     }
 
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> properties = super.getDebugProperties();
+        properties.put("isUnorderedLess", isUnorderedLess());
+        return properties;
+    }
+
     public boolean isUnorderedLess() {
         return this.opcode == Bytecodes.FCMPL || this.opcode == Bytecodes.DCMPL;
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Or.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Or.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -66,7 +67,7 @@
 
     private static class OrCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             Or or = (Or) node;
             CiKind kind = or.kind;
             Graph graph = or.graph();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java	Fri Aug 05 18:44:32 2011 +0200
@@ -24,9 +24,11 @@
 
 import java.util.*;
 
+import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
-import com.oracle.max.graal.compiler.ir.StateSplit.*;
-import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
+import com.oracle.max.graal.compiler.ir.StateSplit.FilteringIterator;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 
@@ -174,48 +176,45 @@
     private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
 
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             Phi phiNode = (Phi) node;
-//            if (phiNode.valueCount() != 2 || phiNode.merge().endCount() != 2 || phiNode.merge().phis().size() != 1) {
-//                return phiNode;
-//            }
-//            if (!(phiNode.valueAt(0) instanceof Constant && phiNode.valueAt(1) instanceof Constant)) {
-//                return phiNode;
-//            }
-//            Merge merge = phiNode.merge();
-//            Node end0 = merge.endAt(0);
-//            Node end1 = merge.endAt(1);
-//            if (end0.predecessors().size() != 1 || end1.predecessors().size() != 1) {
-//                return phiNode;
-//            }
-//            Node endPred0 = end0.predecessors().get(0);
-//            Node endPred1 = end1.predecessors().get(0);
-//            if (endPred0 != endPred1 || !(endPred0 instanceof If)) {
-//                return phiNode;
-//            }
-//            If ifNode = (If) endPred0;
-//            if (ifNode.predecessors().size() != 1) {
-//                return phiNode;
-//            }
-//            boolean inverted = ((If) endPred0).trueSuccessor() == end1;
-//            CiConstant trueValue = phiNode.valueAt(inverted ? 1 : 0).asConstant();
-//            CiConstant falseValue = phiNode.valueAt(inverted ? 0 : 1).asConstant();
-//            if (trueValue.kind != CiKind.Int || falseValue.kind != CiKind.Int) {
-//                return phiNode;
-//            }
-//            if ((trueValue.asInt() == 0 || trueValue.asInt() == 1) && (falseValue.asInt() == 0 || falseValue.asInt() == 1) && (trueValue.asInt() != falseValue.asInt())) {
-//                MaterializeNode result;
-//                if (trueValue.asInt() == 1) {
-//                    result = new MaterializeNode(ifNode.compare(), phiNode.graph());
-//                } else {
-//                    result = new MaterializeNode(new NegateBooleanNode(ifNode.compare(), phiNode.graph()), phiNode.graph());
-//                }
-//                Node next = merge.next();
-//                merge.setNext(null);
-//                ifNode.predecessors().get(0).successors().replace(ifNode, next);
-//                return result;
-//            }
-            return phiNode;
+            if (phiNode.valueCount() != 2 || phiNode.merge().endCount() != 2) {
+                return phiNode;
+            }
+            Merge merge = phiNode.merge();
+            if (merge.phis().size() > 1) { // XXX (gd) disable canonicalization of multiple conditional while we are not able to fuse them and the potentially leftover If in the backend
+                return phiNode;
+            }
+            Node end0 = merge.endAt(0);
+            Node end1 = merge.endAt(1);
+            Node endPred0 = end0.predecessor();
+            Node endPred1 = end1.predecessor();
+            if (endPred0 != endPred1 || !(endPred0 instanceof If)) {
+                return phiNode;
+            }
+            If ifNode = (If) endPred0;
+            boolean inverted = ifNode.trueSuccessor() == end1;
+            Value trueValue = phiNode.valueAt(inverted ? 1 : 0);
+            Value falseValue = phiNode.valueAt(inverted ? 0 : 1);
+            if ((trueValue.kind != CiKind.Int && trueValue.kind != CiKind.Long) || (falseValue.kind != CiKind.Int && falseValue.kind != CiKind.Long)) {
+                return phiNode;
+            }
+            if ((!(trueValue instanceof Constant) && trueValue.usages().size() == 1) || (!(falseValue instanceof Constant) && falseValue.usages().size() == 1)) {
+                return phiNode;
+            }
+            BooleanNode compare = ifNode.compare();
+            while (compare instanceof NegateBooleanNode) {
+                compare = ((NegateBooleanNode) compare).value();
+            }
+            if (!(compare instanceof Compare || compare instanceof IsNonNull || compare instanceof NegateBooleanNode || compare instanceof Constant)) {
+                return phiNode;
+            }
+            if (GraalOptions.TraceCanonicalizer) {
+                TTY.println("> Phi canon'ed to Conditional");
+            }
+            reProcess.reProccess(ifNode);
+            Conditional conditional = new Conditional(ifNode.compare(), trueValue, falseValue, node.graph());
+            return conditional;
         }
     };
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java	Fri Aug 05 18:44:32 2011 +0200
@@ -26,6 +26,7 @@
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.graph.*;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 import com.sun.cri.ri.*;
@@ -69,7 +70,7 @@
     private static final CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
 
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             RegisterFinalizer finalizer = (RegisterFinalizer) node;
             Value object = finalizer.object();
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RightShift.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RightShift.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -57,7 +58,7 @@
 
     private static class RighShiftCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             RightShift rightShift = (RightShift) node;
             CiKind kind = rightShift.kind;
             Graph graph = rightShift.graph();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/UnsignedRightShift.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/UnsignedRightShift.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -57,7 +58,7 @@
 
     private static class UnsignedRightShiftCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             UnsignedRightShift ushr = (UnsignedRightShift) node;
             CiKind kind = ushr.kind;
             Graph graph = ushr.graph();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java	Fri Aug 05 18:44:32 2011 +0200
@@ -35,7 +35,7 @@
     public abstract void visitArrayLength(ArrayLength i);
     public abstract void visitMerge(Merge i);
     public abstract void visitCheckCast(CheckCast i);
-    public abstract void visitMaterialize(NormalizeCompare i);
+    public abstract void visitNormalizeCompare(NormalizeCompare i);
     public abstract void visitConstant(Constant i);
     public abstract void visitConvert(Convert i);
     public abstract void visitExceptionObject(ExceptionObject i);
@@ -43,7 +43,6 @@
     public abstract void visitFrameState(FrameState i);
     public abstract void visitAnchor(Anchor i);
     public abstract void visitIf(If i);
-    public abstract void visitIfOp(Conditional i);
     public abstract void visitInvoke(Invoke i);
     public abstract void visitLoadField(LoadField i);
     public abstract void visitLoadIndexed(LoadIndexed i);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Xor.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Xor.java	Fri Aug 05 18:44:32 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -63,7 +64,7 @@
 
     private static class XorCanonicalizerOp implements CanonicalizerOp {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             assert node instanceof Xor;
             Xor xor = (Xor) node;
             CiKind kind = xor.kind;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRAssembler.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRAssembler.java	Fri Aug 05 18:44:32 2011 +0200
@@ -276,8 +276,14 @@
                 emitCompare2Int(op.code, op.operand1(), op.operand2(), op.result(), op);
                 break;
 
+            case FCmove:
+                emitConditionalMove(op.condition(), op.operand1(), op.operand2(), op.result(), true, false);
+                break;
+            case UFCmove:
+                emitConditionalMove(op.condition(), op.operand1(), op.operand2(), op.result(), true, true);
+                break;
             case Cmove:
-                emitConditionalMove(op.condition(), op.operand1(), op.operand2(), op.result());
+                emitConditionalMove(op.condition(), op.operand1(), op.operand2(), op.result(), false, false);
                 break;
 
             case Shl:
@@ -418,7 +424,7 @@
 
     protected abstract void emitSignificantBitOp(boolean most, CiValue inOpr1, CiValue dst);
 
-    protected abstract void emitConditionalMove(Condition condition, CiValue inOpr1, CiValue inOpr2, CiValue dst);
+    protected abstract void emitConditionalMove(Condition condition, CiValue inOpr1, CiValue inOpr2, CiValue dst, boolean mayBeUnordered, boolean unorderedcmovOpr1);
 
     protected abstract void emitCompare2Int(LIROpcode code, CiValue inOpr1, CiValue inOpr2, CiValue dst, LIROp2 op);
 
@@ -470,4 +476,15 @@
 
     protected abstract void reg2reg(CiValue src, CiValue dest);
 
+    protected abstract boolean trueOnUnordered(Condition condition);
+
+    protected abstract boolean falseOnUnordered(Condition condition);
+
+    protected boolean mayBeTrueOnUnordered(Condition condition) {
+        return trueOnUnordered(condition) || !falseOnUnordered(condition);
+    }
+
+    protected boolean mayBeFalseOnUnordered(Condition condition) {
+        return falseOnUnordered(condition) || !trueOnUnordered(condition);
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBlock.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBlock.java	Fri Aug 05 18:44:32 2011 +0200
@@ -31,7 +31,6 @@
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.compiler.value.*;
 import com.oracle.max.graal.graph.*;
-import com.oracle.max.graal.graph.collections.*;
 
 /**
  * The {@code LIRBlock} class definition.
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRDebugInfo.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRDebugInfo.java	Fri Aug 05 18:44:32 2011 +0200
@@ -26,7 +26,6 @@
 import com.oracle.max.graal.compiler.ir.*;
 import com.oracle.max.graal.compiler.value.*;
 import com.oracle.max.graal.graph.*;
-import com.oracle.max.graal.graph.collections.*;
 import com.sun.cri.ci.*;
 
 /**
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRInstruction.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRInstruction.java	Fri Aug 05 18:44:32 2011 +0200
@@ -27,9 +27,9 @@
 import java.util.*;
 
 import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.lir.LIROperand.*;
+import com.oracle.max.graal.compiler.lir.LIROperand.LIRAddressOperand;
+import com.oracle.max.graal.compiler.lir.LIROperand.LIRVariableOperand;
 import com.oracle.max.graal.graph.*;
-import com.oracle.max.graal.graph.collections.*;
 import com.sun.cri.ci.*;
 
 /**
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRList.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRList.java	Fri Aug 05 18:44:32 2011 +0200
@@ -195,6 +195,10 @@
         append(new LIROp2(LIROpcode.Cmove, condition, src1, src2, dst));
     }
 
+    public void fcmove(Condition condition, CiValue src1, CiValue src2, CiValue dst, boolean unorderedIsSecond) {
+        append(new LIROp2(unorderedIsSecond ? LIROpcode.FCmove : LIROpcode.UFCmove, condition, src1, src2, dst));
+    }
+
     public void abs(CiValue from, CiValue to, CiValue tmp) {
         append(new LIROp2(LIROpcode.Abs, from, tmp, to));
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROp2.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROp2.java	Fri Aug 05 18:44:32 2011 +0200
@@ -63,7 +63,7 @@
     public LIROp2(LIROpcode opcode, Condition condition, CiValue opr1, CiValue opr2, CiValue result) {
         super(opcode, result, null, false, 0, 0, opr1, opr2);
         this.condition = condition;
-        assert opcode == LIROpcode.Cmove : "Instruction opcode should be of type LIROpcode.Cmove";
+        assert opcode == LIROpcode.Cmove || opcode == LIROpcode.FCmove || opcode == LIROpcode.UFCmove : "Instruction opcode should be of type LIROpcode.Cmove";
     }
 
     /**
@@ -156,7 +156,7 @@
      * @return condition the condition of this instruction
      */
     public Condition condition() {
-        assert code == LIROpcode.Cmp || code == LIROpcode.Cmove : "Field access only valid for cmp and cmove";
+        assert code == LIROpcode.Cmp || code == LIROpcode.Cmove || code == LIROpcode.FCmove || code == LIROpcode.UFCmove : "Field access only valid for cmp and cmove";
         return condition;
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROpcode.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROpcode.java	Fri Aug 05 18:44:32 2011 +0200
@@ -59,6 +59,8 @@
         Ucmpfd2i,
         Cmpfd2i,
         Cmove,
+        FCmove,
+        UFCmove,
         Add,
         Sub,
         Mul,
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java	Fri Aug 05 18:44:32 2011 +0200
@@ -41,25 +41,38 @@
 
     @Override
     protected void run(Graph graph) {
-        NodeWorkList nodeWorkList = graph.createNodeWorkList(!newNodes, MAX_ITERATION_PER_NODE);
+        final NodeWorkList nodeWorkList = graph.createNodeWorkList(!newNodes, MAX_ITERATION_PER_NODE);
         if (newNodes) {
             nodeWorkList.addAll(graph.getNewNodes());
         }
+        NotifyReProcess reProcess = new NotifyReProcess() {
+            @Override
+            public void reProccess(Node n) {
+                nodeWorkList.addAgain(n);
+            }
+        };
         for (Node node : nodeWorkList) {
             CanonicalizerOp op = node.lookup(CanonicalizerOp.class);
             if (op != null) {
-                Node canonical = op.canonical(node);
+                graph.mark();
+                Node canonical = op.canonical(node, reProcess);
                 if (canonical != node) {
                     node.replaceAndDelete(canonical);
-                    nodeWorkList.replaced(canonical, node, true, EdgeType.USAGES);
-                    //System.out.println("-->" + n + " canonicalized to " + canonical);
+                    nodeWorkList.replaced(canonical, node, false, EdgeType.USAGES);
+                    for (Node newNode : graph.getNewNodes()) {
+                        nodeWorkList.add(newNode);
+                    }
                     GraalMetrics.NodesCanonicalized++;
                 }
             }
         }
     }
 
+    public interface NotifyReProcess {
+        void reProccess(Node n);
+    }
+
     public interface CanonicalizerOp extends Op {
-        Node canonical(Node node);
+        Node canonical(Node node, NotifyReProcess reProcess);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ConvertConditionalPhase.java	Fri Aug 05 18:44:32 2011 +0200
@@ -0,0 +1,138 @@
+/*
+ * 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.phases;
+
+import com.oracle.max.graal.compiler.ir.*;
+import com.oracle.max.graal.compiler.ir.Phi.PhiType;
+import com.oracle.max.graal.compiler.schedule.*;
+import com.oracle.max.graal.compiler.value.*;
+import com.oracle.max.graal.graph.*;
+
+
+/**
+ * Temporary phase that converts Conditional/Materialize Nodes that can not be LIRGenered properly for now.
+ * Currently LIRGenerating something like
+ * BRANCHcc L1 // (compare, instanceof...)
+ * mov res, fVal
+ * jmp L2
+ * L1:
+ * mov res, tVal
+ * L2:
+ *
+ * or
+ *
+ * mov res, tVal
+ * BRANCHcc L1:
+ * mov res, fVal
+ * L1:
+ *
+ * may create a few problems around register allocation:
+ * - in the first construct, register allocation may decide to spill an other variable to allocate res, resulting ina spilling that is done only in one branch :
+ * BRANCHcc L1 // (compare, instanceof...)
+ * mov SpillSplot, res
+ * mov res, fVal
+ * jmp L2
+ * L1:
+ * mov res, tVal
+ * L2:
+ *
+ * - in the second construct the register allocator will thing that the first definition of res is not used and BRANCHcc may need some temporary register
+ * the allocator could then allocate the same register for res and this temporary
+ */
+public class ConvertConditionalPhase extends Phase {
+
+    @Override
+    protected void run(Graph graph) {
+        IdentifyBlocksPhase schedule = null;
+        for (Conditional conditional  : graph.getNodes(Conditional.class)) {
+            BooleanNode condition = conditional.condition();
+            while (condition instanceof NegateBooleanNode) {
+                condition = ((NegateBooleanNode) condition).value();
+            }
+            if (!(condition instanceof Compare || condition instanceof IsNonNull || condition instanceof NegateBooleanNode || condition instanceof Constant)) {
+                If ifNode = new If(conditional.condition(), 0.5, graph);
+                EndNode trueEnd = new EndNode(graph);
+                EndNode falseEnd = new EndNode(graph);
+                ifNode.setTrueSuccessor(trueEnd);
+                ifNode.setFalseSuccessor(falseEnd);
+                Merge merge = new Merge(graph);
+                merge.addEnd(trueEnd);
+                merge.addEnd(falseEnd);
+                Phi phi = new Phi(conditional.kind, merge, PhiType.Value, graph);
+                phi.addInput(conditional.trueValue());
+                phi.addInput(conditional.falseValue());
+                //recreate framestate
+                FrameState stateDuring = conditional.stateDuring();
+                FrameStateBuilder builder = new FrameStateBuilder(stateDuring);
+                builder.push(phi.kind, phi);
+                merge.setStateAfter(builder.create(stateDuring.bci));
+                // schedule the if...
+                if (schedule == null) {
+                    schedule = new IdentifyBlocksPhase(false, false);
+                    schedule.apply(graph);
+                }
+                schedule.assignBlockToNode(conditional);
+                Block block = schedule.getNodeToBlock().get(conditional);
+                FixedNodeWithNext prev;
+                Node firstNode = block.firstNode();
+                if (firstNode instanceof Merge) {
+                    prev = (Merge) firstNode;
+                } else if (firstNode instanceof EndNode) {
+                    EndNode end = (EndNode) firstNode;
+                    Node pred = end.predecessor();
+                    Anchor anchor = new Anchor(graph);
+                    pred.replaceFirstSuccessor(end, anchor);
+                    anchor.setNext(end);
+                    prev = anchor;
+                } else if (firstNode instanceof StartNode) {
+                    StartNode start = (StartNode) firstNode;
+                    Anchor anchor = new Anchor(graph);
+                    Node next = start.next();
+                    start.setNext(null);
+                    anchor.setNext((FixedNode) next);
+                    start.setNext(anchor);
+                    prev = anchor;
+                } else if (firstNode instanceof If) {
+                    Node pred = firstNode.predecessor();
+                    Anchor anchor = new Anchor(graph);
+                    pred.replaceFirstSuccessor(firstNode, anchor);
+                    anchor.setNext((If) firstNode);
+                    prev = anchor;
+                } else {
+                    prev = (FixedNodeWithNext) firstNode;
+                }
+                FixedNode next = prev.next();
+                prev.setNext(null);
+                merge.setNext(next);
+                prev.setNext(ifNode);
+                conditional.replaceAndDelete(phi);
+            } else {
+                FrameState stateDuring = conditional.stateDuring();
+                conditional.setStateDuring(null);
+                if (stateDuring != null && stateDuring.usages().size() == 0) {
+                    stateDuring.delete();
+                }
+            }
+        }
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Fri Aug 05 18:44:32 2011 +0200
@@ -762,7 +762,9 @@
         Constant typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, type.isResolved());
         Value object = frameState.apop();
         if (typeInstruction != null) {
-            frameState.ipush(append(new MaterializeNode(new InstanceOf(typeInstruction, object, false, graph), graph)));
+            MaterializeNode materialize = new MaterializeNode(new InstanceOf(typeInstruction, object, false, graph), graph);
+            materialize.setStateDuring(frameState.create(bci()));
+            frameState.ipush(append(materialize));
         } else {
             frameState.ipush(appendConstant(CiConstant.INT_0));
         }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/RematerializationPhase.java	Fri Aug 05 15:14:03 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,286 +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.phases;
-
-import java.text.*;
-import java.util.*;
-
-import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.ir.*;
-import com.oracle.max.graal.compiler.schedule.*;
-import com.oracle.max.graal.compiler.util.*;
-import com.oracle.max.graal.graph.*;
-import com.oracle.max.graal.graph.collections.*;
-
-
-public class RematerializationPhase extends Phase {
-
-    private NodeMap<Block> nodeToBlock;
-    private HashMap<Node, Block> newNodesToBlock;
-    private List<Block> blocks;
-    private UsageProbability[] probablityCache;
-    private boolean ignoreUsages;
-
-    @Override
-    protected void run(Graph graph) {
-        Iterable<Node> modifiedNodes = graph.getModifiedNodes();
-        graph.stopRecordModifications();
-        NodeWorkList work = graph.createNodeWorkList();
-        for (Node modified : modifiedNodes) {
-            if (modified instanceof FloatingNode) {
-                work.add(modified);
-            }
-        }
-
-        if (work.isEmpty()) {
-            return;
-        }
-
-        final IdentifyBlocksPhase s = new IdentifyBlocksPhase(true);
-        s.apply(graph);
-
-        newNodesToBlock = new HashMap<Node, Block>();
-        nodeToBlock = s.getNodeToBlock();
-        blocks = s.getBlocks();
-        probablityCache = new UsageProbability[blocks.size()];
-
-        for (Node node : work) {
-            if (node instanceof Phi || node instanceof Local || node instanceof Constant || node instanceof LocationNode) {
-                continue;
-            }
-            boolean delay = false;
-            for (Node usage : node.usages()) {
-                if (usage instanceof FloatingNode && !(usage instanceof Phi) && work.isInQueue(usage)) {
-                    delay = true;
-                    break;
-                }
-            }
-            if (delay) {
-                work.addAgain(node);
-                continue;
-            }
-            Arrays.fill(probablityCache, null);
-            ignoreUsages = true;
-            Block block = nodeToBlock.get(node);
-            if (block == null) {
-                continue;
-            }
-            UsageProbability usageProbability = usageProbability(node, block);
-            if (usageProbability.probability < GraalOptions.MinimumUsageProbability) {
-                if (ignoreUsages) {
-                    ignoreUsages = false;
-                    Arrays.fill(probablityCache, null);
-                    usageProbability = usageProbability(node, block); // recompute with usage maps
-                }
-                //TTY.println("going to remarterialize " + node + " at " + block + " : " + toString(usageProbability));
-                boolean first = true;
-                for (Block sux : block.getSuccessors()) {
-                    if (first) {
-                        first = false;
-                        continue;
-                    }
-                    usageProbability = usageProbability(node, sux);
-                    List<Node> usages = new LinkedList<Node>();
-                    for (Node usage : usageProbability.usages) {
-                        usages.add(usage);
-                    }
-                    if (!usages.isEmpty()) {
-                        Node copy = node.copyWithEdges();
-                        newNodesToBlock.put(copy, sux);
-                        GraalMetrics.Rematerializations++;
-                        //TTY.println("> Rematerialized " + node + " : " + toString(usageProbability));
-                        for (Node usage : usages) {
-                            usage.inputs().replace(node, copy);
-                            if (usageProbability.phiUsages != null) {
-                                Set<Phi> phis = usageProbability.phiUsages.get(usage);
-                                if (phis != null) {
-                                    for (Phi phi : phis) {
-                                        int index = phi.merge().phiPredecessorIndex(usage);
-                                        assert phi.valueAt(index) == node;
-                                        phi.setValueAt(index, (Value) copy);
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    private UsageProbability usageProbability(Node n, Block b) {
-        UsageProbability cached = probablityCache[b.blockID()];
-        if (cached != null) {
-            return cached;
-        }
-        if (ignoreUsages) {
-            GraalMetrics.PartialUsageProbability++;
-        } else {
-            GraalMetrics.FullUsageProbability++;
-        }
-        for (Node usage : n.usages()) {
-            if (usage instanceof Phi) {
-                Phi phi = (Phi) usage;
-                Merge merge = phi.merge();
-                for (int i = 0; i < phi.valueCount(); i++) {
-                    if (phi.valueAt(i) == n) {
-                        insertUsageInCache(merge.phiPredecessorAt(i), phi);
-                    }
-                }
-            } else {
-                insertUsageInCache(usage);
-            }
-        }
-        return usageProbability0(n, b);
-    }
-
-    private void insertUsageInCache(Node usage) {
-        insertUsageInCache(usage, null);
-    }
-
-    private void insertUsageInCache(Node usage, Phi phi) {
-        Block block = block(usage);
-        if (block == null) {
-            return;
-        }
-        int blockID = block.blockID();
-        UsageProbability usageProbability = probablityCache[blockID];
-        if (usageProbability == null) {
-            usageProbability = new UsageProbability(usage);
-            probablityCache[blockID] = usageProbability;
-        } else if (!ignoreUsages) {
-            usageProbability.usages.mark(usage);
-        }
-        if (phi != null) {
-            usageProbability.addPhiUsage(phi, usage);
-        }
-    }
-
-    private Block block(Node node) {
-        Block block;
-        if (!nodeToBlock.isNew(node)) {
-            block = nodeToBlock.get(node);
-        } else {
-            block = newNodesToBlock.get(node);
-            assert block != null;
-        }
-        return block;
-    }
-
-    private UsageProbability usageProbability0(Node n, Block b) {
-        //System.out.println("usageProbability0(" + n.id() + ", " + b + ")");
-        UsageProbability cached = probablityCache[b.blockID()];
-        if (cached != null && (cached.computed || ignoreUsages)) {
-            return cached;
-        }
-        UsageProbability result = cached;
-        if (result == null) {
-            result = new UsageProbability(n.graph());
-        }
-        if (b.getSuccessors().size() > 0) {
-            if (b.isLoopEnd()) {
-                Block loopHeader = b.getSuccessors().get(0);
-                assert loopHeader.isLoopHeader();
-                UsageProbability headerUsages = probablityCache[loopHeader.blockID()];
-                if (headerUsages != null) {
-                    result.merge(headerUsages, 1.0);
-                }
-            } else if (b.getSuccessors().size() == 1) {
-                result.merge(usageProbability0(n, b.getSuccessors().get(0)), 1.0);
-            } else {
-                Node lastNode = b.lastNode();
-                if (lastNode instanceof Invoke) {
-                    result.merge(usageProbability0(n, nodeToBlock.get(((Invoke) lastNode).next())), 1.0);
-                    result.merge(usageProbability0(n, nodeToBlock.get(((Invoke) lastNode).exceptionEdge())), 0.0);
-                } else if (lastNode instanceof ControlSplit) {
-                    ControlSplit split = (ControlSplit) lastNode;
-                    for (int i = 0; i < split.blockSuccessorCount(); i++) {
-                        result.merge(usageProbability0(n, nodeToBlock.get(split.blockSuccessor(i))), split.probability(i));
-                    }
-                } else {
-                    throw Util.shouldNotReachHere();
-                }
-            }
-        }
-        probablityCache[b.blockID()] = result;
-        result.computed = true;
-        return result;
-    }
-
-    private class UsageProbability {
-        double probability;
-        NodeBitMap usages;
-        NodeMap<Set<Phi>> phiUsages;
-        boolean computed;
-
-        public UsageProbability(Node usage) {
-            if (!ignoreUsages) {
-                usages = usage.graph().createNodeBitMap();
-                usages.mark(usage);
-            }
-            probability = 1.0;
-        }
-
-        public UsageProbability(Graph graph) {
-            if (!ignoreUsages) {
-                usages = graph.createNodeBitMap();
-            }
-            probability = 0.0;
-        }
-
-        public void merge(UsageProbability sux, double suxProbability) {
-            if (!ignoreUsages) {
-                usages.setUnion(sux.usages);
-            }
-            probability += suxProbability * sux.probability;
-        }
-
-        public void addPhiUsage(Phi phi, Node usage) {
-            if (phiUsages == null) {
-                phiUsages = phi.graph().createNodeMap();
-            }
-            Set<Phi> phis = phiUsages.get(usage);
-            if (phis == null) {
-                phis = new HashSet<Phi>(2);
-                phiUsages.set(usage, phis);
-            }
-            phis.add(phi);
-        }
-    }
-
-    private String toString(UsageProbability up) {
-        NumberFormat nf = NumberFormat.getPercentInstance();
-        StringBuilder sb = new StringBuilder("p=");
-        sb.append(nf.format(up.probability));
-        if (up.usages != null) {
-            sb.append(" U=[");
-            for (Node n : up.usages) {
-                sb.append(n);
-                sb.append(", ");
-            }
-            sb.append("]");
-        }
-        return sb.toString();
-    }
-}
-
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java	Fri Aug 05 18:44:32 2011 +0200
@@ -26,7 +26,6 @@
 
 import com.oracle.max.graal.compiler.ir.*;
 import com.oracle.max.graal.graph.*;
-import com.oracle.max.graal.graph.collections.*;
 
 
 public class Block {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java	Fri Aug 05 18:44:32 2011 +0200
@@ -314,7 +314,7 @@
         }
     }
 
-    private void assignBlockToNode(Node n) {
+    public void assignBlockToNode(Node n) {
         if (n == null) {
             return;
         }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java	Fri Aug 05 18:44:32 2011 +0200
@@ -533,15 +533,17 @@
                 } else {
                     unorderedLabel = op.unorderedBlock().label;
                 }
-                masm.jcc(ConditionFlag.parity, unorderedLabel);
+                if (unorderedLabel != op.label() || !trueOnUnordered(op.cond())) {
+                    masm.jcc(ConditionFlag.parity, unorderedLabel);
+                }
                 // Checkstyle: off
                 switch (op.cond()) {
                     case EQ : acond = ConditionFlag.equal; break;
                     case NE : acond = ConditionFlag.notEqual; break;
-                    case LT : acond = ConditionFlag.below; break;
-                    case LE : acond = ConditionFlag.belowEqual; break;
-                    case GE : acond = ConditionFlag.aboveEqual; break;
-                    case GT : acond = ConditionFlag.above; break;
+                    case BT : acond = ConditionFlag.below; break;
+                    case BE : acond = ConditionFlag.belowEqual; break;
+                    case AE : acond = ConditionFlag.aboveEqual; break;
+                    case AT : acond = ConditionFlag.above; break;
                     default : throw Util.shouldNotReachHere();
                 }
             } else {
@@ -710,7 +712,8 @@
     }
 
     @Override
-    protected void emitConditionalMove(Condition condition, CiValue opr1, CiValue opr2, CiValue result) {
+    protected void emitConditionalMove(Condition condition, CiValue opr1, CiValue opr2, CiValue result, boolean mayBeUnordered, boolean unorderedcmovOpr1) {
+        //TTY.println("cmov " + condition + " " + opr1 + " : " + opr2 + " mayBeUnordered:" + mayBeUnordered + " pcmovop=" + (unorderedcmovOpr1 ? 1 : 2));
         ConditionFlag acond;
         ConditionFlag ncond;
         switch (condition) {
@@ -754,6 +757,14 @@
                 acond = ConditionFlag.above;
                 ncond = ConditionFlag.belowEqual;
                 break;
+            case OF:
+                acond = ConditionFlag.overflow;
+                ncond = ConditionFlag.noOverflow;
+                break;
+            case NOF:
+                acond = ConditionFlag.noOverflow;
+                ncond = ConditionFlag.overflow;
+                break;
             default:
                 throw Util.shouldNotReachHere();
         }
@@ -766,13 +777,17 @@
             def = opr2;
             other = opr1;
             // and flip the condition
+            condition = condition.negate();
             ConditionFlag tcond = acond;
             acond = ncond;
             ncond = tcond;
+            unorderedcmovOpr1 = !unorderedcmovOpr1;
         }
 
         if (def.isRegister()) {
-            reg2reg(def, result);
+            if (def.asRegister() != result.asRegister()) {
+                reg2reg(def, result);
+            }
         } else if (def.isStackSlot()) {
             stack2reg(def, result, result.kind);
         } else {
@@ -780,29 +795,24 @@
             const2reg(def, result, null);
         }
 
-        if (!other.isConstant()) {
+        boolean cmovOnParity = (unorderedcmovOpr1 && mayBeTrueOnUnordered(condition.negate())) || (!unorderedcmovOpr1 && mayBeFalseOnUnordered(condition.negate()));
+        if (!other.isConstant() && !(cmovOnParity && def.isConstant())) {
             // optimized version that does not require a branch
-            if (other.isRegister()) {
-                assert other.asRegister() != result.asRegister() : "other already overwritten by previous move";
-                if (other.kind.isInt()) {
-                    masm.cmovq(ncond, result.asRegister(), other.asRegister());
-                } else {
-                    masm.cmovq(ncond, result.asRegister(), other.asRegister());
-                }
-            } else {
-                assert other.isStackSlot();
-                CiStackSlot otherSlot = (CiStackSlot) other;
-                if (other.kind.isInt()) {
-                    masm.cmovl(ncond, result.asRegister(), frameMap.toStackAddress(otherSlot));
-                } else {
-                    masm.cmovq(ncond, result.asRegister(), frameMap.toStackAddress(otherSlot));
-                }
+            //TTY.println("> emitting cmov" + (mayBeUnordered && cmovOnParity ? " (with parity check)" : ""));
+            cmov(result, ncond, other);
+            if (mayBeUnordered && cmovOnParity) {
+                cmov(result, ConditionFlag.parity, unorderedcmovOpr1 ? def : other);
             }
-
         } else {
+            //TTY.println("> emitting jumps instead of cmov");
             // conditional move not available, use emit a branch and move
             Label skip = new Label();
+            Label mov = new Label();
+            if (mayBeUnordered && ((mayBeTrueOnUnordered(condition) && !unorderedcmovOpr1) || (mayBeFalseOnUnordered(condition) && unorderedcmovOpr1))) {
+                masm.jcc(ConditionFlag.parity, unorderedcmovOpr1 ? skip : mov);
+            }
             masm.jcc(acond, skip);
+            masm.bind(mov);
             if (other.isRegister()) {
                 reg2reg(other, result);
             } else if (other.isStackSlot()) {
@@ -815,6 +825,25 @@
         }
     }
 
+    private void cmov(CiValue result, ConditionFlag ncond, CiValue other) {
+        if (other.isRegister()) {
+            assert other.asRegister() != result.asRegister() : "other already overwritten by previous move";
+            if (other.kind.isInt()) {
+                masm.cmovl(ncond, result.asRegister(), other.asRegister());
+            } else {
+                masm.cmovq(ncond, result.asRegister(), other.asRegister());
+            }
+        } else {
+            assert other.isStackSlot();
+            CiStackSlot otherSlot = (CiStackSlot) other;
+            if (other.kind.isInt()) {
+                masm.cmovl(ncond, result.asRegister(), frameMap.toStackAddress(otherSlot));
+            } else {
+                masm.cmovq(ncond, result.asRegister(), frameMap.toStackAddress(otherSlot));
+            }
+        }
+    }
+
     @Override
     protected void emitArithOp(LIROpcode code, CiValue left, CiValue right, CiValue dest, LIRDebugInfo info) {
         assert info == null : "should never be used :  idiv/irem and ldiv/lrem not handled by this method";
@@ -1260,8 +1289,8 @@
                     case Double  : masm.ucomisd(reg1, tasm.recordDataReferenceInCode(CiConstant.forDouble(((CiConstant) opr2).asDouble()))); break;
                     case Long    :
                     case Word    : {
-                        if (c.asLong() == 0) {
-                            masm.cmpq(reg1, 0);
+                        if (NumUtil.isInt(c.asLong())) {
+                            masm.cmpq(reg1, (int) c.asLong());
                         } else {
                             masm.movq(rscratch1, c.asLong());
                             masm.cmpq(reg1, rscratch1);
@@ -1291,10 +1320,21 @@
                     case Short   :
                     case Int     : masm.cmpl(left, right.asInt()); break;
                     case Long    :
-                    case Word    : assert NumUtil.isInt(right.asLong());
-                                   masm.cmpq(left, right.asInt()); break;
-                    case Object  : assert right.isNull();
-                                   masm.cmpq(left, 0); break;
+                    case Word    : if (NumUtil.isInt(right.asLong())) {
+                                       masm.cmpq(left, (int) right.asLong());
+                                   } else {
+                                       masm.movq(rscratch1, right.asLong());
+                                       masm.cmpq(left, rscratch1);
+
+                                   }
+                                   break;
+                    case Object  : if (right.isNull()) {
+                                       masm.cmpq(left, 0);
+                                   } else {
+                                       movoop(rscratch1, right);
+                                       masm.cmpq(left, rscratch1);
+                                   }
+                                   break;
                     default      : throw Util.shouldNotReachHere();
                 }
             } else {
@@ -2225,6 +2265,51 @@
         tasm.recordExceptionHandlers(after, info);
     }
 
+    @Override
+    public boolean falseOnUnordered(Condition condition) {
+        switch(condition) {
+            case AE:
+            case NE:
+            case GT:
+            case AT:
+                return true;
+            case EQ:
+            case LE:
+            case BE:
+            case BT:
+            case LT:
+            case GE:
+            case OF:
+            case NOF:
+                return false;
+            default:
+                throw Util.shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public boolean trueOnUnordered(Condition condition) {
+        switch(condition) {
+            case AE:
+            case NE:
+            case GT:
+            case AT:
+                return false;
+            case EQ:
+            case LE:
+            case BE:
+            case BT:
+                return true;
+            case LT:
+            case GE:
+            case OF:
+            case NOF:
+                return false;
+            default:
+                throw Util.shouldNotReachHere();
+        }
+    }
+
     protected void stop(String msg) {
         if (GraalOptions.GenAssertionCode) {
             // TODO: pass a pointer to the message
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Fri Aug 05 18:44:32 2011 +0200
@@ -71,12 +71,12 @@
     }
 
     @Override
-    protected boolean canInlineAsConstant(Value v) {
+    public boolean canInlineAsConstant(Value v) {
+        if (!v.isConstant()) {
+            return false;
+        }
         if (v.kind == CiKind.Long) {
-            if (v.isConstant() && NumUtil.isInt(v.asConstant().asLong())) {
-                return true;
-            }
-            return false;
+            return NumUtil.isInt(v.asConstant().asLong());
         }
         return v.kind != CiKind.Object || v.isNullConstant();
     }
@@ -408,7 +408,7 @@
     }
 
     @Override
-    public void visitMaterialize(NormalizeCompare x) {
+    public void visitNormalizeCompare(NormalizeCompare x) {
         LIRItem left = new LIRItem(x.x(), this);
         LIRItem right = new LIRItem(x.y(), this);
         if (!x.kind.isVoid() && x.x().kind.isLong()) {
@@ -463,4 +463,20 @@
     public void visitValueAnchor(ValueAnchor valueAnchor) {
         // nothing to do for ValueAnchors
     }
+
+    @Override
+    public Condition floatingPointCondition(Condition cond) {
+        switch(cond) {
+            case LT:
+                return Condition.BT;
+            case LE:
+                return Condition.BE;
+            case GT:
+                return Condition.AT;
+            case GE:
+                return Condition.AE;
+            default :
+                return cond;
+        }
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/BitMap2D.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/BitMap2D.java	Fri Aug 05 18:44:32 2011 +0200
@@ -23,7 +23,6 @@
 package com.oracle.max.graal.compiler.util;
 
 import com.oracle.max.graal.graph.*;
-import com.oracle.max.graal.graph.collections.*;
 
 /**
  * This class implements a two-dimensional bitmap.
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/GraphUtil.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/GraphUtil.java	Fri Aug 05 18:44:32 2011 +0200
@@ -31,8 +31,9 @@
 import com.oracle.max.graal.compiler.observer.*;
 import com.oracle.max.graal.compiler.value.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.graph.NodeClass.*;
 import com.oracle.max.graal.graph.collections.*;
-import com.oracle.max.graal.graph.collections.NodeWorkList.*;
+import com.oracle.max.graal.graph.collections.NodeWorkList.InfiniteWorkException;
 
 public class GraphUtil {
 
@@ -87,17 +88,12 @@
     }
 
     private static <T> Collection<Merge> colorCFGDownToMerge(Node from, T color, NodeMap<T> colors) {
-        throw new UnsupportedOperationException();
-        /*
-        //System.out.println("colorCFGDownToMerge(" + from + ", " + color + ", colors)");
         NodeFlood work = from.graph().createNodeFlood();
         Collection<Merge> merges = new LinkedList<Merge>();
         work.add(from);
         for (Node node : work) {
-            //System.out.println("colorToMerge : work on " + node);
             Node current = node;
             while (current != null) {
-                //System.out.println("colorToMerge : current " + current);
                 if (current instanceof Merge) {
                     merges.add((Merge) current);
                     break;
@@ -126,8 +122,7 @@
                 }
             }
         }
-        //System.out.println("return " + merges);
-        return merges;*/
+        return merges;
     }
 
     public static interface ColorSplitingLambda<T> {
@@ -141,8 +136,6 @@
 
     // TODO (gd) rework that code around Phi handling : too complicated
     public static <T> void splitFromColoring(NodeMap<T> coloring, ColorSplitingLambda<T> lambda) {
-        throw new UnsupportedOperationException();
-        /*
         Map<Node, T> internalColoring = new HashMap<Node, T>();
         NodeWorkList work = coloring.graph().createNodeWorkList();
         for (Entry<Node, T> entry : coloring.entries()) {
@@ -154,7 +147,6 @@
         Set<T> colors = new HashSet<T>();
         try {
             for (Node node : work) {
-                //System.out.println("Split : work on " + node);
                 if (node instanceof Phi) {
                     Phi phi = (Phi) node;
                     Merge merge = phi.merge();
@@ -168,7 +160,6 @@
                                     phi.setValueAt(i, replace);
                                 } else {
                                     if (lambda.explore(v) && coloring.get(v) == null && !work.isNew(v)) {
-                                        //System.out.println("Split : Add input " + input + " to work from " + node);
                                         work.add(v);
                                     }
                                 }
@@ -180,7 +171,6 @@
                     colors.clear();
                     T originalColoringColor = coloring.get(node);
                     if (originalColoringColor == null && internalColoring.get(node) != null) {
-                        //System.out.println("Split : ori == null && intern != null -> continue");
                         continue;
                     }
                     if (originalColoringColor == null) {
@@ -188,7 +178,6 @@
                             if (usage instanceof Phi) {
                                 Phi phi = (Phi) usage;
                                 Merge merge = phi.merge();
-                                //System.out.println("Split merge : " + merge + ".endCount = " + merge.endCount() + " phi " + phi + ".valueCount : " + phi.valueCount());
                                 for (int i = 0; i < phi.valueCount(); i++) {
                                     Value v = phi.valueAt(i);
                                     if (v == node) {
@@ -201,7 +190,6 @@
                             } else {
                                 T color = internalColoring.get(usage);
                                 if (color == null) {
-                                    //System.out.println("Split : color from " + usage + " is null : " + (lambda.explore(usage) ? "Should be colored" : "Should be white"));
                                     if (lambda.explore(usage)) {
                                         delay = true;
                                         break;
@@ -212,7 +200,6 @@
                             }
                         }
                         if (delay) {
-                            //System.out.println("Split : delay");
                             work.addAgain(node);
                             continue;
                         }
@@ -220,7 +207,6 @@
                         colors.add(originalColoringColor);
                     }
                     if (colors.size() == 1) {
-                        //System.out.println("Split : 1 color, coloring, fixing");
                         T color = colors.iterator().next();
                         internalColoring.put(node, color);
                         lambda.fixNode(node, color);
@@ -246,18 +232,18 @@
                                 Phi phi = new Phi(((Value) node).kind, lambda.merge(color), PhiType.Value, node.graph());
                                 for (T parentColor : parentColors) {
                                     Node input = newNodes.get(parentColor);
-                                    phi.addInput(input);
+                                    phi.addInput((Value) input);
                                 }
                                 newNode = phi;
                             } else {
-                                newNode = node.copy();
-                                for (int i = 0; i < node.inputs().size(); i++) {
-                                    Node input = node.inputs().get(i);
-                                    newNode.inputs().setOrExpand(i, input);
+                                newNode = node.copy(node.graph());
+                                for (NodeClassIterator iter = node.inputs().iterator(); iter.hasNext();) {
+                                    Position pos = iter.nextPosition();
+                                    newNode.set(pos, node.get(pos));
                                 }
-                                for (int i = 0; i < node.successors().size(); i++) {
-                                    Node input = node.successors().get(i);
-                                    newNode.successors().setOrExpand(i, input);
+                                for (NodeClassIterator iter = node.successors().iterator(); iter.hasNext();) {
+                                    Position pos = iter.nextPosition();
+                                    newNode.set(pos, node.get(pos));
                                 }
                                 internalColoring.put(newNode, color);
                                 lambda.fixSplit(node, newNode, color);
@@ -288,12 +274,11 @@
                                 }
                             }
                         }
-                        lambda.fixNode(node, null*/ /*white*/ /*);
+                        lambda.fixNode(node, null /*white*/);
                     }
                     if (node instanceof StateSplit) {
                         FrameState stateAfter = ((StateSplit) node).stateAfter();
                         if (stateAfter != null && lambda.explore(stateAfter) && !work.isNew(stateAfter)) {
-                            //System.out.println("Split : Add framestate to work");
                             if (!(node instanceof Merge && coloring.get(((Merge) node).next()) == null)) { // not dangling colored merge
                                 work.add(stateAfter);
                             }
@@ -314,7 +299,6 @@
 
                     for (Node input : node.dataInputs()) {
                         if (lambda.explore(input) && coloring.get(input) == null && !work.isNew(input)) {
-                            //System.out.println("Split : Add input " + input + " to work from " + node);
                             work.add(input);
                         }
                     }
@@ -346,6 +330,6 @@
             Map<String, Object> debug = new HashMap<String, Object>();
             debug.put("split", debugColoring);
             compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "Split end!!", coloring.graph(), true, false, debug));
-        }*/
+        }
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java	Fri Aug 05 18:44:32 2011 +0200
@@ -277,32 +277,13 @@
         LoopEnd loopEnd = loop.loopBegin().loopEnd();
         PeelingResult peeling = preparePeeling(loop, loopEnd);
         GraalCompilation compilation = GraalCompilation.compilation();
+
         if (compilation.compiler.isObserved()) {
             compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After peeling preparation", loopEnd.graph(), true, false));
         }
-        /*System.out.println("Peeling : ");
-        System.out.println(" begin = " + peeling.begin);
-        System.out.println(" end = " + peeling.end);
-        System.out.println(" Phis :");
-        for (Entry<Node, Placeholder> entry : peeling.phis.entries()) {
-            System.out.println("  - " + entry.getKey() + " -> " + entry.getValue());
-        }
-        System.out.println(" Exits :");
-        for (Entry<Node, StateSplit> entry : peeling.exits.entries()) {
-            System.out.println("  - " + entry.getKey() + " -> " + entry.getValue());
-        }
-        System.out.println(" PhiInits :");
-        for (Entry<Node, Node> entry : peeling.phiInits.entries()) {
-            System.out.println("  - " + entry.getKey() + " -> " + entry.getValue());
-        }
-        System.out.println(" DataOut :");
-        for (Entry<Node, Node> entry : peeling.dataOut.entries()) {
-            System.out.println("  - " + entry.getKey() + " -> " + entry.getValue());
-        }*/
+
         rewirePeeling(peeling, loop);
-        /*if (compilation.compiler.isObserved()) {
-            compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After rewirePeeling", loopEnd.graph(), true, false));
-        }*/
+
         loop.invalidateCached();
         // update parents
         Loop parent = loop.parent();
@@ -333,8 +314,6 @@
         if (originalLast == loopBegin.loopEnd()) {
             originalLast = loopBegin.loopEnd().predecessor();
         }
-        for (Node sux : originalLast.successors()) {
-        }
         boolean found = false;
         for (NodeClassIterator iter = originalLast.successors().iterator(); iter.hasNext();) {
             Position pos = iter.nextPosition();
@@ -358,7 +337,6 @@
             for (Entry<Node, Node> dataEntry : peeling.dataOut.entries()) {
                 if (dataEntry.getValue() == p) {
                     dataEntry.setValue(init);
-                    //System.out.println("Patch dataOut : " + dataEntry.getKey() + " -> " + dataEntry.getValue());
                 }
             }
         }
@@ -486,14 +464,6 @@
             colors.set(exitPoint, exitPoint);
         }
 
-        /*System.out.println("newExitValues");
-        for (Entry<Node, NodeMap<Value>> entry : newExitValues.entries()) {
-            System.out.println(" - " + entry.getKey() + " :");
-            for (Entry<Node, Value> entry2 : entry.getValue().entries()) {
-                System.out.println("    + " + entry2.getKey() + " -> " + entry2.getValue());
-            }
-        }*/
-
         // color
         GraphUtil.colorCFGDown(colors, new ColoringLambda<Node>() {
             @Override
@@ -550,7 +520,6 @@
             private Value getValueAt(Node point, NodeMap<Value> valueMap, CiKind kind) {
                 Value value = valueMap.get(point);
                 if (value != null) {
-                    //System.out.println("getValueAt(" + point + ", valueMap, kind) = (cached) " + value);
                     return value;
                 }
                 Merge merge = (Merge) point;
@@ -572,24 +541,16 @@
                     for (EndNode end : merge.cfgPredecessors()) {
                         phi.addInput(getValueAt(colors.get(end), valueMap, kind));
                     }
-                    //System.out.println("getValueAt(" + point + ", valueMap, kind) = (new-phi) " + phi);
                     return phi;
                 } else {
                     assert v != null;
                     valueMap.set(point, v);
-                    //System.out.println("getValueAt(" + point + ", valueMap, kind) = (unique) " + v);
                     return v;
                 }
             }
             @Override
             public boolean explore(Node n) {
-                /*System.out.println("Explore " + n + "?");
-                System.out.println(" - exitFS : " + (!exitFrameStates.isNew(n) && exitFrameStates.isMarked(n)));
-                System.out.println(" - !inOrBefore : " + (!inOrBefore.isNew(n) && !inOrBefore.isMarked(n)));
-                System.out.println(" - inputs > 0 : " + (n.inputs().size() > 0));
-                System.out.println(" - !danglingMergeFrameState : " + (!danglingMergeFrameState(n)));*/
-                return exitFrameStates.isNotNewMarked(n)
-                || (inOrBefore.isNotNewNotMarked(n) && n.inputs().explicitCount() > 0 && !afterColoringFramestate(n)); //TODO (gd) hum
+                return exitFrameStates.isNotNewMarked(n) || (inOrBefore.isNotNewNotMarked(n) && n.getNodeClass().directInputCount() > 0 && !afterColoringFramestate(n)); //TODO (gd) hum
             }
             public boolean afterColoringFramestate(Node n) {
                 if (!(n instanceof FrameState)) {
@@ -613,7 +574,6 @@
             }
             @Override
             public void fixNode(Node node, Node color) {
-                //System.out.println("fixNode(" + node + ", " + color + ")");
                 if (color == null) {
                     // 'white' it out : make non-explorable
                     if (!exitFrameStates.isNew(node)) {
@@ -663,22 +623,12 @@
                 return (Merge) color;
             }
         });
-
-        /*if (compilation.compiler.isObserved()) {
-            compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After split from colors", graph, true, false));
-        }*/
     }
 
     private static PeelingResult preparePeeling(Loop loop, FixedNode from) {
         LoopBegin loopBegin = loop.loopBegin();
         Graph graph = loopBegin.graph();
         NodeBitMap marked = computeLoopNodesFrom(loop, from);
-        GraalCompilation compilation = GraalCompilation.compilation();
-        /*if (compilation.compiler.isObserved()) {
-            Map<String, Object> debug = new HashMap<String, Object>();
-            debug.put("marked", marked);
-            compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After computeLoopNodesFrom", loopBegin.graph(), true, false, debug));
-        }*/
         if (from == loopBegin.loopEnd()) {
             clearWithState(from, marked);
         }
@@ -731,20 +681,8 @@
             }
         }
 
-        //GraalCompilation compilation = GraalCompilation.compilation();
-        if (compilation.compiler.isObserved()) {
-            Map<String, Object> debug = new HashMap<String, Object>();
-            debug.put("marked", marked);
-            compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "Before addDuplicate loop#" + loopBegin.id(), loopBegin.graph(), true, false, debug));
-        }
-
         Map<Node, Node> duplicates = graph.addDuplicate(marked, replacements);
 
-        /*System.out.println("Dup mapping :");
-        for (Entry<Node, Node> entry : duplicates.entrySet()) {
-            System.out.println(" - " + entry.getKey().id() + " -> " + entry.getValue().id());
-        }*/
-
         NodeMap<Node> dataOutMapping = graph.createNodeMap();
         for (Node n : dataOut) {
             Node newOut = duplicates.get(n);
@@ -812,7 +750,6 @@
         NodeFlood work = graph.createNodeFlood();
         work.addAll(cfgNodes);
         for (Node n : work) {
-            //inOrAfter.mark(n);
             markWithState(n, inOrAfter);
             if (full) {
                 for (Node sux : n.successors()) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java	Fri Aug 05 18:44:32 2011 +0200
@@ -47,6 +47,16 @@
 
     private final RiMethod method;
 
+    public FrameStateBuilder(FrameState fs) {
+        this.method = fs.method;
+        this.graph = fs.graph();
+        this.locals = new Value[method.maxLocals()];
+        int stackSize = Math.max(1, method.maxStackSize());
+        this.stack = new Value[stackSize];
+        this.locks = new ArrayList<Value>();
+        this.initializeFrom(fs);
+    }
+
     public FrameStateBuilder(RiMethod method, Graph graph) {
         assert graph != null;
         this.method = method;
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java	Fri Aug 05 18:44:32 2011 +0200
@@ -514,7 +514,7 @@
                     graph.setReturn(ret);
                     return graph;
                 }
-            } else if (holderName.equals("Ljava/lang/Float;")) {
+            } else if (holderName.equals("Ljava/lang/Float;")) { //XXX (gd) the non-raw versions of (F/D)2(I/L) should return a sanitized NaN in the NaN case. also check NaN case for (I/L)2(F/D)
                 if (fullName.equals("floatToRawIntBits(F)I") || fullName.equals("floatToIntBits(F)I")) {
                     CompilerGraph graph = new CompilerGraph(this);
                     Return ret = new Return(new FPConversionNode(CiKind.Int, new Local(CiKind.Float, 0, graph), graph), graph);
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FPConversionNode.java	Fri Aug 05 15:14:03 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FPConversionNode.java	Fri Aug 05 18:44:32 2011 +0200
@@ -24,7 +24,9 @@
 
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.compiler.gen.*;
+import com.oracle.max.graal.compiler.gen.LIRGenerator.LIRGeneratorOp;
 import com.oracle.max.graal.compiler.ir.*;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 
@@ -52,17 +54,11 @@
     @SuppressWarnings("unchecked")
     @Override
     public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == LIRGenerator.LIRGeneratorOp.class) {
-            return (T) new LIRGenerator.LIRGeneratorOp() {
-                @Override
-                public void generate(Node n, LIRGenerator generator) {
-                    FPConversionNode conv = (FPConversionNode) n;
-                    CiValue reg = generator.createResultVariable(conv);
-                    CiValue value = generator.load(conv.value());
-                    CiValue tmp = generator.forceToSpill(value, conv.kind, false);
-                    generator.lir().move(tmp, reg);
-                }
-            };
+        if (clazz == LIRGeneratorOp.class) {
+            return (T) LIRGEN;
+        }
+        if (clazz == CanonicalizerOp.class) {
+            return (T) CANON;
         }
         return super.lookup(clazz);
     }
@@ -81,4 +77,37 @@
     public Node copy(Graph into) {
         return new FPConversionNode(kind, null, into);
     }
+
+    private static final CanonicalizerOp CANON = new CanonicalizerOp() {
+        @Override
+        public Node canonical(Node node, NotifyReProcess reProcess) {
+            FPConversionNode conv = (FPConversionNode) node;
+            Value value = conv.value();
+            if (value instanceof Constant) {
+                CiKind toKind = conv.kind;
+                CiKind fromKind = value.kind;
+                if (toKind == CiKind.Int && fromKind == CiKind.Float) {
+                    return Constant.forInt(Float.floatToRawIntBits(((Constant) value).asConstant().asFloat()), node.graph());
+                } else if (toKind == CiKind.Long && fromKind == CiKind.Double) {
+                    return Constant.forLong(Double.doubleToRawLongBits(((Constant) value).asConstant().asDouble()), node.graph());
+                } else if (toKind == CiKind.Float && fromKind == CiKind.Int) {
+                    return Constant.forFloat(Float.intBitsToFloat(((Constant) value).asConstant().asInt()), node.graph());
+                } else if (toKind == CiKind.Double && fromKind == CiKind.Long) {
+                    return Constant.forDouble(Double.longBitsToDouble(((Constant) value).asConstant().asLong()), node.graph());
+                }
+            }
+            return conv;
+        }
+    };
+
+    private static final LIRGeneratorOp LIRGEN = new LIRGeneratorOp() {
+        @Override
+        public void generate(Node n, LIRGenerator generator) {
+            FPConversionNode conv = (FPConversionNode) n;
+            CiValue reg = generator.createResultVariable(conv);
+            CiValue value = generator.load(conv.value());
+            CiValue tmp = generator.forceToSpill(value, conv.kind, false);
+            generator.lir().move(tmp, reg);
+        }
+    };
 }