changeset 3490:ce7cf6d16b38

Reintroduce Conditional (IfOp) using the new infrastructure, fix the Cmov support in the backend, use x86 cmov when possible, make it work with floating point comparison conditions, make MaterializeNode a subclass of Conditional, fix nasty bug related to introducing LIR jumps in an existing LIRBlock in MaterializeNode/Conditional Canonicalize FDConversionNode if input is constant
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Fri, 05 Aug 2011 17:40:35 +0200
parents a64b615ba630
children 2ae2861243b1
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/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/And.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/Condition.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/FloatAdd.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatDiv.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatMul.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatRem.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatSub.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/IntegerAdd.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerDiv.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerMul.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerRem.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.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/LeftShift.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/Or.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/ir/RightShift.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/UnsignedRightShift.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Xor.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRAssembler.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRList.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROp2.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROpcode.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/phases/RematerializationPhase.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/target/amd64/AMD64LIRGenerator.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.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.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 54 files changed, 621 insertions(+), 579 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java	Fri Aug 05 17:40:35 2011 +0200
@@ -246,7 +246,6 @@
             if (GraalOptions.Time) {
                 GraalTimers.LIR_CREATE.stop();
             }
-
             if (GraalOptions.PrintLIR && !TTY.isSuppressed()) {
                 LIRList.printLIR(hir.linearScanOrder());
             }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Fri Aug 05 17:40:35 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();
@@ -1858,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/And.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ArrayLength.java	Fri Aug 05 17:40:35 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.*;
@@ -109,7 +110,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java	Fri Aug 05 17:40:35 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.*;
@@ -97,7 +98,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java	Fri Aug 05 17:40:35 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.*;
@@ -77,8 +79,8 @@
         return (Value) inputs().set(super.inputCount() + INPUT_Y, n);
     }
 
-    Condition condition;
-    boolean unorderedIsTrue;
+    private Condition condition;
+    private boolean unorderedIsTrue;
 
     /**
      * Constructs a new Compare instruction.
@@ -131,6 +133,11 @@
         setY(t);
     }
 
+    public void negate() {
+        condition = condition.negate();
+        unorderedIsTrue = !unorderedIsTrue;
+    }
+
     @Override
     public void accept(ValueVisitor v) {
     }
@@ -160,6 +167,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;
@@ -168,17 +182,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);
@@ -219,6 +230,20 @@
                     }
                 }
             }
+            boolean allUsagesNegate = true;
+            List<Node> usages = new ArrayList<Node>(compare.usages());
+            for (Node usage : usages) {
+                if (!(usage instanceof NegateBooleanNode)) {
+                    allUsagesNegate = false;
+                    break;
+                }
+            }
+            if (allUsagesNegate) {
+                compare.negate();
+                for (Node usage : usages) {
+                    usage.replaceAtUsages(compare);
+                }
+            }
             return compare;
         }
 
@@ -229,7 +254,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Condition.java	Fri Aug 05 17:40:35 2011 +0200
@@ -171,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: {
@@ -211,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Conditional.java	Fri Aug 05 17:40:35 2011 +0200
@@ -22,12 +22,14 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
-import com.oracle.max.asm.*;
+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.lir.*;
 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.*;
@@ -37,10 +39,11 @@
  * Note that these nodes are not built directly from the bytecode but are introduced
  * by conditional expression elimination.
  */
-public final class Conditional extends Binary {
+public class Conditional extends Binary {
 
-    private static final int INPUT_COUNT = 1;
+    private static final int INPUT_COUNT = 2;
     private static final int INPUT_CONDITION = 0;
+    private static final int INPUT_STATE = 1;
 
     private static final int SUCCESSOR_COUNT = 0;
 
@@ -62,6 +65,14 @@
         inputs().set(super.inputCount() + INPUT_CONDITION, n);
     }
 
+    public FrameState stateDuring() {
+        return (FrameState) inputs().get(super.inputCount() + INPUT_STATE);
+    }
+
+    public void setStateDuring(FrameState n) {
+        inputs().set(super.inputCount() + INPUT_STATE, n);
+    }
+
     /**
      * Constructs a new IfOp.
      * @param x the instruction producing the first value to be compared
@@ -89,6 +100,14 @@
         return y();
     }
 
+    public Value setTrueValue(Value value) {
+        return setX(value);
+    }
+
+    public Value setFalseValue(Value value) {
+        return setY(value);
+    }
+
     @Override
     public boolean valueEqual(Node i) {
         if (i instanceof Conditional) {
@@ -130,7 +149,7 @@
 
     private static final CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             Conditional conditional = (Conditional) node;
             BooleanNode condition = conditional.condition();
             Value trueValue = conditional.trueValue();
@@ -146,17 +165,31 @@
             if (trueValue == falseValue) {
                 return trueValue;
             }
-            if (trueValue instanceof Constant && falseValue instanceof Constant
+            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) {
-                    TTY.println("> Conditional canon'ed to Materialize");
-                    return new MaterializeNode(new NegateBooleanNode(condition, node.graph()), node.graph());
+                    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) {
-                    TTY.println("> Conditional canon'ed to Materialize");
-                    return new MaterializeNode(condition, node.graph());
+                    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;
         }
@@ -174,39 +207,52 @@
             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);
                 }
-                cond = compare.condition;
             } 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);
-                generator.lir().cmove(cond, tVal, fVal, result);
-            } else {
-                LIRBlock trueSuccessor = new LIRBlock(new Label(), null);
-                generator.emitBooleanBranch(condition, trueSuccessor, null, null);
-                LIRList lir = generator.lir();
-                lir.move(fVal, result);
-                Label label = new Label();
-                lir.branch(Condition.TRUE, label);
-                lir.branchDestination(trueSuccessor.label);
-                lir.move(tVal, result);
-                lir.branchDestination(label);
+                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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java	Fri Aug 05 17:40:35 2011 +0200
@@ -28,6 +28,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.*;
 
@@ -77,7 +78,7 @@
 
     private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
         @Override
-        public Node canonical(Node node) {
+        public Node canonical(Node node, NotifyReProcess reProcess) {
             FixedGuard fixedGuard = (FixedGuard) node;
             Iterator<Node> iter = fixedGuard.variableInputs().iterator();
             while (iter.hasNext()) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatAdd.java	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatAdd.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatDiv.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatMul.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatRem.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatSub.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java	Fri Aug 05 17:40:35 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.*;
@@ -45,7 +46,7 @@
     }
 
     /**
-     * The instruction that produces the object tested against null.
+     * The instruction that produces the tested boolean value.
      */
     public BooleanNode node() {
         return (BooleanNode) inputs().get(super.inputCount() + INPUT_NODE);
@@ -91,7 +92,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java	Fri Aug 05 17:40:35 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.*;
 
@@ -146,7 +147,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();
@@ -165,15 +166,22 @@
             if (ifNode.trueSuccessor() instanceof EndNode && ifNode.falseSuccessor() instanceof EndNode) {
                 EndNode trueEnd = (EndNode) ifNode.trueSuccessor();
                 EndNode falseEnd = (EndNode) ifNode.falseSuccessor();
-                if (trueEnd.merge() == falseEnd.merge() && trueEnd.merge().phis().size() == 0) {
+                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() ?
-                        TTY.println("> Useless if with side effects Canon'ed to guard");
-                        FixedGuard guard = new FixedGuard(ifNode.compare(), node.graph());
-                        guard.setNext(trueEnd.merge().next());
-                        return guard;
+                        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 {
-                        TTY.println("> Useless if Canon'ed away");
-                        return trueEnd.merge().next();
+                        if (GraalOptions.TraceCanonicalizer) {
+                            TTY.println("> Useless if Canon'ed away");
+                        }
+                        return next;
                     }
                 }
             }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java	Fri Aug 05 17:40:35 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.*;
@@ -85,7 +86,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerAdd.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerDiv.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerMul.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerRem.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java	Fri Aug 05 17:40:35 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.*;
@@ -120,7 +121,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java	Fri Aug 05 17:40:35 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.*;
@@ -140,7 +141,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LeftShift.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java	Fri Aug 05 17:40:35 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.*;
@@ -127,7 +128,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MaterializeNode.java	Fri Aug 05 17:40:35 2011 +0200
@@ -22,48 +22,17 @@
  */
 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 {
 
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_VALUE = 0;
+public final class MaterializeNode extends Conditional {
 
+    private static final int INPUT_COUNT = 0;
     private static final int SUCCESSOR_COUNT = 0;
 
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
-    }
-
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    /**
-     * The instruction which produces the input value to this instruction.
-     */
-     public BooleanNode value() {
-        return (BooleanNode) inputs().get(super.inputCount() + INPUT_VALUE);
-    }
-
-    public void setValue(BooleanNode n) {
-        inputs().set(super.inputCount() + INPUT_VALUE, n);
-    }
 
     public MaterializeNode(BooleanNode value, Graph graph) {
-        super(CiKind.Int, INPUT_COUNT, SUCCESSOR_COUNT, graph);
-        setValue(value);
-    }
-
-    @Override
-    public void accept(ValueVisitor v) {
+        super(value, Constant.forInt(1, graph), Constant.forInt(0, graph), graph);
     }
 
     @Override
@@ -71,35 +40,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Negate.java	Fri Aug 05 17:40:35 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.*;
@@ -116,7 +117,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NegateBooleanNode.java	Fri Aug 05 17:40:35 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.*;
 
@@ -89,17 +90,13 @@
 
     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) {
                 return ((NegateBooleanNode) value).value();
             } else if (value instanceof Constant) {
                 return Constant.forBoolean(!value.asConstant().asBoolean(), node.graph());
-            } else if (value instanceof Compare) {
-                Compare compare = (Compare) value;
-                compare.condition = compare.condition.negate();
-                return compare;
             }
             return negateNode;
         }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NormalizeCompare.java	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NormalizeCompare.java	Fri Aug 05 17:40:35 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.*;
@@ -48,7 +50,7 @@
 
     @Override
     public void accept(ValueVisitor v) {
-        v.visitMaterialize(this);
+        v.visitNormalizeCompare(this);
     }
 
     @Override
@@ -65,6 +67,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Or.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java	Fri Aug 05 17:40:35 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.*;
 
@@ -188,12 +190,15 @@
     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) {
                 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);
             if (end0.predecessors().size() != 1 || end1.predecessors().size() != 1) {
@@ -211,11 +216,25 @@
             boolean inverted = ifNode.trueSuccessor() == end1;
             Value trueValue = phiNode.valueAt(inverted ? 1 : 0);
             Value falseValue = phiNode.valueAt(inverted ? 0 : 1);
-            if (trueValue.kind != CiKind.Int || falseValue.kind != CiKind.Int) {
+            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;
             }
-            TTY.println("> Phi canon'ed to Conditional");
-            return new Conditional(ifNode.compare(), trueValue, falseValue, node.graph());
+            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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java	Fri Aug 05 17:40:35 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.*;
@@ -83,7 +84,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RightShift.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/UnsignedRightShift.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java	Fri Aug 05 17:40:35 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);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Xor.java	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Xor.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRAssembler.java	Fri Aug 05 17:40:35 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/LIRList.java	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRList.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROp2.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIROpcode.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java	Fri Aug 05 17:40:35 2011 +0200
@@ -40,25 +40,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 17:40:35 2011 +0200
@@ -0,0 +1,134 @@
+/*
+ * 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.singlePredecessor();
+                    Anchor anchor = new Anchor(graph);
+                    pred.successors().replace(end, anchor);
+                    anchor.setNext(end);
+                    prev = anchor;
+                } else if (firstNode instanceof StartNode) {
+                    StartNode start = (StartNode) firstNode;
+                    Anchor anchor = new Anchor(graph);
+                    anchor.setNext((FixedNode) start.next());
+                    start.setNext(anchor);
+                    prev = anchor;
+                } else if (firstNode instanceof If) {
+                    Node pred = firstNode.singlePredecessor();
+                    Anchor anchor = new Anchor(graph);
+                    pred.successors().replace(firstNode, anchor);
+                    anchor.setNext((If) firstNode);
+                    prev = anchor;
+                } else {
+                    prev = (FixedNodeWithNext) firstNode;
+                }
+                merge.setNext(prev.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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Fri Aug 05 17:40:35 2011 +0200
@@ -759,7 +759,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	Mon Aug 01 18:30:25 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,285 +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.*;
-
-
-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/IdentifyBlocksPhase.java	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java	Fri Aug 05 17:40:35 2011 +0200
@@ -311,7 +311,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java	Fri Aug 05 17:40:35 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) {
@@ -774,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 {
@@ -788,30 +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
-            TTY.println("> emitting cmov");
-            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));
-                }
+            //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()) {
@@ -824,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";
@@ -1273,8 +1293,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);
@@ -1304,10 +1324,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 {
@@ -2238,6 +2269,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Fri Aug 05 17:40:35 2011 +0200
@@ -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/GraphUtil.java	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/GraphUtil.java	Fri Aug 05 17:40:35 2011 +0200
@@ -86,15 +86,12 @@
     }
 
     private static <T> Collection<Merge> colorCFGDownToMerge(Node from, T color, NodeMap<T> colors) {
-        //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;
@@ -123,7 +120,6 @@
                 }
             }
         }
-        //System.out.println("return " + merges);
         return merges;
     }
 
@@ -149,7 +145,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();
@@ -163,7 +158,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);
                                     }
                                 }
@@ -175,7 +169,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) {
@@ -183,7 +176,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) {
@@ -196,7 +188,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;
@@ -207,7 +198,6 @@
                             }
                         }
                         if (delay) {
-                            //System.out.println("Split : delay");
                             work.addAgain(node);
                             continue;
                         }
@@ -215,7 +205,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);
@@ -288,7 +277,6 @@
                     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);
                             }
@@ -309,7 +297,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);
                         }
                     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java	Fri Aug 05 17:40:35 2011 +0200
@@ -276,32 +276,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();
@@ -355,7 +336,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());
                 }
             }
         }
@@ -484,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
@@ -548,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;
@@ -570,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().size() > 0 && !afterColoringFramestate(n)); //TODO (gd) hum
+                return exitFrameStates.isNotNewMarked(n) || (inOrBefore.isNotNewNotMarked(n) && n.inputs().size() > 0 && !afterColoringFramestate(n)); //TODO (gd) hum
             }
             public boolean afterColoringFramestate(Node n) {
                 if (!(n instanceof FrameState)) {
@@ -611,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)) {
@@ -660,22 +622,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);
         }
@@ -728,20 +680,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);
@@ -809,7 +749,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java	Fri Aug 05 17:40:35 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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java	Fri Aug 05 17:40:35 2011 +0200
@@ -478,7 +478,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	Mon Aug 01 18:30:25 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FPConversionNode.java	Fri Aug 05 17:40:35 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.*;
 
@@ -40,9 +42,6 @@
         return super.inputCount() + INPUT_COUNT;
     }
 
-    /**
-     * The instruction that produces the object tested against null.
-     */
      public Value value() {
         return (Value) inputs().get(super.inputCount() + INPUT_OBJECT);
     }
@@ -60,17 +59,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);
     }
@@ -89,4 +82,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);
+        }
+    };
 }