changeset 3522:65c865bba4c2

Merge
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Tue, 09 Aug 2011 18:59:29 +0200
parents 82266dbf5a5a 3e21ab23406b
children 40121bcd2efc
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/BasicInductionVariable.java
diffstat 36 files changed, 887 insertions(+), 1380 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/And.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/And.java	Tue Aug 09 18:59:29 2011 +0200
@@ -22,74 +22,54 @@
  */
 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.*;
 import com.sun.cri.ci.*;
 
 @NodeInfo(shortName = "&")
-public final class And extends Logic {
-    private static final AndCanonicalizerOp CANONICALIZER = new AndCanonicalizerOp();
+public final class And extends Logic implements Canonicalizable {
 
     public And(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.IAND : Bytecodes.LAND, x, y, graph);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (x() == y()) {
+            return x();
         }
-        return super.lookup(clazz);
-    }
-
-    private static class AndCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            assert node instanceof And;
-            And and = (And) node;
-            CiKind kind = and.kind;
-            Graph graph = and.graph();
-            Value x = and.x();
-            Value y = and.y();
-            if (x == y) {
-                return x;
+        if (x().isConstant() && !y().isConstant()) {
+            swapOperands();
+        }
+        if (x().isConstant()) {
+            if (kind == CiKind.Int) {
+                return Constant.forInt(x().asConstant().asInt() & y().asConstant().asInt(), graph());
+            } else {
+                assert kind == CiKind.Long;
+                return Constant.forLong(x().asConstant().asLong() & y().asConstant().asLong(), graph());
             }
-            if (x.isConstant() && !y.isConstant()) {
-                and.swapOperands();
-                Value t = y;
-                y = x;
-                x = t;
-            }
-            if (x.isConstant()) {
-                if (kind == CiKind.Int) {
-                    return Constant.forInt(x.asConstant().asInt() & y.asConstant().asInt(), graph);
-                } else {
-                    assert kind == CiKind.Long;
-                    return Constant.forLong(x.asConstant().asLong() & y.asConstant().asLong(), graph);
+        } else if (y().isConstant()) {
+            if (kind == CiKind.Int) {
+                int c = y().asConstant().asInt();
+                if (c == -1) {
+                    return x();
                 }
-            } else if (y.isConstant()) {
-                if (kind == CiKind.Int) {
-                    int c = y.asConstant().asInt();
-                    if (c == -1) {
-                        return x;
-                    }
-                    if (c == 0) {
-                        return Constant.forInt(0, graph);
-                    }
-                } else {
-                    assert kind == CiKind.Long;
-                    long c = y.asConstant().asLong();
-                    if (c == -1) {
-                        return x;
-                    }
-                    if (c == 0) {
-                        return Constant.forLong(0, graph);
-                    }
+                if (c == 0) {
+                    return Constant.forInt(0, graph());
+                }
+            } else {
+                assert kind == CiKind.Long;
+                long c = y().asConstant().asLong();
+                if (c == -1) {
+                    return x();
+                }
+                if (c == 0) {
+                    return Constant.forLong(0, graph());
                 }
             }
-            return and;
         }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ArrayLength.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ArrayLength.java	Tue Aug 09 18:59:29 2011 +0200
@@ -33,8 +33,7 @@
 /**
  * The {@code ArrayLength} instruction gets the length of an array.
  */
-public final class ArrayLength extends FloatingNode {
-    private static final ArrayLengthCanonicalizerOp CANONICALIZER = new ArrayLengthCanonicalizerOp();
+public final class ArrayLength extends FloatingNode implements Canonicalizable {
 
     @Input private Value array;
 
@@ -49,6 +48,7 @@
 
     /**
      * Constructs a new ArrayLength instruction.
+     *
      * @param array the instruction producing the array
      * @param newFrameState the state after executing this instruction
      */
@@ -67,40 +67,23 @@
         out.print(array()).print(".length");
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (array() instanceof NewArray) {
+            Value length = ((NewArray) array()).dimension(0);
+            assert length != null;
+            return length;
         }
-        return super.lookup(clazz);
-    }
-
-    private static class ArrayLengthCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            ArrayLength arrayLength = (ArrayLength) node;
-            Value array = arrayLength.array();
-            if (array instanceof NewArray) {
-                Value length = ((NewArray) array).length();
-                if (array instanceof NewMultiArray) {
-                    length = ((NewMultiArray) array).dimension(0);
-                }
-                assert length != null;
-                return length;
-            }
-            CiConstant constantValue = null;
-            if (array.isConstant()) {
-                constantValue = array.asConstant();
-            }
+        CiConstant constantValue = null;
+        if (array().isConstant()) {
+            constantValue = array().asConstant();
             if (constantValue != null && constantValue.isNonNull()) {
-                Graph graph = node.graph();
-                if (graph instanceof CompilerGraph) {
-                    RiRuntime runtime = ((CompilerGraph) graph).runtime();
-                    return Constant.forInt(runtime.getArrayLength(constantValue), graph);
+                if (graph() instanceof CompilerGraph) {
+                    RiRuntime runtime = ((CompilerGraph) graph()).runtime();
+                    return Constant.forInt(runtime.getArrayLength(constantValue), graph());
                 }
             }
-            return arrayLength;
         }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/BasicInductionVariable.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/BasicInductionVariable.java	Tue Aug 09 18:59:29 2011 +0200
@@ -23,6 +23,7 @@
 package com.oracle.max.graal.compiler.ir;
 
 import com.oracle.max.graal.compiler.ir.Phi.PhiType;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.compiler.phases.LoweringPhase.*;
 import com.oracle.max.graal.graph.*;
@@ -33,7 +34,7 @@
  * LinearInductionVariable that is computed in the loops thanks to Phi(init, this + stride).
  * This will keep at least one register busy in the whole loop body
  */
-public class BasicInductionVariable extends LinearInductionVariable {
+public class BasicInductionVariable extends LinearInductionVariable implements Canonicalizable{
     public static final BIVLoweringOp LOWERING = new BIVLoweringOp();
     @Input private LoopCounter loopCounter;
 
@@ -87,15 +88,21 @@
         return newDIV;
     }
 
+    @Override
+    public Node canonical(NotifyReProcess reProcess) {
+        if (this.init().isConstant() && this.init().asConstant().asLong() == 0
+                        && this.stride().isConstant() && this.stride().asConstant().asLong() == 1) {
+            return this.loopCounter();
+        }
+        return this;
+    }
+
     @SuppressWarnings("unchecked")
     @Override
     public <T extends Op> T lookup(Class<T> clazz) {
         if (clazz == LoweringOp.class) {
             return (T) LOWERING;
         }
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANON;
-        }
         return super.lookup(clazz);
     }
 
@@ -115,16 +122,4 @@
             return phi;
         }
     }
-
-    private static CanonicalizerOp CANON = new CanonicalizerOp() {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            BasicInductionVariable biv = (BasicInductionVariable) node;
-            if (biv.init().isConstant() && biv.init().asConstant().asLong() == 0
-                            && biv.stride().isConstant() && biv.stride().asConstant().asLong() == 1) {
-                return biv.loopCounter();
-            }
-            return biv;
-        }
-    };
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java	Tue Aug 09 18:59:29 2011 +0200
@@ -23,7 +23,7 @@
 package com.oracle.max.graal.compiler.ir;
 
 import com.oracle.max.graal.compiler.debug.*;
-import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.Canonicalizable;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
@@ -33,10 +33,11 @@
 /**
  * The {@code CheckCast} instruction represents a {@link Bytecodes#CHECKCAST}.
  */
-public final class CheckCast extends TypeCheck {
+public final class CheckCast extends TypeCheck implements Canonicalizable {
 
     /**
      * Creates a new CheckCast instruction.
+     *
      * @param targetClass the class being cast to
      * @param object the instruction producing the object
      * @param graph
@@ -47,6 +48,7 @@
 
     /**
      * Gets the declared type of the result of this instruction.
+     *
      * @return the declared type of the result
      */
     @Override
@@ -56,6 +58,7 @@
 
     /**
      * Gets the exact type of the result of this instruction.
+     *
      * @return the exact type of the result
      */
     @Override
@@ -70,34 +73,24 @@
 
     @Override
     public void print(LogStream out) {
-        out.print("checkcast(").
-        print(object()).
-        print(",").
-        print(targetClassInstruction()).
-        print(") ").
-        print(CiUtil.toJavaName(targetClass()));
+        out.print("checkcast(").print(object()).print(",").print(targetClassInstruction()).print(") ").print(CiUtil.toJavaName(targetClass()));
     }
 
-    private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            CheckCast checkCast = (CheckCast) node;
-            Value object = checkCast.object();
-            RiType exactType = object.exactType();
-            if (exactType != null) {
-                return Constant.forBoolean(exactType.isSubtypeOf(checkCast.targetClass()), node.graph());
+    @Override
+    public Node canonical(NotifyReProcess reProcess) {
+        if (object().exactType() != null) {
+            return object();
+        }
+        CiConstant constant = object().asConstant();
+        if (constant != null) {
+            assert constant.kind == CiKind.Object;
+            if (constant.isNull()) {
+                return object();
+            } else {
+                // this should never happen - non-null constants are always expected to provide an exactType
+                assert false;
             }
-            CiConstant constant = object.asConstant();
-            if (constant != null) {
-                assert constant.kind == CiKind.Object;
-                if (constant.isNull()) {
-                    return Constant.forBoolean(true, node.graph());
-                } else {
-                    // this should never happen - non-null constants are always expected to provide an exactType
-                    assert false;
-                }
-            }
-            return checkCast;
         }
-    };
+        return this;
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java	Tue Aug 09 18:59:29 2011 +0200
@@ -27,6 +27,7 @@
 import com.oracle.max.graal.compiler.*;
 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.*;
@@ -39,7 +40,8 @@
  * into variants that do not materialize the value (CompareIf, CompareGuard...)
  *
  */
-public final class Compare extends BooleanNode {
+public final class Compare extends BooleanNode implements Canonicalizable {
+
     @Input private Value x;
     @Input private Value y;
 
@@ -66,6 +68,7 @@
 
     /**
      * Constructs a new Compare instruction.
+     *
      * @param x the instruction producing the first input to the instruction
      * @param condition the condition (comparison operation)
      * @param y the instruction that produces the second input to this instruction
@@ -81,6 +84,7 @@
 
     /**
      * Gets the condition (comparison operation) for this instruction.
+     *
      * @return the condition
      */
     public Condition condition() {
@@ -89,19 +93,20 @@
 
     /**
      * Checks whether unordered inputs mean true or false.
+     *
      * @return {@code true} if unordered inputs produce true
      */
     public boolean unorderedIsTrue() {
         return unorderedIsTrue;
     }
 
-
     public void setUnorderedIsTrue(boolean unorderedIsTrue) {
         this.unorderedIsTrue = unorderedIsTrue;
     }
 
     /**
      * Swaps the operands to this if and mirrors the condition (e.g. > becomes <).
+     *
      * @see Condition#mirror()
      */
     public void swapOperands() {
@@ -122,12 +127,7 @@
 
     @Override
     public void print(LogStream out) {
-        out.print("comp ").
-        print(x()).
-        print(' ').
-        print(condition().operator).
-        print(' ').
-        print(y());
+        out.print("comp ").print(x()).print(' ').print(condition().operator).print(' ').print(y());
     }
 
     @Override
@@ -135,15 +135,6 @@
         return "Comp " + condition.operator;
     }
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
-        }
-        return super.lookup(clazz);
-    }
-
     @Override
     public Map<Object, Object> getDebugProperties() {
         Map<Object, Object> properties = super.getDebugProperties();
@@ -151,107 +142,104 @@
         return properties;
     }
 
-    private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            Compare compare = (Compare) node;
-            if (compare.x().isConstant() && !compare.y().isConstant()) { // move constants to the left (y)
-                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(), compare.unorderedIsTrue());
-                if (result != null) {
-                    if (GraalOptions.TraceCanonicalizer) {
-                        TTY.println("folded condition " + constX + " " + compare.condition() + " " + constY);
-                    }
-                    return Constant.forBoolean(result, compare.graph());
-                } else {
-                    if (GraalOptions.TraceCanonicalizer) {
-                        TTY.println("if not removed %s %s %s (%s %s)", constX, compare.condition(), constY, constX.kind, constY.kind);
-                    }
+    private Node optimizeMaterialize(CiConstant constant, MaterializeNode materializeNode) {
+        if (constant.kind == CiKind.Int) {
+            boolean isFalseCheck = (constant.asInt() == 0);
+            if (condition == Condition.EQ || condition == Condition.NE) {
+                if (condition == Condition.NE) {
+                    isFalseCheck = !isFalseCheck;
                 }
-            }
-
-            if (compare.y().isConstant()) {
-                if (compare.x() instanceof MaterializeNode) {
-                    return optimizeMaterialize(compare, compare.y().asConstant(), (MaterializeNode) compare.x());
-                } else if (compare.x() instanceof NormalizeCompare) {
-                    return optimizeNormalizeCmp(compare, compare.y().asConstant(), (NormalizeCompare) compare.x());
+                BooleanNode result = materializeNode.condition();
+                if (isFalseCheck) {
+                    result = new NegateBooleanNode(result, graph());
                 }
-            }
-
-            if (compare.x() == compare.y() && compare.x().kind != CiKind.Float && compare.x().kind != CiKind.Double) {
-                return Constant.forBoolean(compare.condition().check(1, 1), compare.graph());
-            }
-            if ((compare.condition == Condition.NE || compare.condition == Condition.EQ) && compare.x().kind == CiKind.Object) {
-                Value object = null;
-                if (compare.x().isNullConstant()) {
-                    object = compare.y();
-                } else if (compare.y().isNullConstant()) {
-                    object = compare.x();
-                }
-                if (object != null) {
-                    IsNonNull nonNull =  new IsNonNull(object, compare.graph());
-                    if (compare.condition == Condition.NE) {
-                        return nonNull;
-                    } else {
-                        assert compare.condition == Condition.EQ;
-                        return new NegateBooleanNode(nonNull, compare.graph());
-                    }
-                }
-            }
-            boolean allUsagesNegate = true;
-            for (Node usage : compare.usages()) {
-                if (!(usage instanceof NegateBooleanNode)) {
-                    allUsagesNegate = false;
-                    break;
-                }
-            }
-            if (allUsagesNegate) {
-                compare.negate();
-                for (Node usage : compare.usages().snapshot()) {
-                    usage.replaceAtUsages(compare);
-                }
-            }
-            return compare;
-        }
-
-        private Node optimizeMaterialize(Compare compare, CiConstant constant, MaterializeNode materializeNode) {
-            if (constant.kind == CiKind.Int) {
-                boolean isFalseCheck = (constant.asInt() == 0);
-                if (compare.condition == Condition.EQ || compare.condition == Condition.NE) {
-                    if (compare.condition == Condition.NE) {
-                        isFalseCheck = !isFalseCheck;
-                    }
-                    BooleanNode result = materializeNode.condition();
-                    if (isFalseCheck) {
-                        result = new NegateBooleanNode(result, compare.graph());
-                    }
-                    if (GraalOptions.TraceCanonicalizer) {
-                        TTY.println("Removed materialize replacing with " + result);
-                    }
-                    return result;
-                }
-            }
-            return compare;
-        }
-
-        private Node optimizeNormalizeCmp(Compare compare, CiConstant constant, NormalizeCompare normalizeNode) {
-            if (constant.kind == CiKind.Int && constant.asInt() == 0) {
-                Condition condition = compare.condition();
-                if (normalizeNode == compare.y()) {
-                    condition = condition.mirror();
-                }
-                Compare result = new Compare(normalizeNode.x(), condition, normalizeNode.y(), compare.graph());
-                boolean isLess = condition == Condition.LE || condition == Condition.LT || condition == Condition.BE || condition == Condition.BT;
-                result.unorderedIsTrue = condition != Condition.EQ && (condition == Condition.NE || !(isLess ^ normalizeNode.isUnorderedLess()));
                 if (GraalOptions.TraceCanonicalizer) {
-                    TTY.println("Replaced Compare+NormalizeCompare with " + result);
+                    TTY.println("Removed materialize replacing with " + result);
                 }
                 return result;
             }
-            return compare;
         }
-    };
+        return this;
+    }
+
+    private Node optimizeNormalizeCmp(CiConstant constant, NormalizeCompare normalizeNode) {
+        if (constant.kind == CiKind.Int && constant.asInt() == 0) {
+            Condition condition = condition();
+            if (normalizeNode == y()) {
+                condition = condition.mirror();
+            }
+            Compare result = new Compare(normalizeNode.x(), condition, normalizeNode.y(), graph());
+            boolean isLess = condition == Condition.LE || condition == Condition.LT || condition == Condition.BE || condition == Condition.BT;
+            result.unorderedIsTrue = condition != Condition.EQ && (condition == Condition.NE || !(isLess ^ normalizeNode.isUnorderedLess()));
+            if (GraalOptions.TraceCanonicalizer) {
+                TTY.println("Replaced Compare+NormalizeCompare with " + result);
+            }
+            return result;
+        }
+        return this;
+    }
+
+    @Override
+    public Node canonical(NotifyReProcess reProcess) {
+        if (x().isConstant() && !y().isConstant()) { // move constants to the left (y)
+            swapOperands();
+        } else if (x().isConstant() && y().isConstant()) {
+            CiConstant constX = x().asConstant();
+            CiConstant constY = y().asConstant();
+            Boolean result = condition().foldCondition(constX, constY, ((CompilerGraph) graph()).runtime(), unorderedIsTrue());
+            if (result != null) {
+                if (GraalOptions.TraceCanonicalizer) {
+                    TTY.println("folded condition " + constX + " " + condition() + " " + constY);
+                }
+                return Constant.forBoolean(result, graph());
+            } else {
+                if (GraalOptions.TraceCanonicalizer) {
+                    TTY.println("if not removed %s %s %s (%s %s)", constX, condition(), constY, constX.kind, constY.kind);
+                }
+            }
+        }
+
+        if (y().isConstant()) {
+            if (x() instanceof MaterializeNode) {
+                return optimizeMaterialize(y().asConstant(), (MaterializeNode) x());
+            } else if (x() instanceof NormalizeCompare) {
+                return optimizeNormalizeCmp(y().asConstant(), (NormalizeCompare) x());
+            }
+        }
+
+        if (x() == y() && x().kind != CiKind.Float && x().kind != CiKind.Double) {
+            return Constant.forBoolean(condition().check(1, 1), graph());
+        }
+        if ((condition == Condition.NE || condition == Condition.EQ) && x().kind == CiKind.Object) {
+            Value object = null;
+            if (x().isNullConstant()) {
+                object = y();
+            } else if (y().isNullConstant()) {
+                object = x();
+            }
+            if (object != null) {
+                IsNonNull nonNull = new IsNonNull(object, graph());
+                if (condition == Condition.NE) {
+                    return nonNull;
+                } else {
+                    assert condition == Condition.EQ;
+                    return new NegateBooleanNode(nonNull, graph());
+                }
+            }
+        }
+        boolean allUsagesNegate = true;
+        for (Node usage : usages()) {
+            if (!(usage instanceof NegateBooleanNode)) {
+                allUsagesNegate = false;
+                break;
+            }
+        }
+        if (allUsagesNegate) {
+            negate();
+            for (Node usage : usages().snapshot()) {
+                usage.replaceAtUsages(this);
+            }
+        }
+        return this;
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Conditional.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Conditional.java	Tue Aug 09 18:59:29 2011 +0200
@@ -26,8 +26,8 @@
 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.Phi.*;
-import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.ir.Phi.PhiType;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.Canonicalizable;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.graph.*;
@@ -35,11 +35,11 @@
 import com.sun.cri.ci.*;
 
 /**
- * The {@code Conditional} class represents a comparison that yields one of two values.
- * Note that these nodes are not built directly from the bytecode but are introduced
- * by conditional expression elimination.
+ * The {@code Conditional} class represents a comparison that yields one of two values. Note that these nodes are not
+ * built directly from the bytecode but are introduced by conditional expression elimination.
  */
-public class Conditional extends Binary {
+public class Conditional extends Binary implements Canonicalizable {
+
     @Input private BooleanNode condition;
 
     public BooleanNode condition() {
@@ -53,6 +53,7 @@
 
     /**
      * Constructs a new IfOp.
+     *
      * @param x the instruction producing the first value to be compared
      * @param condition the condition of the comparison
      * @param y the instruction producing the second value to be compared
@@ -88,23 +89,12 @@
 
     @Override
     public void print(LogStream out) {
-        out.print(x()).
-        print(' ').
-        print(condition()).
-        print(' ').
-        print(y()).
-        print(" ? ").
-        print(trueValue()).
-        print(" : ").
-        print(falseValue());
+        out.print(x()).print(' ').print(condition()).print(' ').print(y()).print(" ? ").print(trueValue()).print(" : ").print(falseValue());
     }
 
     @SuppressWarnings("unchecked")
     @Override
     public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
-        }
         if (clazz == LIRGeneratorOp.class) {
             return (T) LIRGEN;
         }
@@ -112,9 +102,11 @@
     }
 
     public static class ConditionalStructure {
+
         public final If ifNode;
         public final Phi phi;
         public final Merge merge;
+
         public ConditionalStructure(If ifNode, Phi phi, Merge merge) {
             this.ifNode = ifNode;
             this.phi = phi;
@@ -143,50 +135,6 @@
         return new ConditionalStructure(ifNode, phi, merge);
     }
 
-    private static final CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            Conditional conditional = (Conditional) node;
-            BooleanNode condition = conditional.condition();
-            Value trueValue = conditional.trueValue();
-            Value falseValue = conditional.falseValue();
-            if (condition instanceof Constant) {
-                Constant c = (Constant) condition;
-                if (c.asConstant().asBoolean()) {
-                    return trueValue;
-                } else {
-                    return falseValue;
-                }
-            }
-            if (trueValue == falseValue) {
-                return trueValue;
-            }
-            if (!(conditional instanceof MaterializeNode) && trueValue instanceof Constant && falseValue instanceof Constant
-                            && trueValue.kind == CiKind.Int && falseValue.kind == CiKind.Int) {
-                int trueInt = trueValue.asConstant().asInt();
-                int falseInt = falseValue.asConstant().asInt();
-                if (trueInt == 0 && falseInt == 1) {
-                    if (GraalOptions.TraceCanonicalizer) {
-                        TTY.println("> Conditional canon'ed to ~Materialize");
-                    }
-                    reProcess.reProccess(condition); // because we negate it
-                    return new MaterializeNode(new NegateBooleanNode(condition, node.graph()), node.graph());
-                } else if (trueInt == 1 && falseInt == 0) {
-                    if (GraalOptions.TraceCanonicalizer) {
-                        TTY.println("> Conditional canon'ed to Materialize");
-                    }
-                    return new MaterializeNode(condition, node.graph());
-                }
-            } else if (falseValue instanceof Constant && !(trueValue instanceof Constant)) {
-                conditional.setTrueValue(falseValue);
-                conditional.setFalseValue(trueValue);
-                condition = new NegateBooleanNode(condition, node.graph());
-                conditional.setCondition(condition);
-            }
-            return conditional;
-        }
-    };
-
     private static final LIRGeneratorOp LIRGEN = new LIRGeneratorOp() {
 
         @Override
@@ -258,4 +206,42 @@
             }
         }
     };
+
+    @Override
+    public Node canonical(NotifyReProcess reProcess) {
+        if (condition instanceof Constant) {
+            Constant c = (Constant) condition;
+            if (c.asConstant().asBoolean()) {
+                return trueValue();
+            } else {
+                return falseValue();
+            }
+        }
+        if (trueValue() == falseValue()) {
+            return trueValue();
+        }
+        if (!(this instanceof MaterializeNode) && trueValue() instanceof Constant && falseValue() instanceof Constant && trueValue().kind == CiKind.Int && falseValue().kind == CiKind.Int) {
+            int trueInt = trueValue().asConstant().asInt();
+            int falseInt = falseValue().asConstant().asInt();
+            if (trueInt == 0 && falseInt == 1) {
+                if (GraalOptions.TraceCanonicalizer) {
+                    TTY.println("> Conditional canon'ed to ~Materialize");
+                }
+                reProcess.reProccess(condition); // because we negate it
+                return new MaterializeNode(new NegateBooleanNode(condition, graph()), graph());
+            } else if (trueInt == 1 && falseInt == 0) {
+                if (GraalOptions.TraceCanonicalizer) {
+                    TTY.println("> Conditional canon'ed to Materialize");
+                }
+                return new MaterializeNode(condition, graph());
+            }
+        } else if (falseValue() instanceof Constant && !(trueValue() instanceof Constant)) {
+            Value temp = trueValue();
+            setTrueValue(falseValue());
+            setFalseValue(temp);
+            condition = new NegateBooleanNode(condition, graph());
+            setCondition(condition);
+        }
+        return this;
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java	Tue Aug 09 18:59:29 2011 +0200
@@ -25,13 +25,13 @@
 import com.oracle.max.graal.compiler.*;
 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.Canonicalizable;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 
+public final class FixedGuard extends FixedNodeWithNext implements Canonicalizable {
 
-public final class FixedGuard extends FixedNodeWithNext {
     @Input private final NodeInputList<BooleanNode> conditions = new NodeInputList<BooleanNode>(this);
 
     public FixedGuard(BooleanNode node, Graph graph) {
@@ -57,40 +57,28 @@
         conditions.add(x);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
-        }
-        return super.lookup(clazz);
-    }
-
-    private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            FixedGuard fixedGuard = (FixedGuard) node;
-            for (BooleanNode n : fixedGuard.conditions.snapshot()) {
-                if (n instanceof Constant) {
-                    Constant c = (Constant) n;
-                    if (c.asConstant().asBoolean()) {
-                        if (GraalOptions.TraceCanonicalizer) {
-                            TTY.println("Removing redundant fixed guard " + fixedGuard);
-                        }
-                        fixedGuard.conditions.remove(n);
-                    } else {
-                        if (GraalOptions.TraceCanonicalizer) {
-                            TTY.println("Replacing fixed guard " + fixedGuard + " with deoptimization node");
-                        }
-                        return new Deoptimize(DeoptAction.InvalidateRecompile, fixedGuard.graph());
+    public Node canonical(NotifyReProcess reProcess) {
+        for (BooleanNode n : conditions.snapshot()) {
+            if (n instanceof Constant) {
+                Constant c = (Constant) n;
+                if (c.asConstant().asBoolean()) {
+                    if (GraalOptions.TraceCanonicalizer) {
+                        TTY.println("Removing redundant fixed guard " + this);
                     }
+                    conditions.remove(n);
+                } else {
+                    if (GraalOptions.TraceCanonicalizer) {
+                        TTY.println("Replacing fixed guard " + this + " with deoptimization node");
+                    }
+                    return new Deoptimize(DeoptAction.InvalidateRecompile, graph());
                 }
             }
+        }
 
-            if (fixedGuard.conditions.isEmpty()) {
-                return fixedGuard.next();
-            }
-            return fixedGuard;
+        if (conditions.isEmpty()) {
+            return next();
         }
-    };
+        return this;
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatAdd.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatAdd.java	Tue Aug 09 18:59:29 2011 +0200
@@ -29,58 +29,38 @@
 import com.sun.cri.ci.*;
 
 @NodeInfo(shortName = "+")
-public final class FloatAdd extends FloatArithmetic {
-    private static final FloatAddCanonicalizerOp CANONICALIZER = new FloatAddCanonicalizerOp();
+public final class FloatAdd extends FloatArithmetic implements Canonicalizable {
 
     public FloatAdd(CiKind kind, Value x, Value y, boolean isStrictFP, Graph graph) {
         super(kind, kind == CiKind.Double ? Bytecodes.DADD : Bytecodes.FADD, x, y, isStrictFP, graph);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (x().isConstant() && !y().isConstant()) {
+            swapOperands();
         }
-        return super.lookup(clazz);
-    }
-
-    private static class FloatAddCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            FloatAdd add = (FloatAdd) node;
-            Value x = add.x();
-            Value y = add.y();
-            CiKind kind = add.kind;
-            Graph graph = add.graph();
-            if (x.isConstant() && !y.isConstant()) {
-                add.swapOperands();
-                Value t = y;
-                y = x;
-                x = t;
+        if (x().isConstant()) {
+            if (kind == CiKind.Float) {
+                return Constant.forFloat(x().asConstant().asFloat() + y().asConstant().asFloat(), graph());
+            } else {
+                assert kind == CiKind.Double;
+                return Constant.forDouble(x().asConstant().asDouble() + y().asConstant().asDouble(), graph());
             }
-            if (x.isConstant()) {
-                if (kind == CiKind.Float) {
-                    return Constant.forFloat(x.asConstant().asFloat() + y.asConstant().asFloat(), graph);
-                } else {
-                    assert kind == CiKind.Double;
-                    return Constant.forDouble(x.asConstant().asDouble() + y.asConstant().asDouble(), graph);
+        } else if (y().isConstant()) {
+            if (kind == CiKind.Float) {
+                float c = y().asConstant().asFloat();
+                if (c == 0.0f) {
+                    return x();
                 }
-            } else if (y.isConstant()) {
-                if (kind == CiKind.Float) {
-                    float c = y.asConstant().asFloat();
-                    if (c == 0.0f) {
-                        return x;
-                    }
-                } else {
-                    assert kind == CiKind.Double;
-                    double c = y.asConstant().asDouble();
-                    if (c == 0.0) {
-                        return x;
-                    }
+            } else {
+                assert kind == CiKind.Double;
+                double c = y().asConstant().asDouble();
+                if (c == 0.0) {
+                    return x();
                 }
             }
-            return add;
         }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatDiv.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatDiv.java	Tue Aug 09 18:59:29 2011 +0200
@@ -22,46 +22,29 @@
  */
 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.*;
 import com.sun.cri.ci.*;
 
 @NodeInfo(shortName = "/")
-public final class FloatDiv extends FloatArithmetic {
-    private static final FloatDivCanonicalizerOp CANONICALIZER = new FloatDivCanonicalizerOp();
+public final class FloatDiv extends FloatArithmetic implements Canonicalizable {
 
     public FloatDiv(CiKind kind, Value x, Value y, boolean isStrictFP, Graph graph) {
         super(kind, kind == CiKind.Double ? Bytecodes.DDIV : Bytecodes.FDIV, x, y, isStrictFP, graph);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (x().isConstant() && y().isConstant()) {
+            if (kind == CiKind.Float) {
+                return Constant.forFloat(x().asConstant().asFloat() / y().asConstant().asFloat(), graph());
+            } else {
+                assert kind == CiKind.Double;
+                return Constant.forDouble(x().asConstant().asDouble() / y().asConstant().asDouble(), graph());
+            }
         }
-        return super.lookup(clazz);
+        return this;
     }
-
-    private static class FloatDivCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            FloatDiv div = (FloatDiv) node;
-            Value x = div.x();
-            Value y = div.y();
-            if (x.isConstant() && y.isConstant()) {
-                CiKind kind = div.kind;
-                Graph graph = div.graph();
-                if (kind == CiKind.Float) {
-                    return Constant.forFloat(x.asConstant().asFloat() / y.asConstant().asFloat(), graph);
-                } else {
-                    assert kind == CiKind.Double;
-                    return Constant.forDouble(x.asConstant().asDouble() / y.asConstant().asDouble(), graph);
-                }
-            }
-            return div;
-        }
-    }
-
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatMul.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatMul.java	Tue Aug 09 18:59:29 2011 +0200
@@ -22,64 +22,45 @@
  */
 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.*;
 import com.sun.cri.ci.*;
 
 @NodeInfo(shortName = "*")
-public final class FloatMul extends FloatArithmetic {
-    private static final FloatMulCanonicalizerOp CANONICALIZER = new FloatMulCanonicalizerOp();
+public final class FloatMul extends FloatArithmetic implements Canonicalizable {
 
     public FloatMul(CiKind kind, Value x, Value y, boolean isStrictFP, Graph graph) {
         super(kind, kind == CiKind.Double ? Bytecodes.DMUL : Bytecodes.FMUL, x, y, isStrictFP, graph);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (x().isConstant() && !y().isConstant()) {
+            swapOperands();
         }
-        return super.lookup(clazz);
-    }
-
-    private static class FloatMulCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            FloatMul mul = (FloatMul) node;
-            Value x = mul.x();
-            Value y = mul.y();
-            CiKind kind = mul.kind;
-            Graph graph = mul.graph();
-            if (x.isConstant() && !y.isConstant()) {
-                mul.swapOperands();
-                Value t = y;
-                y = x;
-                x = t;
+        if (x().isConstant()) {
+            if (kind == CiKind.Float) {
+                return Constant.forFloat(x().asConstant().asFloat() * y().asConstant().asFloat(), graph());
+            } else {
+                assert kind == CiKind.Double;
+                return Constant.forDouble(x().asConstant().asDouble() * y().asConstant().asDouble(), graph());
             }
-            if (x.isConstant()) {
-                if (kind == CiKind.Float) {
-                    return Constant.forFloat(x.asConstant().asFloat() * y.asConstant().asFloat(), graph);
-                } else {
-                    assert kind == CiKind.Double;
-                    return Constant.forDouble(x.asConstant().asDouble() * y.asConstant().asDouble(), graph);
+        } else if (y().isConstant()) {
+            if (kind == CiKind.Float) {
+                float c = y().asConstant().asFloat();
+                if (c == 0.0f) {
+                    return Constant.forFloat(0.0f, graph());
                 }
-            } else if (y.isConstant()) {
-                if (kind == CiKind.Float) {
-                    float c = y.asConstant().asFloat();
-                    if (c == 0.0f) {
-                        return Constant.forFloat(0.0f, graph);
-                    }
-                } else {
-                    assert kind == CiKind.Double;
-                    double c = y.asConstant().asDouble();
-                    if (c == 0.0) {
-                        return Constant.forDouble(0.0, graph);
-                    }
+            } else {
+                assert kind == CiKind.Double;
+                double c = y().asConstant().asDouble();
+                if (c == 0.0) {
+                    return Constant.forDouble(0.0, graph());
                 }
             }
-            return mul;
         }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatRem.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatRem.java	Tue Aug 09 18:59:29 2011 +0200
@@ -22,45 +22,29 @@
  */
 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.*;
 import com.sun.cri.ci.*;
 
 @NodeInfo(shortName = "%")
-public final class FloatRem extends FloatArithmetic {
-    private static final FloatRemCanonicalizerOp CANONICALIZER = new FloatRemCanonicalizerOp();
+public final class FloatRem extends FloatArithmetic implements Canonicalizable {
 
     public FloatRem(CiKind kind, Value x, Value y, boolean isStrictFP, Graph graph) {
         super(kind, kind == CiKind.Double ? Bytecodes.DREM : Bytecodes.FREM, x, y, isStrictFP, graph);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (x().isConstant() && y().isConstant()) {
+            if (kind == CiKind.Float) {
+                return Constant.forFloat(x().asConstant().asFloat() % y().asConstant().asFloat(), graph());
+            } else {
+                assert kind == CiKind.Double;
+                return Constant.forDouble(x().asConstant().asDouble() % y().asConstant().asDouble(), graph());
+            }
         }
-        return super.lookup(clazz);
-    }
-
-    private static class FloatRemCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            FloatRem rem = (FloatRem) node;
-            Value x = rem.x();
-            Value y = rem.y();
-            if (x.isConstant() && y.isConstant()) {
-                CiKind kind = rem.kind;
-                Graph graph = rem.graph();
-                if (kind == CiKind.Float) {
-                    return Constant.forFloat(x.asConstant().asFloat() % y.asConstant().asFloat(), graph);
-                } else {
-                    assert kind == CiKind.Double;
-                    return Constant.forDouble(x.asConstant().asDouble() % y.asConstant().asDouble(), graph);
-                }
-            }
-            return rem;
-        }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatSub.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatSub.java	Tue Aug 09 18:59:29 2011 +0200
@@ -22,68 +22,52 @@
  */
 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.*;
 import com.sun.cri.ci.*;
 
 @NodeInfo(shortName = "-")
-public final class FloatSub extends FloatArithmetic {
-    private static final FloatSubCanonicalizerOp CANONICALIZER = new FloatSubCanonicalizerOp();
+public final class FloatSub extends FloatArithmetic implements Canonicalizable {
 
     public FloatSub(CiKind kind, Value x, Value y, boolean isStrictFP, Graph graph) {
         super(kind, kind == CiKind.Double ? Bytecodes.DSUB : Bytecodes.FSUB, x, y, isStrictFP, graph);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (x() == y()) {
+            if (kind == CiKind.Float) {
+                return Constant.forFloat(0.0f, graph());
+            } else {
+                assert kind == CiKind.Double;
+                return Constant.forDouble(0.0, graph());
+            }
         }
-        return super.lookup(clazz);
-    }
-
-    private static class FloatSubCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            FloatSub sub = (FloatSub) node;
-            Value x = sub.x();
-            Value y = sub.y();
-            CiKind kind = sub.kind;
-            Graph graph = sub.graph();
-            if (x == y) {
-                if (kind == CiKind.Float) {
-                    return Constant.forFloat(0.0f, graph);
-                } else {
-                    assert kind == CiKind.Double;
-                    return Constant.forDouble(0.0, graph);
+        if (x().isConstant() && y().isConstant()) {
+            if (kind == CiKind.Float) {
+                return Constant.forFloat(x().asConstant().asFloat() - y().asConstant().asFloat(), graph());
+            } else {
+                assert kind == CiKind.Double;
+                return Constant.forDouble(x().asConstant().asDouble() - y().asConstant().asDouble(), graph());
+            }
+        } else if (y().isConstant()) {
+            if (kind == CiKind.Float) {
+                float c = y().asConstant().asFloat();
+                if (c == 0.0f) {
+                    return x();
                 }
+                return new FloatAdd(kind, x(), Constant.forFloat(-c, graph()), isStrictFP(), graph());
+            } else {
+                assert kind == CiKind.Double;
+                double c = y().asConstant().asDouble();
+                if (c == 0.0) {
+                    return x();
+                }
+                return new FloatAdd(kind, x(), Constant.forDouble(-c, graph()), isStrictFP(), graph());
             }
-            if (x.isConstant() && y.isConstant()) {
-                if (kind == CiKind.Float) {
-                    return Constant.forFloat(x.asConstant().asFloat() - y.asConstant().asFloat(), graph);
-                } else {
-                    assert kind == CiKind.Double;
-                    return Constant.forDouble(x.asConstant().asDouble() - y.asConstant().asDouble(), graph);
-                }
-            } else if (y.isConstant()) {
-                if (kind == CiKind.Float) {
-                    float c = y.asConstant().asFloat();
-                    if (c == 0.0f) {
-                        return x;
-                    }
-                    return new FloatAdd(kind, x, Constant.forFloat(-c, graph), sub.isStrictFP(), graph);
-                } else {
-                    assert kind == CiKind.Double;
-                    double c = y.asConstant().asDouble();
-                    if (c == 0.0) {
-                        return x;
-                    }
-                    return new FloatAdd(kind, x, Constant.forDouble(-c, graph), sub.isStrictFP(), graph);
-                }
-            }
-            return sub;
         }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java	Tue Aug 09 18:59:29 2011 +0200
@@ -29,8 +29,8 @@
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 
+public final class GuardNode extends FloatingNode implements Canonicalizable {
 
-public final class GuardNode extends FloatingNode {
     @Input private FixedNode anchor;
     @Input private BooleanNode node;
 
@@ -70,29 +70,17 @@
         out.print("guard node ").print(node());
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (node() instanceof Constant) {
+            Constant c = (Constant) node();
+            if (c.asConstant().asBoolean()) {
+                if (GraalOptions.TraceCanonicalizer) {
+                    TTY.println("Removing redundant floating guard " + this);
+                }
+                return Node.Null;
+            }
         }
-        return super.lookup(clazz);
+        return this;
     }
-
-    private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            GuardNode guard = (GuardNode) node;
-            if (guard.node() instanceof Constant) {
-                Constant c = (Constant) guard.node();
-                if (c.asConstant().asBoolean()) {
-                    if (GraalOptions.TraceCanonicalizer) {
-                        TTY.println("Removing redundant floating guard " + guard);
-                    }
-                    return Node.Null;
-                }
-            }
-            return guard;
-        }
-    };
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java	Tue Aug 09 18:59:29 2011 +0200
@@ -24,18 +24,18 @@
 
 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.Canonicalizable;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 
 /**
- * The {@code If} instruction represents a branch that can go one of two directions
- * depending on the outcome of a comparison.
+ * The {@code If} instruction represents a branch that can go one of two directions depending on the outcome of a
+ * comparison.
  */
-public final class If extends ControlSplit {
+public final class If extends ControlSplit implements Canonicalizable {
 
-    @Input    private BooleanNode compare;
+    @Input private BooleanNode compare;
 
     public BooleanNode compare() {
         return compare;
@@ -53,6 +53,7 @@
 
     /**
      * Gets the block corresponding to the true successor.
+     *
      * @return the true successor
      */
     public FixedNode trueSuccessor() {
@@ -61,24 +62,24 @@
 
     /**
      * Gets the block corresponding to the false successor.
+     *
      * @return the false successor
      */
     public FixedNode falseSuccessor() {
         return blockSuccessor(1);
     }
 
-
     public void setTrueSuccessor(FixedNode node) {
         setBlockSuccessor(0, node);
     }
 
-
     public void setFalseSuccessor(FixedNode node) {
         setBlockSuccessor(1, node);
     }
 
     /**
      * Gets the block corresponding to the specified outcome of the branch.
+     *
      * @param istrue {@code true} if the true successor is requested, {@code false} otherwise
      * @return the corresponding successor
      */
@@ -101,64 +102,47 @@
 
     @Override
     public void print(LogStream out) {
-        out.print("if ").
-        print(compare()).
-        print(" then ").
-        print(trueSuccessor()).
-        print(" else ").
-        print(falseSuccessor());
+        out.print("if ").print(compare()).print(" then ").print(trueSuccessor()).print(" else ").print(falseSuccessor());
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (compare() instanceof Constant) {
+            Constant c = (Constant) compare();
+            if (c.asConstant().asBoolean()) {
+                if (GraalOptions.TraceCanonicalizer) {
+                    TTY.println("Replacing if " + this + " with true branch");
+                }
+                return trueSuccessor();
+            } else {
+                if (GraalOptions.TraceCanonicalizer) {
+                    TTY.println("Replacing if " + this + " with false branch");
+                }
+                return falseSuccessor();
+            }
         }
-        return super.lookup(clazz);
-    }
-
-    private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            If ifNode = (If) node;
-            if (ifNode.compare() instanceof Constant) {
-                Constant c = (Constant) ifNode.compare();
-                if (c.asConstant().asBoolean()) {
+        if (trueSuccessor() instanceof EndNode && falseSuccessor() instanceof EndNode) {
+            EndNode trueEnd = (EndNode) trueSuccessor();
+            EndNode falseEnd = (EndNode) falseSuccessor();
+            Merge merge = trueEnd.merge();
+            if (merge == falseEnd.merge() && merge.phis().size() == 0) {
+                FixedNode next = merge.next();
+                merge.setNext(null); // disconnect to avoid next from having 2 preds
+                if (compare().usages().size() == 1 && /* ifNode.compare().hasSideEffets() */true) { // TODO (gd) ifNode.compare().hasSideEffets() ?
                     if (GraalOptions.TraceCanonicalizer) {
-                        TTY.println("Replacing if " + ifNode + " with true branch");
+                        TTY.println("> Useless if with side effects Canon'ed to guard");
                     }
-                    return ifNode.trueSuccessor();
+                    ValueAnchor anchor = new ValueAnchor(compare(), graph());
+                    anchor.setNext(next);
+                    return anchor;
                 } else {
                     if (GraalOptions.TraceCanonicalizer) {
-                        TTY.println("Replacing if " + ifNode + " with false branch");
+                        TTY.println("> Useless if Canon'ed away");
                     }
-                    return ifNode.falseSuccessor();
+                    return next;
                 }
             }
-            if (ifNode.trueSuccessor() instanceof EndNode && ifNode.falseSuccessor() instanceof EndNode) {
-                EndNode trueEnd = (EndNode) ifNode.trueSuccessor();
-                EndNode falseEnd = (EndNode) ifNode.falseSuccessor();
-                Merge merge = trueEnd.merge();
-                if (merge == falseEnd.merge() && merge.phis().size() == 0) {
-                    FixedNode next = merge.next();
-                    merge.setNext(null); //disconnect to avoid next from having 2 preds
-                    if (ifNode.compare().usages().size() == 1 && /*ifNode.compare().hasSideEffets()*/ true) { // TODO (gd) ifNode.compare().hasSideEffets() ?
-                        if (GraalOptions.TraceCanonicalizer) {
-                            TTY.println("> Useless if with side effects Canon'ed to guard");
-                        }
-                        ValueAnchor anchor = new ValueAnchor(ifNode.compare(), node.graph());
-                        anchor.setNext(next);
-                        return anchor;
-                    } else {
-                        if (GraalOptions.TraceCanonicalizer) {
-                            TTY.println("> Useless if Canon'ed away");
-                        }
-                        return next;
-                    }
-                }
-            }
-            return ifNode;
         }
-    };
+        return this;
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java	Tue Aug 09 18:59:29 2011 +0200
@@ -23,19 +23,19 @@
 package com.oracle.max.graal.compiler.ir;
 
 import com.oracle.max.graal.compiler.debug.*;
-import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.Canonicalizable;
 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.*;
 
 /**
  * The {@code InstanceOf} instruction represents an instanceof test.
  */
-public final class InstanceOf extends TypeCheck {
+public final class InstanceOf extends TypeCheck implements Canonicalizable {
 
     /**
      * Constructs a new InstanceOf instruction.
+     *
      * @param targetClass the target class of the instanceof check
      * @param object the instruction producing the object input to this instruction
      * @param graph
@@ -53,35 +53,21 @@
         out.print("instanceof(").print(object()).print(") ").print(CiUtil.toJavaName(targetClass()));
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (object().exactType() != null) {
+            return Constant.forBoolean(object().exactType().isSubtypeOf(targetClass()), graph());
         }
-        return super.lookup(clazz);
+        CiConstant constant = object().asConstant();
+        if (constant != null) {
+            assert constant.kind == CiKind.Object;
+            if (constant.isNull()) {
+                return Constant.forBoolean(false, graph());
+            } else {
+                // this should never happen - non-null constants are always expected to provide an exactType
+                assert false;
+            }
+        }
+        return this;
     }
-
-    private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            InstanceOf isInstance = (InstanceOf) node;
-            Value object = isInstance.object();
-            RiType exactType = object.exactType();
-            if (exactType != null) {
-                return Constant.forBoolean(exactType.isSubtypeOf(isInstance.targetClass()), node.graph());
-            }
-            CiConstant constant = object.asConstant();
-            if (constant != null) {
-                assert constant.kind == CiKind.Object;
-                if (constant.isNull()) {
-                    return Constant.forBoolean(false, node.graph());
-                } else {
-                    // this should never happen - non-null constants are always expected to provide an exactType
-                    assert false;
-                }
-            }
-            return isInstance;
-        }
-    };
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerAdd.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerAdd.java	Tue Aug 09 18:59:29 2011 +0200
@@ -22,65 +22,45 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.Canonicalizable;
 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.*;
 import com.sun.cri.ci.*;
 
 @NodeInfo(shortName = "+")
-public final class IntegerAdd extends IntegerArithmeticNode {
-    private static final IntegerAddCanonicalizerOp CANONICALIZER = new IntegerAddCanonicalizerOp();
+public final class IntegerAdd extends IntegerArithmeticNode implements Canonicalizable {
 
     public IntegerAdd(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.IADD : Bytecodes.LADD, x, y, graph);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (x().isConstant() && !y().isConstant()) {
+            swapOperands();
         }
-        return super.lookup(clazz);
-    }
-
-    private static class IntegerAddCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            IntegerAdd add = (IntegerAdd) node;
-            Value x = add.x();
-            Value y = add.y();
-            CiKind kind = add.kind;
-            Graph graph = add.graph();
-            if (x.isConstant() && !y.isConstant()) {
-                add.swapOperands();
-                Value t = y;
-                y = x;
-                x = t;
+        if (x().isConstant()) {
+            if (kind == CiKind.Int) {
+                return Constant.forInt(x().asConstant().asInt() + y().asConstant().asInt(), graph());
+            } else {
+                assert kind == CiKind.Long;
+                return Constant.forLong(x().asConstant().asLong() + y().asConstant().asLong(), graph());
             }
-            if (x.isConstant()) {
-                if (kind == CiKind.Int) {
-                    return Constant.forInt(x.asConstant().asInt() + y.asConstant().asInt(), graph);
-                } else {
-                    assert kind == CiKind.Long;
-                    return Constant.forLong(x.asConstant().asLong() + y.asConstant().asLong(), graph);
+        } else if (y().isConstant()) {
+            if (kind == CiKind.Int) {
+                int c = y().asConstant().asInt();
+                if (c == 0) {
+                    return x();
                 }
-            } else if (y.isConstant()) {
-                if (kind == CiKind.Int) {
-                    int c = y.asConstant().asInt();
-                    if (c == 0) {
-                        return x;
-                    }
-                } else {
-                    assert kind == CiKind.Long;
-                    long c = y.asConstant().asLong();
-                    if (c == 0) {
-                        return x;
-                    }
+            } else {
+                assert kind == CiKind.Long;
+                long c = y().asConstant().asLong();
+                if (c == 0) {
+                    return x();
                 }
             }
-            return add;
         }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerDiv.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerDiv.java	Tue Aug 09 18:59:29 2011 +0200
@@ -22,54 +22,38 @@
  */
 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.*;
 import com.sun.cri.ci.*;
 
 @NodeInfo(shortName = "/")
-public final class IntegerDiv extends IntegerArithmeticNode {
-    private static final IntegerDivCanonicalizerOp CANONICALIZER = new IntegerDivCanonicalizerOp();
+public final class IntegerDiv extends IntegerArithmeticNode implements Canonicalizable {
 
     public IntegerDiv(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.IDIV : Bytecodes.LDIV, x, y, graph);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (x().isConstant() && y().isConstant()) {
+            long yConst = y().asConstant().asLong();
+            if (yConst == 0) {
+                return this; // this will trap, can not canonicalize
+            }
+            if (kind == CiKind.Int) {
+                return Constant.forInt(x().asConstant().asInt() / (int) yConst, graph());
+            } else {
+                assert kind == CiKind.Long;
+                return Constant.forLong(x().asConstant().asLong() / yConst, graph());
+            }
+        } else if (y().isConstant()) {
+            long c = y().asConstant().asLong();
+            if (c == 1) {
+                return x();
+            }
         }
-        return super.lookup(clazz);
-    }
-
-    private static class IntegerDivCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            IntegerDiv div = (IntegerDiv) node;
-            Value x = div.x();
-            Value y = div.y();
-            CiKind kind = div.kind;
-            Graph graph = div.graph();
-            if (x.isConstant() && y.isConstant()) {
-                long yConst = y.asConstant().asLong();
-                if (yConst == 0) {
-                    return div; // this will trap, can not canonicalize
-                }
-                if (kind == CiKind.Int) {
-                    return Constant.forInt(x.asConstant().asInt() / (int) yConst, graph);
-                } else {
-                    assert kind == CiKind.Long;
-                    return Constant.forLong(x.asConstant().asLong() / yConst, graph);
-                }
-            } else if (y.isConstant()) {
-                long c = y.asConstant().asLong();
-                if (c == 1) {
-                    return x;
-                }
-            }
-            return div;
-        }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerMul.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerMul.java	Tue Aug 09 18:59:29 2011 +0200
@@ -22,62 +22,43 @@
  */
 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.*;
 import com.sun.cri.ci.*;
 
 @NodeInfo(shortName = "*")
-public final class IntegerMul extends IntegerArithmeticNode {
-    private static final IntegerMulCanonicalizerOp CANONICALIZER = new IntegerMulCanonicalizerOp();
+public final class IntegerMul extends IntegerArithmeticNode implements Canonicalizable {
 
     public IntegerMul(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.IMUL : Bytecodes.LMUL, x, y, graph);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (x().isConstant() && !y().isConstant()) {
+            swapOperands();
         }
-        return super.lookup(clazz);
-    }
-
-    private static class IntegerMulCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            IntegerMul mul = (IntegerMul) node;
-            Value x = mul.x();
-            Value y = mul.y();
-            CiKind kind = mul.kind;
-            Graph graph = mul.graph();
-            if (x.isConstant() && !y.isConstant()) {
-                mul.swapOperands();
-                Value t = y;
-                y = x;
-                x = t;
+        if (x().isConstant()) {
+            if (kind == CiKind.Int) {
+                return Constant.forInt(x().asConstant().asInt() * y().asConstant().asInt(), graph());
+            } else {
+                assert kind == CiKind.Long;
+                return Constant.forLong(x().asConstant().asLong() * y().asConstant().asLong(), graph());
             }
-            if (x.isConstant()) {
-                if (kind == CiKind.Int) {
-                    return Constant.forInt(x.asConstant().asInt() * y.asConstant().asInt(), graph);
-                } else {
-                    assert kind == CiKind.Long;
-                    return Constant.forLong(x.asConstant().asLong() * y.asConstant().asLong(), graph);
-                }
-            } else if (y.isConstant()) {
-                long c = y.asConstant().asLong();
-                if (c == 1) {
-                    return x;
-                }
-                if (c == 0) {
-                    return Constant.forInt(0, graph);
-                }
-                if (c > 0 && CiUtil.isPowerOf2(c)) {
-                    return new LeftShift(kind, x, Constant.forInt(CiUtil.log2(c), graph), graph);
-                }
+        } else if (y().isConstant()) {
+            long c = y().asConstant().asLong();
+            if (c == 1) {
+                return x();
             }
-            return mul;
+            if (c == 0) {
+                return Constant.forInt(0, graph());
+            }
+            if (c > 0 && CiUtil.isPowerOf2(c)) {
+                return new LeftShift(kind, x(), Constant.forInt(CiUtil.log2(c), graph()), graph());
+            }
         }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerRem.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerRem.java	Tue Aug 09 18:59:29 2011 +0200
@@ -22,54 +22,43 @@
  */
 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.*;
 import com.sun.cri.ci.*;
 
 @NodeInfo(shortName = "%")
-public final class IntegerRem extends IntegerArithmeticNode {
-    private static final IntegerRemCanonicalizerOp CANONICALIZER = new IntegerRemCanonicalizerOp();
+public final class IntegerRem extends IntegerArithmeticNode implements Canonicalizable {
 
     public IntegerRem(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.IREM : Bytecodes.LREM, x, y, graph);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
-        }
-        return super.lookup(clazz);
-    }
-
-    private static class IntegerRemCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            IntegerRem rem = (IntegerRem) node;
-            Value x = rem.x();
-            Value y = rem.y();
-            CiKind kind = rem.kind;
-            Graph graph = rem.graph();
-            if (x.isConstant() && y.isConstant()) {
-                long yConst = y.asConstant().asLong();
-                if (yConst == 0) {
-                    return rem; // this will trap, can not canonicalize
-                }
+    public Node canonical(NotifyReProcess reProcess) {
+        if (x().isConstant() && y().isConstant()) {
+            long yConst = y().asConstant().asLong();
+            if (yConst == 0) {
+                return this; // this will trap, can not canonicalize
+            }
+            if (kind == CiKind.Int) {
+                return Constant.forInt(x().asConstant().asInt() % (int) yConst, graph());
+            } else {
+                assert kind == CiKind.Long;
+                return Constant.forLong(x().asConstant().asLong() % yConst, graph());
+            }
+        } else if (y().isConstant()) {
+            long c = y().asConstant().asLong();
+            if (c == 1 || c == -1) {
                 if (kind == CiKind.Int) {
-                    return Constant.forInt(x.asConstant().asInt() % (int) yConst, graph);
+                    return Constant.forInt(0, graph());
                 } else {
                     assert kind == CiKind.Long;
-                    return Constant.forLong(x.asConstant().asLong() % yConst, graph);
-                }
-            } else if (y.isConstant()) {
-                long c = y.asConstant().asLong();
-                if (c == 1) {
-                    return x;
+                    return Constant.forLong(0, graph());
                 }
             }
-            return rem;
         }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.java	Tue Aug 09 18:59:29 2011 +0200
@@ -22,69 +22,53 @@
  */
 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.*;
 import com.sun.cri.ci.*;
 
 @NodeInfo(shortName = "-")
-public final class IntegerSub extends IntegerArithmeticNode {
-    private static final IntegerSubCanonicalizerOp CANONICALIZER = new IntegerSubCanonicalizerOp();
+public final class IntegerSub extends IntegerArithmeticNode implements Canonicalizable {
 
     public IntegerSub(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.ISUB : Bytecodes.LSUB, x, y, graph);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (x() == y()) {
+            if (kind == CiKind.Int) {
+                return Constant.forInt(0, graph());
+            } else {
+                assert kind == CiKind.Long;
+                return Constant.forLong(0, graph());
+            }
         }
-        return super.lookup(clazz);
-    }
-
-    private static class IntegerSubCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            IntegerSub sub = (IntegerSub) node;
-            Value x = sub.x();
-            Value y = sub.y();
-            CiKind kind = sub.kind;
-            Graph graph = sub.graph();
-            if (x == y) {
-                if (kind == CiKind.Int) {
-                    return Constant.forInt(0, graph);
-                } else {
-                    assert kind == CiKind.Long;
-                    return Constant.forLong(0, graph);
-                }
+        if (x().isConstant() && y().isConstant()) {
+            if (kind == CiKind.Int) {
+                return Constant.forInt(x().asConstant().asInt() - y().asConstant().asInt(), graph());
+            } else {
+                assert kind == CiKind.Long;
+                return Constant.forLong(x().asConstant().asLong() - y().asConstant().asLong(), graph());
             }
-            if (x.isConstant() && y.isConstant()) {
-                if (kind == CiKind.Int) {
-                    return Constant.forInt(x.asConstant().asInt() - y.asConstant().asInt(), graph);
-                } else {
-                    assert kind == CiKind.Long;
-                    return Constant.forLong(x.asConstant().asLong() - y.asConstant().asLong(), graph);
-                }
-            } else if (y.isConstant()) {
-                long c = y.asConstant().asLong();
-                if (c == 0) {
-                    return x;
-                }
-                if (kind == CiKind.Int) {
-                    return new IntegerAdd(kind, x, Constant.forInt((int) -c, graph), graph);
-                } else {
-                    assert kind ==  CiKind.Long;
-                    return new IntegerAdd(kind, x, Constant.forLong(-c, graph), graph);
-                }
-            } else if (x.isConstant()) {
-                long c = x.asConstant().asLong();
-                if (c == 0) {
-                    return new Negate(y, graph);
-                }
+        } else if (y().isConstant()) {
+            long c = y().asConstant().asLong();
+            if (c == 0) {
+                return x();
             }
-            return sub;
+            if (kind == CiKind.Int) {
+                return new IntegerAdd(kind, x(), Constant.forInt((int) -c, graph()), graph());
+            } else {
+                assert kind == CiKind.Long;
+                return new IntegerAdd(kind, x(), Constant.forLong(-c, graph()), graph());
+            }
+        } else if (x().isConstant()) {
+            long c = x().asConstant().asLong();
+            if (c == 0) {
+                return new Negate(y(), graph());
+            }
         }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java	Tue Aug 09 18:59:29 2011 +0200
@@ -23,7 +23,7 @@
 package com.oracle.max.graal.compiler.ir;
 
 import com.oracle.max.graal.compiler.debug.*;
-import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.Canonicalizable;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
@@ -32,9 +32,9 @@
 /**
  * The {@code NullCheck} class represents an explicit null check instruction.
  */
-public final class IsNonNull extends BooleanNode {
+public final class IsNonNull extends BooleanNode implements Canonicalizable {
 
-    @Input    private Value object;
+    @Input private Value object;
 
     public Value object() {
         return object;
@@ -47,6 +47,7 @@
 
     /**
      * Constructs a new NullCheck instruction.
+     *
      * @param object the instruction producing the object to check against null
      * @param graph
      */
@@ -78,29 +79,16 @@
         out.print("null_check(").print(object()).print(')');
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (object() instanceof NewInstance || object() instanceof NewArray) {
+            return Constant.forBoolean(true, graph());
         }
-        return super.lookup(clazz);
+        CiConstant constant = object().asConstant();
+        if (constant != null) {
+            assert constant.kind == CiKind.Object;
+            return Constant.forBoolean(constant.isNonNull(), graph());
+        }
+        return this;
     }
-
-    private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            IsNonNull isNonNull = (IsNonNull) node;
-            Value object = isNonNull.object();
-            if (object instanceof NewInstance || object instanceof NewArray) {
-                return Constant.forBoolean(true, node.graph());
-            }
-            CiConstant constant = object.asConstant();
-            if (constant != null) {
-                assert constant.kind == CiKind.Object;
-                return Constant.forBoolean(constant.isNonNull(), node.graph());
-            }
-            return isNonNull;
-        }
-    };
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java	Tue Aug 09 18:59:29 2011 +0200
@@ -25,7 +25,7 @@
 import java.util.*;
 
 import com.oracle.max.graal.compiler.debug.*;
-import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.Canonicalizable;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
@@ -34,9 +34,9 @@
 /**
  * The {@code TypeCheck} class represents an explicit type check instruction.
  */
-public final class IsType extends BooleanNode {
+public final class IsType extends BooleanNode implements Canonicalizable {
 
-    @Input    private Value object;
+    @Input private Value object;
 
     public Value object() {
         return object;
@@ -51,6 +51,7 @@
 
     /**
      * Constructs a new IsType instruction.
+     *
      * @param object the instruction producing the object to check against the given type
      * @param graph
      */
@@ -94,26 +95,12 @@
         return properties;
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (object().exactType() != null) {
+            return Constant.forBoolean(object().exactType() == type(), graph());
         }
-        return super.lookup(clazz);
+        // constants return the correct exactType, so they are handled by the code above
+        return this;
     }
-
-    private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            IsType isType = (IsType) node;
-            Value object = isType.object();
-            RiType exactType = object.exactType();
-            if (exactType != null) {
-                return Constant.forBoolean(exactType == isType.type, node.graph());
-            }
-            // constants return the correct exactType, so they are handled by the code above
-            return isType;
-        }
-    };
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LeftShift.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LeftShift.java	Tue Aug 09 18:59:29 2011 +0200
@@ -22,84 +22,67 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
-import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.Canonicalizable;
 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.*;
 
 @NodeInfo(shortName = "<<")
-public final class LeftShift extends Shift {
-    private static final LeftShiftCanonicalizerOp CANONICALIZER = new LeftShiftCanonicalizerOp();
+public final class LeftShift extends Shift implements Canonicalizable {
 
     public LeftShift(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.ISHL : Bytecodes.LSHL, x, y, graph);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
-        }
-        return super.lookup(clazz);
-    }
-
-    private static class LeftShiftCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            LeftShift leftShift = (LeftShift) node;
-            CiKind kind = leftShift.kind;
-            Graph graph = leftShift.graph();
-            Value value = leftShift.x();
-            Value y = leftShift.y();
-            if (y.isConstant()) {
-                int amount = y.asConstant().asInt();
-                int originalAmout = amount;
-                int mask;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (y().isConstant()) {
+            int amount = y().asConstant().asInt();
+            int originalAmout = amount;
+            int mask;
+            if (kind == CiKind.Int) {
+                mask = 0x1f;
+            } else {
+                assert kind == CiKind.Long;
+                mask = 0x3f;
+            }
+            amount &= mask;
+            if (x().isConstant()) {
                 if (kind == CiKind.Int) {
-                    mask = 0x1f;
+                    return Constant.forInt(x().asConstant().asInt() << amount, graph());
                 } else {
                     assert kind == CiKind.Long;
-                    mask = 0x3f;
+                    return Constant.forLong(x().asConstant().asLong() << amount, graph());
                 }
-                amount &= mask;
-                if (value.isConstant()) {
-                    if (kind == CiKind.Int) {
-                        return Constant.forInt(value.asConstant().asInt() << amount, graph);
-                    } else {
-                        assert kind == CiKind.Long;
-                        return Constant.forLong(value.asConstant().asLong() << amount, graph);
-                    }
-                }
-                if (amount == 0) {
-                    return value;
-                }
-                if (value instanceof Shift) {
-                    Shift other = (Shift) value;
-                    if (other.y().isConstant()) {
-                        int otherAmount = other.y().asConstant().asInt() & mask;
-                        if (other instanceof LeftShift) {
-                            int total = amount + otherAmount;
-                            if (total != (total & mask)) {
-                                return Constant.forInt(0, graph);
-                            }
-                            return new LeftShift(kind, other.x(), Constant.forInt(total, graph), graph);
-                        } else if ((other instanceof RightShift || other instanceof UnsignedRightShift) && otherAmount == amount) {
-                            if (kind == CiKind.Long) {
-                                return new And(kind, other.x(), Constant.forLong(-1L << amount, graph), graph);
-                            } else {
-                                assert kind == CiKind.Int;
-                                return new And(kind, other.x(), Constant.forInt(-1 << amount, graph), graph);
-                            }
+            }
+            if (amount == 0) {
+                return x();
+            }
+            if (x() instanceof Shift) {
+                Shift other = (Shift) x();
+                if (other.y().isConstant()) {
+                    int otherAmount = other.y().asConstant().asInt() & mask;
+                    if (other instanceof LeftShift) {
+                        int total = amount + otherAmount;
+                        if (total != (total & mask)) {
+                            return Constant.forInt(0, graph());
+                        }
+                        return new LeftShift(kind, other.x(), Constant.forInt(total, graph()), graph());
+                    } else if ((other instanceof RightShift || other instanceof UnsignedRightShift) && otherAmount == amount) {
+                        if (kind == CiKind.Long) {
+                            return new And(kind, other.x(), Constant.forLong(-1L << amount, graph()), graph());
+                        } else {
+                            assert kind == CiKind.Int;
+                            return new And(kind, other.x(), Constant.forInt(-1 << amount, graph()), graph());
                         }
                     }
                 }
-                if (originalAmout != amount) {
-                    return new LeftShift(kind, value, Constant.forInt(amount, graph), graph);
-                }
             }
-            return leftShift;
+            if (originalAmout != amount) {
+                return new LeftShift(kind, x(), Constant.forInt(amount, graph()), graph());
+            }
         }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java	Tue Aug 09 18:59:29 2011 +0200
@@ -23,10 +23,8 @@
 package com.oracle.max.graal.compiler.ir;
 
 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.Canonicalizable;
 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.*;
 import com.sun.cri.ri.*;
@@ -34,11 +32,11 @@
 /**
  * The {@code LoadField} instruction represents a read of a static or instance field.
  */
-public final class LoadField extends AccessField {
-    private static final LoadFieldCanonicalizerOp CANONICALIZER = new LoadFieldCanonicalizerOp();
+public final class LoadField extends AccessField implements Canonicalizable {
 
     /**
      * Creates a new LoadField instance.
+     *
      * @param object the receiver object
      * @param field the compiler interface field
      * @param isStatic indicates if the field is static
@@ -52,6 +50,7 @@
 
     /**
      * Gets the declared type of the field being accessed.
+     *
      * @return the declared type of the field being accessed.
      */
     @Override
@@ -60,9 +59,9 @@
     }
 
     /**
-     * Gets the exact type of the field being accessed. If the field type is
-     * a primitive array or an instance class and the class is loaded and final,
-     * then the exact type is the same as the declared type. Otherwise it is {@code null}
+     * Gets the exact type of the field being accessed. If the field type is a primitive array or an instance class and
+     * the class is loaded and final, then the exact type is the same as the declared type. Otherwise it is {@code null}
+     *
      * @return the exact type of the field if known; {@code null} otherwise
      */
     @Override
@@ -78,12 +77,7 @@
 
     @Override
     public void print(LogStream out) {
-        out.print(object()).
-        print(".").
-        print(field.name()).
-        print(" [field: ").
-        print(CiUtil.format("%h.%n:%t", field, false)).
-        print("]");
+        out.print(object()).print(".").print(field.name()).print(" [field: ").print(CiUtil.format("%h.%n:%t", field, false)).print("]");
     }
 
     @Override
@@ -105,35 +99,17 @@
         return null;
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
-        } else if (clazz == LoweringOp.class) {
-            return (T) LoweringPhase.DELEGATE_TO_RUNTIME;
+    public Node canonical(NotifyReProcess reProcess) {
+        CiConstant constant = null;
+        if (isStatic()) {
+            constant = field().constantValue(null);
+        } else if (object().isConstant()) {
+            constant = field().constantValue(object().asConstant());
         }
-        return super.lookup(clazz);
-    }
-
-    private static class LoadFieldCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            LoadField loadField = (LoadField) node;
-            Graph graph = node.graph();
-            CiConstant constant = null;
-            if (loadField.isStatic()) {
-                    constant = loadField.field().constantValue(null);
-            } else {
-                Value object = loadField.object();
-                if (object.isConstant()) {
-                    constant = loadField.field().constantValue(object.asConstant());
-                }
-            }
-            if (constant != null) {
-                return new Constant(constant, graph);
-            }
-            return loadField;
+        if (constant != null) {
+            return new Constant(constant, graph());
         }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Negate.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Negate.java	Tue Aug 09 18:59:29 2011 +0200
@@ -31,10 +31,10 @@
 /**
  * The {@code NegateOp} instruction negates its operand.
  */
-public final class Negate extends FloatingNode {
-    private static final NegateCanonicalizerOp CANONICALIZER = new NegateCanonicalizerOp();
+public final class Negate extends FloatingNode implements Canonicalizable {
 
-    @Input    private Value x;
+    @Input
+    private Value x;
 
     public Value x() {
         return x;
@@ -47,6 +47,7 @@
 
     /**
      * Creates new NegateOp instance.
+     *
      * @param x the instruction producing the value that is input to this instruction
      */
     public Negate(Value x, Graph graph) {
@@ -69,33 +70,23 @@
         out.print("- ").print(x());
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (x().isConstant()) {
+            switch (x().kind) {
+                case Int:
+                    return Constant.forInt(-x().asConstant().asInt(), graph());
+                case Long:
+                    return Constant.forLong(-x().asConstant().asLong(), graph());
+                case Float:
+                    return Constant.forFloat(-x().asConstant().asFloat(), graph());
+                case Double:
+                    return Constant.forDouble(-x().asConstant().asDouble(), graph());
+            }
         }
-        return super.lookup(clazz);
-    }
-
-    private static class NegateCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            Negate negate = (Negate) node;
-            Value x = negate.x();
-            Graph graph = negate.graph();
-            if (x.isConstant()) {
-                switch (x.kind) {
-                    case Int: return Constant.forInt(-x.asConstant().asInt(), graph);
-                    case Long: return Constant.forLong(-x.asConstant().asLong(), graph);
-                    case Float: return Constant.forFloat(-x.asConstant().asFloat(), graph);
-                    case Double: return Constant.forDouble(-x.asConstant().asDouble(), graph);
-                }
-            }
-            if (x instanceof Negate) {
-                return ((Negate) x).x();
-            }
-            return negate;
+        if (x() instanceof Negate) {
+            return ((Negate) x()).x();
         }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NegateBooleanNode.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NegateBooleanNode.java	Tue Aug 09 18:59:29 2011 +0200
@@ -23,14 +23,14 @@
 package com.oracle.max.graal.compiler.ir;
 
 import com.oracle.max.graal.compiler.debug.*;
-import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.Canonicalizable;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 
-public final class NegateBooleanNode extends BooleanNode {
+public final class NegateBooleanNode extends BooleanNode implements Canonicalizable {
 
-    @Input    private BooleanNode value;
+    @Input private BooleanNode value;
 
     public BooleanNode value() {
         return value;
@@ -55,26 +55,13 @@
         out.print(value()).print("!");
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (value() instanceof NegateBooleanNode) {
+            return ((NegateBooleanNode) value()).value();
+        } else if (value() instanceof Constant) {
+            return Constant.forBoolean(!value().asConstant().asBoolean(), graph());
         }
-        return super.lookup(clazz);
+        return this;
     }
-
-    private static final CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
-        @Override
-        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());
-            }
-            return negateNode;
-        }
-    };
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewMultiArray.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewMultiArray.java	Tue Aug 09 18:59:29 2011 +0200
@@ -33,7 +33,7 @@
  */
 public final class NewMultiArray extends NewArray {
 
-    @Input    private final NodeInputList<Value> dimensions;
+    @Input private final NodeInputList<Value> dimensions;
 
     @Override
     public Value dimension(int index) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Or.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Or.java	Tue Aug 09 18:59:29 2011 +0200
@@ -22,73 +22,54 @@
  */
 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.*;
 import com.sun.cri.ci.*;
 
 @NodeInfo(shortName = "|")
-public final class Or extends Logic {
-    private static final OrCanonicalizerOp CANONICALIZER = new OrCanonicalizerOp();
+public final class Or extends Logic implements Canonicalizable {
 
     public Or(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.IOR : Bytecodes.LOR, x, y, graph);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (x() == y()) {
+            return x();
         }
-        return super.lookup(clazz);
-    }
-
-    private static class OrCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            Or or = (Or) node;
-            CiKind kind = or.kind;
-            Graph graph = or.graph();
-            Value x = or.x();
-            Value y = or.y();
-            if (x == y) {
-                return x;
+        if (x().isConstant() && !y().isConstant()) {
+            swapOperands();
+        }
+        if (x().isConstant()) {
+            if (kind == CiKind.Int) {
+                return Constant.forInt(x().asConstant().asInt() | y().asConstant().asInt(), graph());
+            } else {
+                assert kind == CiKind.Long;
+                return Constant.forLong(x().asConstant().asLong() | y().asConstant().asLong(), graph());
             }
-            if (x.isConstant() && !y.isConstant()) {
-                or.swapOperands();
-                Value t = y;
-                y = x;
-                x = t;
-            }
-            if (x.isConstant()) {
-                if (kind == CiKind.Int) {
-                    return Constant.forInt(x.asConstant().asInt() | y.asConstant().asInt(), graph);
-                } else {
-                    assert kind == CiKind.Long;
-                    return Constant.forLong(x.asConstant().asLong() | y.asConstant().asLong(), graph);
+        } else if (y().isConstant()) {
+            if (kind == CiKind.Int) {
+                int c = y().asConstant().asInt();
+                if (c == -1) {
+                    return Constant.forInt(-1, graph());
                 }
-            } else if (y.isConstant()) {
-                if (kind == CiKind.Int) {
-                    int c = y.asConstant().asInt();
-                    if (c == -1) {
-                        return Constant.forInt(-1, graph);
-                    }
-                    if (c == 0) {
-                        return x;
-                    }
-                } else {
-                    assert kind == CiKind.Long;
-                    long c = y.asConstant().asLong();
-                    if (c == -1) {
-                        return Constant.forLong(-1, graph);
-                    }
-                    if (c == 0) {
-                        return x;
-                    }
+                if (c == 0) {
+                    return x();
+                }
+            } else {
+                assert kind == CiKind.Long;
+                long c = y().asConstant().asLong();
+                if (c == -1) {
+                    return Constant.forLong(-1, graph());
+                }
+                if (c == 0) {
+                    return x();
                 }
             }
-            return or;
         }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java	Tue Aug 09 18:59:29 2011 +0200
@@ -27,20 +27,20 @@
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
 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.Canonicalizable;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 
 /**
- * The {@code Phi} instruction represents the merging of dataflow
- * in the instruction graph. It refers to a join block and a variable.
+ * The {@code Phi} instruction represents the merging of dataflow in the instruction graph. It refers to a join block
+ * and a variable.
  */
-public final class Phi extends FloatingNode {
+public final class Phi extends FloatingNode implements Canonicalizable {
 
-    @Input    private Merge merge;
+    @Input private Merge merge;
 
-    @Input    private final NodeInputList<Value> values = new NodeInputList<Value>(this);
+    @Input private final NodeInputList<Value> values = new NodeInputList<Value>(this);
 
     public Merge merge() {
         return merge;
@@ -52,9 +52,9 @@
     }
 
     public static enum PhiType {
-        Value,          // normal value phis
-        Memory,         // memory phis
-        Virtual         // phis used for VirtualObjectField merges
+        Value, // normal value phis
+        Memory, // memory phis
+        Virtual // phis used for VirtualObjectField merges
     }
 
     private final PhiType type;
@@ -82,8 +82,8 @@
     }
 
     /**
-     * Get the instruction that produces the value associated with the i'th predecessor
-     * of the join block.
+     * Get the instruction that produces the value associated with the i'th predecessor of the join block.
+     *
      * @param i the index of the predecessor
      * @return the instruction that produced the value in the i'th predecessor
      */
@@ -97,6 +97,7 @@
 
     /**
      * Get the number of inputs to this phi (i.e. the number of predecessors to the join block).
+     *
      * @return the number of inputs in this phi
      */
     public int valueCount() {
@@ -145,9 +146,10 @@
     }
 
     @Override
-    public Iterable<? extends Node> dataInputs() {
+    public Iterable< ? extends Node> dataInputs() {
         final Iterator< ? extends Node> input = super.dataInputs().iterator();
         return new Iterable<Node>() {
+
             @Override
             public Iterator<Node> iterator() {
                 return new FilteringIterator(input, Merge.class);
@@ -155,58 +157,42 @@
         };
     }
 
-
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (valueCount() != 2 || merge().endCount() != 2) {
+            return this;
         }
-        return super.lookup(clazz);
+        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 this;
+        }
+        Node end0 = merge().endAt(0);
+        Node end1 = merge().endAt(1);
+        Node endPred0 = end0.predecessor();
+        Node endPred1 = end1.predecessor();
+        if (endPred0 != endPred1 || !(endPred0 instanceof If)) {
+            return this;
+        }
+        If ifNode = (If) endPred0;
+        boolean inverted = ifNode.trueSuccessor() == end1;
+        Value trueValue = valueAt(inverted ? 1 : 0);
+        Value falseValue = valueAt(inverted ? 0 : 1);
+        if ((trueValue.kind != CiKind.Int && trueValue.kind != CiKind.Long) || (falseValue.kind != CiKind.Int && falseValue.kind != CiKind.Long)) {
+            return this;
+        }
+        if ((!(trueValue instanceof Constant) && trueValue.usages().size() == 1) || (!(falseValue instanceof Constant) && falseValue.usages().size() == 1)) {
+            return this;
+        }
+        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 this;
+        }
+        if (GraalOptions.TraceCanonicalizer) {
+            TTY.println("> Phi canon'ed to Conditional");
+        }
+        reProcess.reProccess(ifNode);
+        return new Conditional(ifNode.compare(), trueValue, falseValue, graph());
     }
-
-    private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
-
-        @Override
-        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);
-            Node endPred0 = end0.predecessor();
-            Node endPred1 = end1.predecessor();
-            if (endPred0 != endPred1 || !(endPred0 instanceof If)) {
-                return phiNode;
-            }
-            If ifNode = (If) endPred0;
-            boolean inverted = ifNode.trueSuccessor() == end1;
-            Value trueValue = phiNode.valueAt(inverted ? 1 : 0);
-            Value falseValue = phiNode.valueAt(inverted ? 0 : 1);
-            if ((trueValue.kind != CiKind.Int && trueValue.kind != CiKind.Long) || (falseValue.kind != CiKind.Int && falseValue.kind != CiKind.Long)) {
-                return phiNode;
-            }
-            if ((!(trueValue instanceof Constant) && trueValue.usages().size() == 1) || (!(falseValue instanceof Constant) && falseValue.usages().size() == 1)) {
-                return phiNode;
-            }
-            BooleanNode compare = ifNode.compare();
-            while (compare instanceof NegateBooleanNode) {
-                compare = ((NegateBooleanNode) compare).value();
-            }
-            if (!(compare instanceof Compare || compare instanceof IsNonNull || compare instanceof NegateBooleanNode || compare instanceof Constant)) {
-                return phiNode;
-            }
-            if (GraalOptions.TraceCanonicalizer) {
-                TTY.println("> Phi canon'ed to Conditional");
-            }
-            reProcess.reProccess(ifNode);
-            Conditional conditional = new Conditional(ifNode.compare(), trueValue, falseValue, node.graph());
-            return conditional;
-        }
-    };
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java	Tue Aug 09 18:59:29 2011 +0200
@@ -25,7 +25,7 @@
 import com.oracle.max.graal.compiler.*;
 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.Canonicalizable;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.NotifyReProcess;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
@@ -34,7 +34,8 @@
 /**
  * This instruction is used to perform the finalizer registration at the end of the java.lang.Object constructor.
  */
-public final class RegisterFinalizer extends StateSplit {
+public final class RegisterFinalizer extends StateSplit implements Canonicalizable {
+
     @Input private Value object;
 
     public Value object() {
@@ -56,58 +57,43 @@
         v.visitRegisterFinalizer(this);
     }
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
-        }
-        return super.lookup(clazz);
-    }
-
-    private static final CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
-
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            RegisterFinalizer finalizer = (RegisterFinalizer) node;
-            Value object = finalizer.object();
-
-            RiType declaredType = object.declaredType();
-            RiType exactType = object.exactType();
-            if (exactType == null && declaredType != null) {
-                exactType = declaredType.exactType();
-            }
-
-            boolean needsCheck = true;
-            if (exactType != null) {
-                // we have an exact type
-                needsCheck = exactType.hasFinalizer();
-            } else {
-                // if either the declared type of receiver or the holder can be assumed to have no finalizers
-                if (declaredType != null && !declaredType.hasFinalizableSubclass()) {
-                    if (((CompilerGraph) node.graph()).assumptions().recordNoFinalizableSubclassAssumption(declaredType)) {
-                        needsCheck = false;
-                    }
-                }
-            }
-
-            if (needsCheck) {
-                if (GraalOptions.TraceCanonicalizer) {
-                    TTY.println("Could not canonicalize finalizer " + object + " (declaredType=" + declaredType + ", exactType=" + exactType + ")");
-                }
-            } else {
-                if (GraalOptions.TraceCanonicalizer) {
-                    TTY.println("Canonicalized finalizer for object " + object);
-                }
-                return finalizer.next();
-            }
-
-            return finalizer;
-        }
-    };
-
     @Override
     public void print(LogStream out) {
         out.print("register finalizer ").print(object());
     }
+
+    @Override
+    public Node canonical(NotifyReProcess reProcess) {
+        RiType declaredType = object.declaredType();
+        RiType exactType = object.exactType();
+        if (exactType == null && declaredType != null) {
+            exactType = declaredType.exactType();
+        }
+
+        boolean needsCheck = true;
+        if (exactType != null) {
+            // we have an exact type
+            needsCheck = exactType.hasFinalizer();
+        } else {
+            // if either the declared type of receiver or the holder can be assumed to have no finalizers
+            if (declaredType != null && !declaredType.hasFinalizableSubclass()) {
+                if (((CompilerGraph) graph()).assumptions().recordNoFinalizableSubclassAssumption(declaredType)) {
+                    needsCheck = false;
+                }
+            }
+        }
+
+        if (needsCheck) {
+            if (GraalOptions.TraceCanonicalizer) {
+                TTY.println("Could not canonicalize finalizer " + object + " (declaredType=" + declaredType + ", exactType=" + exactType + ")");
+            }
+        } else {
+            if (GraalOptions.TraceCanonicalizer) {
+                TTY.println("Canonicalized finalizer for object " + object);
+            }
+            return next();
+        }
+
+        return this;
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RightShift.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RightShift.java	Tue Aug 09 18:59:29 2011 +0200
@@ -22,76 +22,60 @@
  */
 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.*;
 import com.sun.cri.ci.*;
 
 @NodeInfo(shortName = ">>")
-public final class RightShift extends Shift {
-    private static final RighShiftCanonicalizerOp CANONICALIZER = new RighShiftCanonicalizerOp();
+public final class RightShift extends Shift implements Canonicalizable {
 
     public RightShift(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.ISHR : Bytecodes.LSHR, x, y, graph);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
-        }
-        return super.lookup(clazz);
-    }
-
-    private static class RighShiftCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            RightShift rightShift = (RightShift) node;
-            CiKind kind = rightShift.kind;
-            Graph graph = rightShift.graph();
-            Value value = rightShift.x();
-            Value y = rightShift.y();
-            if (y.isConstant()) {
-                int amount = y.asConstant().asInt();
-                int originalAmout = amount;
-                int mask;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (y().isConstant()) {
+            int amount = y().asConstant().asInt();
+            int originalAmout = amount;
+            int mask;
+            if (kind == CiKind.Int) {
+                mask = 0x1f;
+            } else {
+                assert kind == CiKind.Long;
+                mask = 0x3f;
+            }
+            amount &= mask;
+            if (x().isConstant()) {
                 if (kind == CiKind.Int) {
-                    mask = 0x1f;
+                    return Constant.forInt(x().asConstant().asInt() >> amount, graph());
                 } else {
                     assert kind == CiKind.Long;
-                    mask = 0x3f;
+                    return Constant.forLong(x().asConstant().asLong() >> amount, graph());
                 }
-                amount &= mask;
-                if (value.isConstant()) {
-                    if (kind == CiKind.Int) {
-                        return Constant.forInt(value.asConstant().asInt() >> amount, graph);
-                    } else {
-                        assert kind == CiKind.Long;
-                        return Constant.forLong(value.asConstant().asLong() >> amount, graph);
+            }
+            if (amount == 0) {
+                return x();
+            }
+            if (x() instanceof Shift) {
+                Shift other = (Shift) x();
+                if (other.y().isConstant()) {
+                    int otherAmount = other.y().asConstant().asInt() & mask;
+                    if (other instanceof RightShift) {
+                        int total = amount + otherAmount;
+                        if (total != (total & mask)) {
+                            return Constant.forInt(0, graph());
+                        }
+                        return new RightShift(kind, other.x(), Constant.forInt(total, graph()), graph());
                     }
                 }
-                if (amount == 0) {
-                    return value;
-                }
-                if (value instanceof Shift) {
-                    Shift other = (Shift) value;
-                    if (other.y().isConstant()) {
-                        int otherAmount = other.y().asConstant().asInt() & mask;
-                        if (other instanceof RightShift) {
-                            int total = amount + otherAmount;
-                            if (total != (total & mask)) {
-                                return Constant.forInt(0, graph);
-                            }
-                            return new RightShift(kind, other.x(), Constant.forInt(total, graph), graph);
-                        }
-                    }
-                }
-                if (originalAmout != amount) {
-                    return new RightShift(kind, value, Constant.forInt(amount, graph), graph);
-                }
             }
-            return rightShift;
+            if (originalAmout != amount) {
+                return new RightShift(kind, x(), Constant.forInt(amount, graph()), graph());
+            }
         }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/UnsignedRightShift.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/UnsignedRightShift.java	Tue Aug 09 18:59:29 2011 +0200
@@ -22,83 +22,67 @@
  */
 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.*;
 import com.sun.cri.ci.*;
 
 @NodeInfo(shortName = ">>>")
-public final class UnsignedRightShift extends Shift {
-    private static final UnsignedRightShiftCanonicalizerOp CANONICALIZER = new UnsignedRightShiftCanonicalizerOp();
+public final class UnsignedRightShift extends Shift implements Canonicalizable {
 
     public UnsignedRightShift(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.IUSHR : Bytecodes.LUSHR, x, y, graph);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
-        }
-        return super.lookup(clazz);
-    }
-
-    private static class UnsignedRightShiftCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            UnsignedRightShift ushr = (UnsignedRightShift) node;
-            CiKind kind = ushr.kind;
-            Graph graph = ushr.graph();
-            Value value = ushr.x();
-            Value y = ushr.y();
-            if (y.isConstant()) {
-                int amount = y.asConstant().asInt();
-                int originalAmout = amount;
-                int mask;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (y().isConstant()) {
+            int amount = y().asConstant().asInt();
+            int originalAmout = amount;
+            int mask;
+            if (kind == CiKind.Int) {
+                mask = 0x1f;
+            } else {
+                assert kind == CiKind.Long;
+                mask = 0x3f;
+            }
+            amount &= mask;
+            if (x().isConstant()) {
                 if (kind == CiKind.Int) {
-                    mask = 0x1f;
+                    return Constant.forInt(x().asConstant().asInt() >>> amount, graph());
                 } else {
                     assert kind == CiKind.Long;
-                    mask = 0x3f;
+                    return Constant.forLong(x().asConstant().asLong() >>> amount, graph());
                 }
-                amount &= mask;
-                if (value.isConstant()) {
-                    if (kind == CiKind.Int) {
-                        return Constant.forInt(value.asConstant().asInt() >>> amount, graph);
-                    } else {
-                        assert kind == CiKind.Long;
-                        return Constant.forLong(value.asConstant().asLong() >>> amount, graph);
-                    }
-                }
-                if (amount == 0) {
-                    return value;
-                }
-                if (value instanceof Shift) {
-                    Shift other = (Shift) value;
-                    if (other.y().isConstant()) {
-                        int otherAmount = other.y().asConstant().asInt() & mask;
-                        if (other instanceof UnsignedRightShift) {
-                            int total = amount + otherAmount;
-                            if (total != (total & mask)) {
-                                return Constant.forInt(0, graph);
-                            }
-                            return new UnsignedRightShift(kind, other.x(), Constant.forInt(total, graph), graph);
-                        } else if (other instanceof LeftShift && otherAmount == amount) {
-                            if (kind == CiKind.Long) {
-                                return new And(kind, other.x(), Constant.forLong(-1L >>> amount, graph), graph);
-                            } else {
-                                assert kind == CiKind.Int;
-                                return new And(kind, other.x(), Constant.forInt(-1 >>> amount, graph), graph);
-                            }
+            }
+            if (amount == 0) {
+                return x();
+            }
+            if (x() instanceof Shift) {
+                Shift other = (Shift) x();
+                if (other.y().isConstant()) {
+                    int otherAmount = other.y().asConstant().asInt() & mask;
+                    if (other instanceof UnsignedRightShift) {
+                        int total = amount + otherAmount;
+                        if (total != (total & mask)) {
+                            return Constant.forInt(0, graph());
+                        }
+                        return new UnsignedRightShift(kind, other.x(), Constant.forInt(total, graph()), graph());
+                    } else if (other instanceof LeftShift && otherAmount == amount) {
+                        if (kind == CiKind.Long) {
+                            return new And(kind, other.x(), Constant.forLong(-1L >>> amount, graph()), graph());
+                        } else {
+                            assert kind == CiKind.Int;
+                            return new And(kind, other.x(), Constant.forInt(-1 >>> amount, graph()), graph());
                         }
                     }
                 }
-                if (originalAmout != amount) {
-                    return new UnsignedRightShift(kind, value, Constant.forInt(amount, graph), graph);
-                }
             }
-            return ushr;
+            if (originalAmout != amount) {
+                return new UnsignedRightShift(kind, x(), Constant.forInt(amount, graph()), graph());
+            }
         }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Xor.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Xor.java	Tue Aug 09 18:59:29 2011 +0200
@@ -22,73 +22,53 @@
  */
 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.*;
 import com.sun.cri.ci.*;
 
 @NodeInfo(shortName = "^")
-public final class Xor extends Logic {
-    private static final XorCanonicalizerOp CANONICALIZER = new XorCanonicalizerOp();
+public final class Xor extends Logic implements Canonicalizable {
 
     public Xor(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.IXOR : Bytecodes.LXOR, x, y, graph);
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public <T extends Op> T lookup(Class<T> clazz) {
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANONICALIZER;
+    public Node canonical(NotifyReProcess reProcess) {
+        if (x() == y()) {
+            if (kind == CiKind.Int) {
+                return Constant.forInt(0, graph());
+            } else {
+                assert kind == CiKind.Long;
+                return Constant.forLong(0L, graph());
+            }
         }
-        return super.lookup(clazz);
-    }
-
-    private static class XorCanonicalizerOp implements CanonicalizerOp {
-        @Override
-        public Node canonical(Node node, NotifyReProcess reProcess) {
-            assert node instanceof Xor;
-            Xor xor = (Xor) node;
-            CiKind kind = xor.kind;
-            Graph graph = xor.graph();
-            Value x = xor.x();
-            Value y = xor.y();
-            if (x == y) {
-                if (kind == CiKind.Int) {
-                    return Constant.forInt(0, graph);
-                } else {
-                    assert kind == CiKind.Long;
-                    return Constant.forLong(0L, graph);
+        if (x().isConstant() && !y().isConstant()) {
+            swapOperands();
+        }
+        if (x().isConstant()) {
+            if (kind == CiKind.Int) {
+                return Constant.forInt(x().asConstant().asInt() ^ y().asConstant().asInt(), graph());
+            } else {
+                assert kind == CiKind.Long;
+                return Constant.forLong(x().asConstant().asLong() ^ y().asConstant().asLong(), graph());
+            }
+        } else if (y().isConstant()) {
+            if (kind == CiKind.Int) {
+                int c = y().asConstant().asInt();
+                if (c == 0) {
+                    return x();
+                }
+            } else {
+                assert kind == CiKind.Long;
+                long c = y().asConstant().asLong();
+                if (c == 0) {
+                    return x();
                 }
             }
-            if (x.isConstant() && !y.isConstant()) {
-                xor.swapOperands();
-                Value t = y;
-                y = x;
-                x = t;
-            }
-            if (x.isConstant()) {
-                if (kind == CiKind.Int) {
-                    return Constant.forInt(x.asConstant().asInt() ^ y.asConstant().asInt(), graph);
-                } else {
-                    assert kind == CiKind.Long;
-                    return Constant.forLong(x.asConstant().asLong() ^ y.asConstant().asLong(), graph);
-                }
-            } else if (y.isConstant()) {
-                if (kind == CiKind.Int) {
-                    int c = y.asConstant().asInt();
-                    if (c == 0) {
-                        return x;
-                    }
-                } else {
-                    assert kind == CiKind.Long;
-                    long c = y.asConstant().asLong();
-                    if (c == 0) {
-                        return x;
-                    }
-                }
-            }
-            return xor;
         }
+        return this;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java	Tue Aug 09 18:59:29 2011 +0200
@@ -53,13 +53,12 @@
             }
         };
         for (Node node : nodeWorkList) {
-            CanonicalizerOp op = node.lookup(CanonicalizerOp.class);
-            if (op != null) {
+            if (node instanceof Canonicalizable) {
                 if (GraalOptions.TraceCanonicalizer) {
                     TTY.println("Canonicalizer: work on " + node);
                 }
                 graph.mark();
-                Node canonical = op.canonical(node, reProcess);
+                Node canonical = ((Canonicalizable) node).canonical(reProcess);
                 if (canonical != node) {
                     node.replaceAndDelete(canonical);
                     nodeWorkList.replaced(canonical, node, false, EdgeType.USAGES);
@@ -76,7 +75,7 @@
         void reProccess(Node n);
     }
 
-    public interface CanonicalizerOp extends Op {
-        Node canonical(Node node, NotifyReProcess reProcess);
+    public interface Canonicalizable {
+        Node canonical(NotifyReProcess reProcess);
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Tue Aug 09 18:59:29 2011 +0200
@@ -845,7 +845,7 @@
 
     private void genGetStatic(int cpi, RiField field) {
         RiType holder = field.holder();
-        boolean isInitialized = field.isResolved() && field.holder().isInitialized();
+        boolean isInitialized = field.isResolved() && holder.isInitialized();
         CiConstant constantValue = null;
         if (isInitialized) {
             constantValue = field.constantValue(null);
@@ -867,7 +867,7 @@
 
     private void genPutStatic(int cpi, RiField field) {
         RiType holder = field.holder();
-        Value container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, field.isResolved() && field.holder().isInitialized());
+        Value container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, field.isResolved() && holder.isInitialized());
         Value value = frameState.pop(field.kind().stackKind());
         if (container != null) {
             StoreField store = new StoreField(container, field, value, graph);
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FPConversionNode.java	Tue Aug 09 18:53:11 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FPConversionNode.java	Tue Aug 09 18:59:29 2011 +0200
@@ -26,12 +26,14 @@
 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.NotifyReProcess;
 import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 
 
-public final class FPConversionNode extends FloatingNode {
+public final class FPConversionNode extends FloatingNode implements Canonicalizable {
+
     @Input private Value value;
 
     public Value value() {
@@ -48,16 +50,12 @@
         this.setValue(value);
     }
 
-
     @SuppressWarnings("unchecked")
     @Override
     public <T extends Op> T lookup(Class<T> clazz) {
         if (clazz == LIRGeneratorOp.class) {
             return (T) LIRGEN;
         }
-        if (clazz == CanonicalizerOp.class) {
-            return (T) CANON;
-        }
         return super.lookup(clazz);
     }
 
@@ -66,29 +64,8 @@
         out.print("fp conversion node ").print(value());
     }
 
-    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() {
 
-    private static final LIRGeneratorOp LIRGEN = new LIRGeneratorOp() {
         @Override
         public void generate(Node n, LIRGenerator generator) {
             FPConversionNode conv = (FPConversionNode) n;
@@ -98,4 +75,21 @@
             generator.lir().move(tmp, reg);
         }
     };
+
+    @Override
+    public Node canonical(NotifyReProcess reProcess) {
+        if (value instanceof Constant) {
+            CiKind fromKind = value.kind;
+            if (kind == CiKind.Int && fromKind == CiKind.Float) {
+                return Constant.forInt(Float.floatToRawIntBits(((Constant) value).asConstant().asFloat()), graph());
+            } else if (kind == CiKind.Long && fromKind == CiKind.Double) {
+                return Constant.forLong(Double.doubleToRawLongBits(((Constant) value).asConstant().asDouble()), graph());
+            } else if (kind == CiKind.Float && fromKind == CiKind.Int) {
+                return Constant.forFloat(Float.intBitsToFloat(((Constant) value).asConstant().asInt()), graph());
+            } else if (kind == CiKind.Double && fromKind == CiKind.Long) {
+                return Constant.forDouble(Double.longBitsToDouble(((Constant) value).asConstant().asLong()), graph());
+            }
+        }
+        return this;
+    }
 }