changeset 3131:5c696a58e692

Merge.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Fri, 01 Jul 2011 19:39:29 +0200
parents a4b0c3df7f80 (diff) c3573103764e (current diff)
children 20058d88555b
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java
diffstat 42 files changed, 858 insertions(+), 265 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java	Fri Jul 01 19:39:29 2011 +0200
@@ -73,9 +73,13 @@
             @Override
             public void verificationFailed(Node n, String message) {
                 GraalCompiler.this.fireCompilationEvent(new CompilationEvent(currentCompilation, "Verification Error on Node " + n.id(), currentCompilation.graph, true, false, true));
+                TTY.println(n.toString());
                 for (Node p : n.predecessors()) {
                     TTY.println("predecessor: " + p);
                 }
+                for (Node p : n.usages()) {
+                    TTY.println("usage: " + p);
+                }
                 assert false : "Verification of node " + n + " failed: " + message;
             }
         });
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Fri Jul 01 19:39:29 2011 +0200
@@ -41,6 +41,7 @@
 
     // inlining settings
     public static boolean Inline                             = true;
+    public static boolean Intrinsify                         = true;
     public static boolean CacheGraphs                        = ____;
     public static boolean InlineWithTypeCheck                = ____;
     public static int     MaximumInstructionCount            = 37000;
@@ -109,8 +110,10 @@
     public static boolean TraceInlining                      = ____;
     public static boolean TraceDeadCodeElimination           = ____;
     public static boolean TraceEscapeAnalysis                = ____;
+    public static boolean TraceCanonicalizer                 = ____;
     public static boolean TraceMemoryMaps                    = ____;
     public static boolean TraceReadElimination               = ____;
+    public static boolean TraceGVN                           = ____;
     public static int     TraceBytecodeParserLevel           = 0;
     public static boolean QuietBailout                       = ____;
 
@@ -150,6 +153,7 @@
     public static boolean CommentedAssembly                  = ____;
     public static boolean PrintLIRWithAssembly               = ____;
 
+    public static boolean OptGVN                             = true;
     public static boolean OptCanonicalizer                   = true;
     public static boolean OptLoops                           = true;
     public static boolean LoopPeeling                        = ____;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java	Fri Jul 01 19:39:29 2011 +0200
@@ -130,6 +130,8 @@
                             ((LIRBranch) instr).substitute(block, newTarget);
                         } else if (instr instanceof LIRTableSwitch) {
                             ((LIRTableSwitch) instr).substitute(block, newTarget);
+                        } else if (instr instanceof LIRXirInstruction) {
+                            ((LIRXirInstruction) instr).substitute(block, newTarget);
                         }
                     }
                 }
@@ -246,8 +248,8 @@
             for (LIRInstruction instr : instructions) {
                 if (instr instanceof LIRBranch) {
                     LIRBranch opBranch = (LIRBranch) instr;
-                    assert opBranch.block() == null || code.contains(opBranch.block()) : "missing successor branch from: " + block + " to: " + opBranch.block();
-                    assert opBranch.unorderedBlock() == null || code.contains(opBranch.unorderedBlock()) : "missing successor branch from: " + block + " to: " + opBranch.unorderedBlock();
+                    assert opBranch.block() == null || opBranch.block().blockID() == -1 || code.contains(opBranch.block()) : "missing successor branch from: " + block + " to: " + opBranch.block();
+                    assert opBranch.unorderedBlock() == null || opBranch.unorderedBlock().blockID() == -1 || code.contains(opBranch.unorderedBlock()) : "missing successor branch from: " + block + " to: " + opBranch.unorderedBlock();
                 }
             }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java	Fri Jul 01 19:39:29 2011 +0200
@@ -136,8 +136,12 @@
                 return;
             }
 
+            if (predInstructions.get(predInstructions.size() - 1).code == LIROpcode.Xir) {
+                return;
+            }
+
             assert pred.suxAt(0) == block : "invalid control flow";
-            assert predInstructions.get(predInstructions.size() - 1).code == LIROpcode.Branch : "block with successor must end with branch";
+            assert predInstructions.get(predInstructions.size() - 1).code == LIROpcode.Branch : "block with successor must end with branch" + predInstructions.get(predInstructions.size() - 1);
             assert predInstructions.get(predInstructions.size() - 1) instanceof LIRBranch : "branch must be LIROpBranch";
             assert ((LIRBranch) predInstructions.get(predInstructions.size() - 1)).cond() == Condition.TRUE : "block must end with unconditional branch";
 
@@ -191,6 +195,11 @@
 
         assert numSux == 2 : "method should not be called otherwise";
 
+        if (instructions.get(instructions.size() - 1).code == LIROpcode.Xir) {
+            // cannot optimize when last instruction is Xir.
+            return;
+        }
+
         assert instructions.get(instructions.size() - 1).code == LIROpcode.Branch : "block with successor must end with branch block=B" + block.blockID();
         assert instructions.get(instructions.size() - 1) instanceof LIRBranch : "branch must be LIROpBranch";
         assert ((LIRBranch) instructions.get(instructions.size() - 1)).cond() == Condition.TRUE : "block must end with unconditional branch";
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Fri Jul 01 19:39:29 2011 +0200
@@ -354,13 +354,6 @@
     }
 
     @Override
-    public void visitInstanceOf(InstanceOf x) {
-        XirArgument obj = toXirArgument(x.object());
-        XirSnippet snippet = xir.genInstanceOf(site(x), obj, toXirArgument(x.targetClassInstruction()), x.targetClass());
-        emitXir(snippet, x, stateFor(x), null, true);
-    }
-
-    @Override
     public void visitMonitorEnter(MonitorEnter x) {
         XirArgument obj = toXirArgument(x.object());
         XirArgument lockAddress = toXirArgument(x.lockAddress());
@@ -461,12 +454,8 @@
 
     @Override
     public void visitIf(If x) {
-        Condition cond = emitBooleanBranch(x.compare());
-        emitBranch(x.compare(), cond, getLIRBlock(x.trueSuccessor()), getLIRBlock(x.falseSuccessor()));
-        assert x.defaultSuccessor() == x.falseSuccessor() : "wrong destination above";
-        LIRBlock block = getLIRBlock(x.defaultSuccessor());
-        assert block != null : x;
-        lir.jump(block);
+        assert x.defaultSuccessor() == x.falseSuccessor() : "wrong destination";
+        emitBooleanBranch(x.compare(), getLIRBlock(x.trueSuccessor()),  getLIRBlock(x.falseSuccessor()), null);
     }
 
     public void emitBranch(BooleanNode n, Condition cond, LIRBlock trueSuccessor, LIRBlock falseSucc) {
@@ -484,18 +473,39 @@
         lir.branch(cond, trueSuccessor);
     }
 
-    public Condition emitBooleanBranch(BooleanNode node) {
+    public void emitBooleanBranch(Node node, LIRBlock trueSuccessor, LIRBlock falseSuccessor, LIRDebugInfo info) {
         if (node instanceof Compare) {
-            return emitCompare((Compare) node);
+            emitCompare((Compare) node, trueSuccessor, falseSuccessor);
+        } else if (node instanceof InstanceOf) {
+            emitInstanceOf((TypeCheck) node, trueSuccessor, falseSuccessor, info);
+        } else if (node instanceof NotInstanceOf) {
+            emitInstanceOf((TypeCheck) node, falseSuccessor, trueSuccessor, info);
         } else {
-            throw Util.unimplemented();
+            throw Util.unimplemented(node.toString());
         }
     }
 
-    public Condition emitCompare(Compare compare) {
+    private void emitInstanceOf(TypeCheck x, LIRBlock trueSuccessor, LIRBlock falseSuccessor, LIRDebugInfo info) {
+        XirArgument obj = toXirArgument(x.object());
+        XirSnippet snippet = xir.genInstanceOf(site(x), obj, toXirArgument(x.targetClassInstruction()), x.targetClass());
+        emitXir(snippet, x, info, null, false);
+        LIRXirInstruction instr = (LIRXirInstruction) lir.instructionsList().get(lir.instructionsList().size() - 1);
+        instr.setTrueSuccessor(trueSuccessor);
+        instr.setFalseSuccessor(falseSuccessor);
+    }
+
+    public void emitCompare(Compare compare, LIRBlock trueSuccessorBlock, LIRBlock falseSuccessorBlock) {
         CiKind kind = compare.x().kind;
 
         Condition cond = compare.condition();
+        boolean unorderedIsTrue = compare.unorderedIsTrue();
+
+        if (trueSuccessorBlock == null) {
+            cond = cond.negate();
+            unorderedIsTrue = !unorderedIsTrue;
+            trueSuccessorBlock = falseSuccessorBlock;
+            falseSuccessorBlock = null;
+        }
 
         LIRItem xitem = new LIRItem(compare.x(), this);
         LIRItem yitem = new LIRItem(compare.y(), this);
@@ -523,7 +533,20 @@
         CiValue left = xin.result();
         CiValue right = yin.result();
         lir.cmp(cond, left, right);
-        return cond;
+
+        if (compare.x().kind.isFloat() || compare.x().kind.isDouble()) {
+            LIRBlock unorderedSuccBlock = falseSuccessorBlock;
+            if (unorderedIsTrue) {
+                unorderedSuccBlock = trueSuccessorBlock;
+            }
+            lir.branch(cond, trueSuccessorBlock, unorderedSuccBlock);
+        } else {
+            lir.branch(cond, trueSuccessorBlock);
+        }
+
+        if (falseSuccessorBlock != null) {
+            lir.jump(falseSuccessorBlock);
+        }
     }
 
     @Override
@@ -743,12 +766,10 @@
             if (deoptimizationStubs == null) {
                 deoptimizationStubs = new ArrayList<DeoptimizationStub>();
             }
-
             DeoptimizationStub stub = new DeoptimizationStub(DeoptAction.InvalidateReprofile, state);
             deoptimizationStubs.add(stub);
 
-            Condition cond = emitBooleanBranch(comp);
-            lir.branch(cond.negate(), stub.label, stub.info);
+            emitBooleanBranch(comp, null, new LIRBlock(stub.label, stub.info), stub.info);
         }
     }
 
@@ -1117,7 +1138,7 @@
      * @param x an instruction that produces a result
      * @return the variable assigned to hold the result produced by {@code x}
      */
-    protected CiVariable createResultVariable(Value x) {
+    public CiVariable createResultVariable(Value x) {
         CiVariable operand = newVariable(x.kind);
         setResult(x, operand);
         return operand;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/CompilerGraph.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/CompilerGraph.java	Fri Jul 01 19:39:29 2011 +0200
@@ -25,6 +25,7 @@
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.ir.*;
 import com.oracle.max.graal.graph.*;
+import com.sun.cri.ri.*;
 
 
 public class CompilerGraph extends Graph {
@@ -56,6 +57,9 @@
         return unwindSingleton;
     }
 
+    public RiRuntime runtime() {
+        return compilation.runtime;
+    }
 
     public GraalCompilation getCompilation() {
         return compilation;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Fri Jul 01 19:39:29 2011 +0200
@@ -107,6 +107,12 @@
             new DeadCodeEliminationPhase().apply(graph);
         }
 
+        if (GraalOptions.OptGVN) {
+            new GlobalValueNumberingPhase().apply(graph);
+        }
+//
+//        new EscapeAnalysisPhase().apply(graph);
+
         if (GraalOptions.OptLoops) {
             new LoopPhase().apply(graph);
         }
@@ -114,6 +120,9 @@
         if (GraalOptions.Lower) {
             new LoweringPhase(compilation.runtime).apply(graph);
             new MemoryPhase().apply(graph);
+            if (GraalOptions.OptGVN) {
+                new GlobalValueNumberingPhase().apply(graph);
+            }
             new ReadEliminationPhase().apply(graph);
         }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/BooleanNode.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/BooleanNode.java	Fri Jul 01 19:39:29 2011 +0200
@@ -32,4 +32,8 @@
         super(kind, inputCount, successorCount, graph);
     }
 
+
+    public BooleanNode negate() {
+        throw new IllegalStateException();
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java	Fri Jul 01 19:39:29 2011 +0200
@@ -23,7 +23,6 @@
 package com.oracle.max.graal.compiler.ir;
 
 import com.oracle.max.graal.compiler.debug.*;
-import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
@@ -43,8 +42,8 @@
      * @param object the instruction producing the object
      * @param graph
      */
-    public CheckCast(RiType targetClass, Value targetClassInstruction, Value object, Graph graph) {
-        super(targetClass, targetClassInstruction, object, CiKind.Object, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+    public CheckCast(Constant targetClassInstruction, Value object, Graph graph) {
+        super(targetClassInstruction, object, CiKind.Object, INPUT_COUNT, SUCCESSOR_COUNT, graph);
     }
 
     /**
@@ -53,7 +52,7 @@
      */
     @Override
     public RiType declaredType() {
-        return targetClass;
+        return targetClass();
     }
 
     /**
@@ -62,7 +61,7 @@
      */
     @Override
     public RiType exactType() {
-        return targetClass.isResolved() ? targetClass.exactType() : null;
+        return targetClass().isResolved() ? targetClass().exactType() : null;
     }
 
     @Override
@@ -70,19 +69,15 @@
         v.visitCheckCast(this);
     }
 
-    @Override
-    public int valueNumber() {
-        return targetClass.isResolved() ? Util.hash1(Bytecodes.CHECKCAST, object()) : 0;
-    }
-
-    @Override
-    public boolean valueEqual(Node i) {
-        if (i instanceof CheckCast) {
-            CheckCast o = (CheckCast) i;
-            return targetClass == o.targetClass && object() == o.object();
-        }
-        return false;
-    }
+//    @Override
+//    public int valueNumber() {
+//        return targetClass().isResolved() ? Util.hash1(Bytecodes.CHECKCAST, object()) : 0;
+//    }
+//
+//    @Override
+//    public boolean valueEqual(Node i) {
+//        return i instanceof CheckCast;
+//    }
 
     @Override
     public void print(LogStream out) {
@@ -96,7 +91,7 @@
 
     @Override
     public Node copy(Graph into) {
-        CheckCast x = new CheckCast(targetClass, null, null, into);
+        CheckCast x = new CheckCast(null, null, into);
         return x;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java	Fri Jul 01 19:39:29 2011 +0200
@@ -22,7 +22,10 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.graph.*;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
@@ -138,10 +141,71 @@
         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 Node copy(Graph into) {
         Compare x = new Compare(null, condition, null, into);
         x.unorderedIsTrue = unorderedIsTrue;
         return x;
     }
+
+    @Override
+    public BooleanNode negate() {
+        return new Compare(x(), condition.negate(), y(), graph());
+    }
+
+    private static CanonicalizerOp CANONICALIZER = new CanonicalizerOp() {
+        @Override
+        public Node canonical(Node node) {
+            Compare compare = (Compare) node;
+            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());
+                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);
+                    }
+                }
+            } else if (compare.x().isConstant() && compare.y() instanceof MaterializeNode) {
+                return optimizeMaterialize(compare, compare.x().asConstant(), (MaterializeNode) compare.y());
+            } else if (compare.y().isConstant() && compare.x() instanceof MaterializeNode) {
+                return optimizeMaterialize(compare, compare.y().asConstant(), (MaterializeNode) compare.x());
+            }
+            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.value();
+                    if (isFalseCheck) {
+                        result = result.negate();
+                    }
+                    if (GraalOptions.TraceCanonicalizer) {
+                        TTY.println("Removed materialize replacing with " + result);
+                    }
+                    return result;
+                }
+            }
+            return compare;
+        }
+    };
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Constant.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Constant.java	Fri Jul 01 19:39:29 2011 +0200
@@ -33,7 +33,7 @@
  * The {@code Constant} instruction represents a constant such as an integer value,
  * long, float, object reference, address, etc.
  */
-public final class Constant extends FloatingNode {
+public final class Constant extends BooleanNode {
 
     private static final int INPUT_COUNT = 0;
     private static final int SUCCESSOR_COUNT = 0;
@@ -55,6 +55,14 @@
         v.visitConstant(this);
     }
 
+    @Override
+    public BooleanNode negate() {
+        if (kind != CiKind.Boolean) {
+            throw new IllegalStateException();
+        }
+        return Constant.forBoolean(!value.asBoolean(), graph());
+    }
+
     /**
      * Creates an instruction for a double constant.
      * @param d the double value for which to create the instruction
@@ -193,7 +201,6 @@
 
     @Override
     public Node copy(Graph into) {
-        Constant x = new Constant(value, into);
-        return x;
+        return new Constant(value, into);
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FixedGuard.java	Fri Jul 01 19:39:29 2011 +0200
@@ -22,7 +22,10 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.ir.Deoptimize.DeoptAction;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 
@@ -44,8 +47,9 @@
         inputs().set(super.inputCount() + INPUT_NODE, n);
     }
 
-    public FixedGuard(Graph graph) {
+    public FixedGuard(BooleanNode node, Graph graph) {
         super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        setNode(node);
     }
 
     @Override
@@ -60,6 +64,37 @@
 
     @Override
     public Node copy(Graph into) {
-        return new FixedGuard(into);
+        return new FixedGuard(null, into);
+    }
+
+    @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) {
+            FixedGuard fixedGuard = (FixedGuard) node;
+            if (fixedGuard.node() instanceof Constant) {
+                Constant c = (Constant) fixedGuard.node();
+                if (c.asConstant().asBoolean()) {
+                    if (GraalOptions.TraceCanonicalizer) {
+                        TTY.println("Removing redundant fixed guard " + fixedGuard);
+                    }
+                    return fixedGuard.next();
+                } else {
+                    if (GraalOptions.TraceCanonicalizer) {
+                        TTY.println("Replacing fixed guard " + fixedGuard + " with deoptimization node");
+                    }
+                    return new Deoptimize(DeoptAction.InvalidateRecompile, fixedGuard.graph());
+                }
+            }
+            return fixedGuard;
+        }
+    };
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java	Fri Jul 01 19:39:29 2011 +0200
@@ -22,7 +22,9 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 
@@ -64,11 +66,37 @@
 
     @Override
     public void print(LogStream out) {
-        out.print("clip node ").print(node());
+        out.print("guard node ").print(node());
     }
 
     @Override
     public Node copy(Graph into) {
         return new GuardNode(into);
     }
+
+    @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) {
+            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	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java	Fri Jul 01 19:39:29 2011 +0200
@@ -22,7 +22,9 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 
@@ -112,4 +114,35 @@
     public Node copy(Graph into) {
         return new If(null, into);
     }
+
+    @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) {
+            If ifNode = (If) node;
+            if (ifNode.compare() instanceof Constant) {
+                Constant c = (Constant) ifNode.compare();
+                if (c.asConstant().asBoolean()) {
+                    if (GraalOptions.TraceCanonicalizer) {
+                        TTY.println("Replacing if " + ifNode + " with true branch");
+                    }
+                    return ifNode.trueSuccessor();
+                } else {
+                    if (GraalOptions.TraceCanonicalizer) {
+                        TTY.println("Replacing if " + ifNode + " with false branch");
+                    }
+                    return ifNode.falseSuccessor();
+                }
+            }
+            return ifNode;
+        }
+    };
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java	Fri Jul 01 19:39:29 2011 +0200
@@ -27,7 +27,6 @@
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
-import com.sun.cri.ri.*;
 
 /**
  * The {@code InstanceOf} instruction represents an instanceof test.
@@ -43,13 +42,12 @@
      * @param object the instruction producing the object input to this instruction
      * @param graph
      */
-    public InstanceOf(RiType targetClass, Value targetClassInstruction, Value object, Graph graph) {
-        super(targetClass, targetClassInstruction, object, CiKind.Int, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+    public InstanceOf(Constant targetClassInstruction, Value object, Graph graph) {
+        super(targetClassInstruction, object, CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph);
     }
 
     @Override
     public void accept(ValueVisitor v) {
-        v.visitInstanceOf(this);
     }
 
     @Override
@@ -59,11 +57,7 @@
 
     @Override
     public boolean valueEqual(Node i) {
-        if (i instanceof InstanceOf) {
-            InstanceOf o = (InstanceOf) i;
-            return targetClass == o.targetClass && object() == o.object();
-        }
-        return false;
+        return i instanceof InstanceOf;
     }
 
     @Override
@@ -72,8 +66,12 @@
     }
 
     @Override
+    public BooleanNode negate() {
+        return new NotInstanceOf(targetClassInstruction(), object(), graph());
+    }
+
+    @Override
     public Node copy(Graph into) {
-        InstanceOf x = new InstanceOf(targetClass, null, null, into);
-        return x;
+        return new InstanceOf(null, null, into);
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java	Fri Jul 01 19:39:29 2011 +0200
@@ -83,11 +83,7 @@
 
     @Override
     public boolean valueEqual(Node i) {
-        if (i instanceof IsNonNull) {
-            IsNonNull o = (IsNonNull) i;
-            return object() == o.object();
-        }
-        return false;
+        return i instanceof IsNonNull;
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java	Fri Jul 01 19:39:29 2011 +0200
@@ -95,7 +95,7 @@
     public boolean valueEqual(Node i) {
         if (i instanceof IsType) {
             IsType o = (IsType) i;
-            return type == o.type() && object() == o.object();
+            return type == o.type();
         }
         return false;
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java	Fri Jul 01 19:39:29 2011 +0200
@@ -36,7 +36,12 @@
     private CiKind valueKind;
     private Object locationIdentity;
 
-    public LocationNode(Object identity, CiKind kind, int displacement, Graph graph) {
+    public static LocationNode create(Object identity, CiKind kind, int displacement, Graph graph) {
+        LocationNode result = new LocationNode(identity, kind, displacement, graph);
+        return graph.ideal(result);
+    }
+
+    private LocationNode(Object identity, CiKind kind, int displacement, Graph graph) {
         super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph);
         this.displacement = displacement;
         this.valueKind = kind;
@@ -73,7 +78,17 @@
         return locationIdentity;
     }
 
-    public boolean same(LocationNode location) {
-        return valueKind == location.valueKind && displacement == location.displacement;
+    @Override
+    public boolean valueEqual(Node i) {
+        if (i instanceof LocationNode) {
+            LocationNode locationNode = (LocationNode) i;
+            return locationNode.locationIdentity == locationIdentity && locationNode.displacement == displacement;
+        }
+        return false;
+    }
+
+    @Override
+    public int valueNumber() {
+        return locationIdentity.hashCode() + displacement;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopBegin.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopBegin.java	Fri Jul 01 19:39:29 2011 +0200
@@ -42,7 +42,6 @@
                 }
             }
         }
-        assert false : "LoopBegin should always have a LoopEnd";
         return null;
     }
 
@@ -63,8 +62,7 @@
 
     @Override
     public Node copy(Graph into) {
-        LoopBegin x = new LoopBegin(into);
-        return x;
+        return new LoopBegin(into);
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MaterializeNode.java	Fri Jul 01 19:39:29 2011 +0200
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.compiler.ir;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.gen.*;
+import com.oracle.max.graal.compiler.lir.*;
+import com.oracle.max.graal.graph.*;
+import com.sun.cri.ci.*;
+
+/**
+ * The {@code Convert} class represents a conversion between primitive types.
+ */
+public final class MaterializeNode extends FloatingNode {
+
+    private static final int INPUT_COUNT = 1;
+    private static final int INPUT_VALUE = 0;
+
+    private static final int SUCCESSOR_COUNT = 0;
+
+    @Override
+    protected int inputCount() {
+        return super.inputCount() + INPUT_COUNT;
+    }
+
+    @Override
+    protected int successorCount() {
+        return super.successorCount() + SUCCESSOR_COUNT;
+    }
+
+    /**
+     * The instruction which produces the input value to this instruction.
+     */
+     public BooleanNode value() {
+        return (BooleanNode) inputs().get(super.inputCount() + INPUT_VALUE);
+    }
+
+    public void setValue(BooleanNode n) {
+        inputs().set(super.inputCount() + INPUT_VALUE, n);
+    }
+
+    /**
+     * Constructs a new Convert instance.
+     * @param opcode the bytecode representing the operation
+     * @param value the instruction producing the input value
+     * @param kind the result type of this instruction
+     * @param graph
+     */
+    public MaterializeNode(BooleanNode value, Graph graph) {
+        super(CiKind.Int, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        setValue(value);
+    }
+
+    @Override
+    public void accept(ValueVisitor v) {
+    }
+
+    @Override
+    public boolean valueEqual(Node i) {
+        return (i instanceof MaterializeNode);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == LIRGenerator.LIRGeneratorOp.class) {
+            return (T) LIR_GENERATOR_OP;
+        }
+        return super.lookup(clazz);
+    }
+
+    public static final LIRGenerator.LIRGeneratorOp LIR_GENERATOR_OP = new LIRGenerator.LIRGeneratorOp() {
+
+        @Override
+        public void generate(Node n, LIRGenerator generator) {
+            LIRBlock trueSuccessor = new LIRBlock(new Label(), null);
+            generator.emitBooleanBranch(((MaterializeNode) n).value(), trueSuccessor, null, null);
+            CiValue result = generator.createResultVariable((Value) n);
+            LIRList lir = generator.lir();
+            lir.move(CiConstant.FALSE, result);
+            Label label = new Label();
+            lir.branch(Condition.TRUE, label);
+            lir.branchDestination(trueSuccessor.label);
+            lir.move(CiConstant.TRUE, result);
+            lir.branchDestination(label);
+        }
+    };
+
+    @Override
+    public void print(LogStream out) {
+        out.print("materialize(").print(value().toString()).print(')');
+    }
+
+    @Override
+    public Node copy(Graph into) {
+        return new MaterializeNode(null, into);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NotInstanceOf.java	Fri Jul 01 19:39:29 2011 +0200
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.compiler.ir;
+
+import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.graph.*;
+import com.sun.cri.bytecode.*;
+import com.sun.cri.ci.*;
+
+/**
+ * The {@code InstanceOf} instruction represents an instanceof test.
+ */
+public final class NotInstanceOf extends TypeCheck {
+
+    private static final int INPUT_COUNT = 0;
+    private static final int SUCCESSOR_COUNT = 0;
+
+    /**
+     * 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
+     */
+    public NotInstanceOf(Constant targetClassInstruction, Value object, Graph graph) {
+        super(targetClassInstruction, object, CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+    }
+
+    @Override
+    public void accept(ValueVisitor v) {
+    }
+
+    @Override
+    public int valueNumber() {
+        return Util.hash1(Bytecodes.INSTANCEOF, object());
+    }
+
+    @Override
+    public boolean valueEqual(Node i) {
+        return i instanceof NotInstanceOf;
+    }
+
+    @Override
+    public void print(LogStream out) {
+        out.print("instanceof(").print(object()).print(") ").print(CiUtil.toJavaName(targetClass()));
+    }
+
+    @Override
+    public BooleanNode negate() {
+        return new InstanceOf(targetClassInstruction(), object(), graph());
+    }
+
+    @Override
+    public Node copy(Graph into) {
+        return new NotInstanceOf(null, null, into);
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ReadNode.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ReadNode.java	Fri Jul 01 19:39:29 2011 +0200
@@ -47,6 +47,11 @@
     }
 
     @Override
+    public boolean valueEqual(Node i) {
+        return i instanceof ReadNode;
+    }
+
+    @Override
     public Node copy(Graph into) {
         return new ReadNode(super.kind, null, null, into);
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java	Fri Jul 01 19:39:29 2011 +0200
@@ -22,9 +22,13 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.compiler.graph.*;
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
+import com.sun.cri.ri.*;
 
 /**
  * This instruction is used to perform the finalizer registration at the end of the java.lang.Object constructor.
@@ -67,6 +71,57 @@
         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) {
+            RegisterFinalizer finalizer = (RegisterFinalizer) node;
+            Value object = finalizer.object();
+
+            RiType declaredType = object.declaredType();
+            RiType exactType = object.exactType();
+            if (exactType == null && declaredType != null) {
+                exactType = declaredType.exactType();
+            }
+
+            GraalCompilation compilation = ((CompilerGraph) node.graph()).getCompilation();
+            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 (compilation.recordNoFinalizableSubclassAssumption(declaredType)) {
+                        needsCheck = false;
+                    }
+                }
+            }
+
+            if (needsCheck) {
+                if (GraalOptions.TraceGVN) {
+                    TTY.println("Could not canonicalize finalizer " + object + " (declaredType=" + declaredType + ", exactType=" + exactType + ")");
+                }
+            } else {
+                if (GraalOptions.TraceGVN) {
+                    TTY.println("Canonicalized finalizer for object " + object);
+                }
+                return finalizer.next();
+            }
+
+            return finalizer;
+        }
+    };
+
     @Override
     public void print(LogStream out) {
         out.print("register finalizer ").print(object());
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TypeCheck.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TypeCheck.java	Fri Jul 01 19:39:29 2011 +0200
@@ -29,7 +29,7 @@
 /**
  * The {@code TypeCheck} instruction is the base class of casts and instanceof tests.
  */
-public abstract class TypeCheck extends FloatingNode {
+public abstract class TypeCheck extends BooleanNode {
 
     private static final int INPUT_COUNT = 2;
     private static final int INPUT_OBJECT = 0;
@@ -61,16 +61,23 @@
     /**
      * The instruction that loads the target class object that is used by this checkcast.
      */
-     public Value targetClassInstruction() {
-        return (Value) inputs().get(super.inputCount() + INPUT_TARGET_CLASS_INSTRUCTION);
+     public Constant targetClassInstruction() {
+        return (Constant) inputs().get(super.inputCount() + INPUT_TARGET_CLASS_INSTRUCTION);
+    }
+
+    private void setTargetClassInstruction(Constant n) {
+        inputs().set(super.inputCount() + INPUT_TARGET_CLASS_INSTRUCTION, n);
     }
 
-    public Value setTargetClassInstruction(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_TARGET_CLASS_INSTRUCTION, n);
+
+    /**
+     * Gets the target class, i.e. the class being cast to, or the class being tested against.
+     * @return the target class
+     */
+    public RiType targetClass() {
+        return (RiType) targetClassInstruction().asConstant().asObject();
     }
 
-    final RiType targetClass;
-
     /**
      * Creates a new TypeCheck instruction.
      * @param targetClass the class which is being casted to or checked against
@@ -80,27 +87,9 @@
      * @param successorCount
      * @param graph
      */
-    public TypeCheck(RiType targetClass, Value targetClassInstruction, Value object, CiKind kind, int inputCount, int successorCount, Graph graph) {
+    public TypeCheck(Constant targetClassInstruction, Value object, CiKind kind, int inputCount, int successorCount, Graph graph) {
         super(kind, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph);
-        this.targetClass = targetClass;
         setObject(object);
         setTargetClassInstruction(targetClassInstruction);
     }
-
-    /**
-     * Gets the target class, i.e. the class being cast to, or the class being tested against.
-     * @return the target class
-     */
-    public RiType targetClass() {
-        return targetClass;
-    }
-
-    /**
-     * Checks whether the target class of this instruction is loaded.
-     * @return {@code true} if the target class is loaded
-     */
-    public boolean isLoaded() {
-        return targetClass != null;
-    }
-
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java	Fri Jul 01 19:39:29 2011 +0200
@@ -44,7 +44,6 @@
     public abstract void visitAnchor(Anchor i);
     public abstract void visitIf(If i);
     public abstract void visitIfOp(Conditional i);
-    public abstract void visitInstanceOf(InstanceOf i);
     public abstract void visitInvoke(Invoke i);
     public abstract void visitLoadField(LoadField i);
     public abstract void visitLoadIndexed(LoadIndexed i);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRAssembler.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRAssembler.java	Fri Jul 01 19:39:29 2011 +0200
@@ -49,7 +49,6 @@
     public int registerRestoreEpilogueOffset = -1;
 
     protected final List<SlowPath> xirSlowPath;
-    protected final List<LIRBlock> branchTargetBlocks;
 
     private int lastDecodeStart;
 
@@ -70,7 +69,6 @@
         this.tasm = compilation.assembler();
         this.asm = tasm.asm;
         this.frameMap = compilation.frameMap();
-        this.branchTargetBlocks = new ArrayList<LIRBlock>();
         this.xirSlowPath = new ArrayList<SlowPath>();
     }
 
@@ -164,12 +162,12 @@
     }
 
     boolean checkNoUnboundLabels() {
-        for (int i = 0; i < branchTargetBlocks.size() - 1; i++) {
-            if (!branchTargetBlocks.get(i).label().isBound()) {
-                TTY.println(String.format("label of block B%d is not bound", branchTargetBlocks.get(i).blockID()));
-                assert false : "unbound label";
-            }
-        }
+//        for (int i = 0; i < branchTargetBlocks.size() - 1; i++) {
+//            if (!branchTargetBlocks.get(i).label().isBound()) {
+//                TTY.println(String.format("label of block B%d is not bound", branchTargetBlocks.get(i).blockID()));
+//                assert false : "unbound label";
+//            }
+//        }
 
         return true;
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBlock.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBlock.java	Fri Jul 01 19:39:29 2011 +0200
@@ -36,13 +36,14 @@
  */
 public final class LIRBlock {
 
-    public final Label label = new Label();
+    public final Label label;
     private LIRList lir;
     private final int blockID;
     private FrameState lastState;
     private List<Node> instructions = new ArrayList<Node>(4);
     private List<LIRBlock> predecessors = new ArrayList<LIRBlock>(4);
     private List<LIRBlock> successors = new ArrayList<LIRBlock>(4);
+    private LIRDebugInfo debugInfo;
 
     /**
      * Bit map specifying which {@linkplain OperandPool operands} are live upon entry to this block.
@@ -77,10 +78,24 @@
     private int lastLirInstructionID;
     public int blockEntryPco;
 
+    public LIRBlock(Label label, LIRDebugInfo debugInfo) {
+        this.label = label;
+        blockID = -1;
+        this.debugInfo = debugInfo;
+    }
+
+    public LIRDebugInfo debugInfo() {
+        return this.debugInfo;
+    }
+
     public LIRBlock(int blockID) {
         this.blockID = blockID;
+        label = new Label();
         loopIndex = -1;
         linearScanNumber = blockID;
+        instructions = new ArrayList<Node>(4);
+        predecessors = new ArrayList<LIRBlock>(4);
+        successors = new ArrayList<LIRBlock>(4);
     }
 
     public List<Node> getInstructions() {
@@ -261,7 +276,12 @@
         if (instructionsList.size() == 0) {
             return false;
         }
-        LIROpcode code = instructionsList.get(instructionsList.size() - 1).code;
+        LIRInstruction lirInstruction = instructionsList.get(instructionsList.size() - 1);
+        if (lirInstruction instanceof LIRXirInstruction) {
+            LIRXirInstruction lirXirInstruction = (LIRXirInstruction) lirInstruction;
+            return (lirXirInstruction.falseSuccessor() != null) && (lirXirInstruction.trueSuccessor() != null);
+        }
+        LIROpcode code = lirInstruction.code;
         return code == LIROpcode.Branch || code == LIROpcode.TableSwitch;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBranch.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBranch.java	Fri Jul 01 19:39:29 2011 +0200
@@ -73,7 +73,7 @@
      *
      */
     public LIRBranch(Condition cond, LIRBlock block) {
-        super(LIROpcode.Branch, CiValue.IllegalValue, null, false);
+        super(LIROpcode.Branch, CiValue.IllegalValue, block.debugInfo(), false);
         this.cond = cond;
         this.label = block.label();
         this.block = block;
@@ -81,7 +81,7 @@
     }
 
     public LIRBranch(Condition cond, LIRBlock block, LIRBlock ublock) {
-        super(LIROpcode.CondFloatBranch, CiValue.IllegalValue, null, false);
+        super(LIROpcode.CondFloatBranch, CiValue.IllegalValue, (block.debugInfo() != null ? block.debugInfo() : (ublock != null ? ublock.debugInfo() : null)), false);
         this.cond = cond;
         this.label = block.label();
         this.block = block;
@@ -116,11 +116,6 @@
         this.label = b.label();
     }
 
-    public void changeUblock(LIRBlock b) {
-        assert unorderedBlock != null : "must have old block";
-        this.unorderedBlock = b;
-    }
-
     public void negateCondition() {
         cond = cond.negate();
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRXirInstruction.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRXirInstruction.java	Fri Jul 01 19:39:29 2011 +0200
@@ -42,6 +42,8 @@
     public final int inputCount;
     public final List<CiValue> pointerSlots;
     public final LIRDebugInfo infoAfter;
+    private LIRBlock trueSuccessor;
+    private LIRBlock falseSuccessor;
 
     public LIRXirInstruction(XirSnippet snippet,
                              CiValue[] originalOperands,
@@ -71,6 +73,24 @@
         GraalMetrics.LIRXIRInstructions++;
     }
 
+
+    public void setFalseSuccessor(LIRBlock falseSuccessor) {
+        this.falseSuccessor = falseSuccessor;
+    }
+
+
+    public void setTrueSuccessor(LIRBlock trueSuccessor) {
+        this.trueSuccessor = trueSuccessor;
+    }
+
+    public LIRBlock falseSuccessor() {
+        return falseSuccessor;
+    }
+
+    public LIRBlock trueSuccessor() {
+        return trueSuccessor;
+    }
+
     public CiValue[] getOperands() {
         for (int i = 0; i < operandIndices.length; i++) {
             originalOperands[operandIndices[i]] = operand(i);
@@ -163,4 +183,15 @@
 
         return sb.toString();
     }
+
+
+    public void substitute(LIRBlock block, LIRBlock newTarget) {
+        if (trueSuccessor == block) {
+            trueSuccessor = newTarget;
+        }
+
+        if (falseSuccessor == block) {
+            falseSuccessor = newTarget;
+        }
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java	Fri Jul 01 19:39:29 2011 +0200
@@ -29,70 +29,37 @@
 import com.oracle.max.graal.compiler.gen.*;
 import com.oracle.max.graal.compiler.ir.*;
 import com.oracle.max.graal.graph.*;
-import com.sun.cri.ci.*;
 
 
 public class DeadCodeEliminationPhase extends Phase {
 
     private NodeFlood flood;
     private Graph graph;
-    private ArrayList<LoopBegin> brokenLoops;
 
     @Override
     protected void run(Graph graph) {
         this.graph = graph;
         this.flood = graph.createNodeFlood();
-        this.brokenLoops = new ArrayList<LoopBegin>();
-
-        // remove chained Merges
-        for (Merge merge : graph.getNodes(Merge.class)) {
-            if (merge.endCount() == 1 && merge.usages().size() == 0 && !(merge instanceof LoopBegin)) {
-                FixedNode next = merge.next();
-                EndNode endNode = merge.endAt(0);
-                merge.delete();
-                endNode.replaceAndDelete(next);
-            }
-        }
-        // remove if nodes with constant-value comparison
-        for (If ifNode : graph.getNodes(If.class)) {
-            BooleanNode bool = ifNode.compare();
-            if (bool instanceof Compare) {
-                Compare compare = (Compare) bool;
-                if (compare.x().isConstant() && compare.y().isConstant()) {
-                    CiConstant constX = compare.x().asConstant();
-                    CiConstant constY = compare.y().asConstant();
-                    Boolean result = compare.condition().foldCondition(constX, constY, GraalCompilation.compilation().runtime);
-                    if (result != null) {
-                        Node actualSuccessor = result ? ifNode.trueSuccessor() : ifNode.falseSuccessor();
-                        ifNode.replaceAndDelete(actualSuccessor);
-                    } else {
-                        TTY.println("if not removed %s %s %s (%s %s)", constX, compare.condition(), constY, constX.kind, constY.kind);
-                    }
-                }
-            }
-        }
-        // remove unnecessary FixedGuards
-        for (FixedGuard guard : graph.getNodes(FixedGuard.class)) {
-            if (guard.node() instanceof IsNonNull && ((IsNonNull) guard.node()).object() instanceof NewInstance) {
-                guard.replaceAndDelete(guard.next());
-            }
-        }
 
         flood.add(graph.start());
-
         iterateSuccessors();
         disconnectCFGNodes();
         iterateInputs();
         disconnectNodes();
         deleteNodes();
 
-        deleteBrokenLoops();
+        // remove chained Merges
+        for (Merge merge : graph.getNodes(Merge.class)) {
+            if (merge.endCount() == 1 && !(merge instanceof LoopBegin)) {
+                replacePhis(merge);
+                EndNode endNode = merge.endAt(0);
+                FixedNode next = merge.next();
+                merge.delete();
+                endNode.replaceAndDelete(next);
+            }
+        }
 
         new PhiSimplifier(graph);
-
-        if (GraalOptions.TraceDeadCodeElimination) {
-            TTY.println("dead code elimination finished");
-        }
     }
 
     private void iterateSuccessors() {
@@ -118,20 +85,28 @@
                         // We are a dead end node leading to a live merge.
                         merge.removeEnd(end);
                     }
+                } else if (node instanceof LoopEnd) {
+                    LoopBegin loop = ((LoopEnd) node).loopBegin();
+                    if (flood.isMarked(loop)) {
+                        if (GraalOptions.TraceDeadCodeElimination) {
+                            TTY.println("Building loop begin node back: " + loop);
+                        }
+                        ((LoopEnd) node).setLoopBegin(null);
+                        EndNode endNode = loop.endAt(0);
+                        assert endNode.predecessors().size() == 1 : endNode.predecessors().size();
+                        replacePhis(loop);
+                        endNode.replaceAndDelete(loop.next());
+                        loop.delete();
+                    }
                 }
             }
         }
     }
 
-    private void deleteBrokenLoops() {
-        for (LoopBegin loop : brokenLoops) {
-            assert loop.predecessors().size() == 1;
-            for (Node usage : new ArrayList<Node>(loop.usages())) {
-                assert usage instanceof Phi;
-                usage.replaceAndDelete(((Phi) usage).valueAt(0));
-            }
-
-            loop.replaceAndDelete(loop.next());
+    private void replacePhis(Merge merge) {
+        for (Node usage : new ArrayList<Node>(merge.usages())) {
+            assert usage instanceof Phi;
+            usage.replaceAndDelete(((Phi) usage).valueAt(0));
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GlobalValueNumberingPhase.java	Fri Jul 01 19:39:29 2011 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.compiler.phases;
+
+import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.compiler.debug.*;
+import com.oracle.max.graal.graph.*;
+
+/**
+ * Duplicates every node in the graph to test the implementation of the {@link com.oracle.max.graal.graph.Node#copy()} method in node subclasses.
+ */
+public class GlobalValueNumberingPhase extends Phase {
+
+    @Override
+    protected void run(Graph graph) {
+        NodeBitMap visited = graph.createNodeBitMap();
+        for (Node n : graph.getNodes()) {
+            apply(n, visited);
+        }
+    }
+
+    private void apply(Node n, NodeBitMap visited) {
+        if (n != null && !visited.isMarked(n)) {
+            visited.mark(n);
+            for (Node input : n.inputs()) {
+                apply(input, visited);
+            }
+            Node newNode = n.graph().ideal(n);
+            if (GraalOptions.TraceGVN && newNode != n) {
+                TTY.println("GVN applied and new node is " + newNode);
+            }
+        }
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Fri Jul 01 19:39:29 2011 +0200
@@ -725,8 +725,7 @@
 
     private void genThrow(int bci) {
         Value exception = frameState.apop();
-        FixedGuard node = new FixedGuard(graph);
-        node.setNode(new IsNonNull(exception, graph));
+        FixedGuard node = new FixedGuard(new IsNonNull(exception, graph), graph);
         append(node);
 
         FixedNode entry = handleException(exception, bci);
@@ -743,10 +742,12 @@
         int cpi = stream().readCPI();
         RiType type = constantPool.lookupType(cpi, CHECKCAST);
         boolean isInitialized = type.isResolved();
-        Value typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, isInitialized, cpi);
+        Constant typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, isInitialized, cpi);
         Value object = frameState.apop();
         if (typeInstruction != null) {
-            frameState.apush(append(new CheckCast(type, typeInstruction, object, graph)));
+//            append(new FixedGuard(new InstanceOf(typeInstruction, object, graph), graph));
+//            frameState.apush(object);
+            frameState.apush(new CheckCast(typeInstruction, object, graph));
         } else {
             frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
         }
@@ -756,10 +757,10 @@
         int cpi = stream().readCPI();
         RiType type = constantPool.lookupType(cpi, INSTANCEOF);
         boolean isInitialized = type.isResolved();
-        Value typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, isInitialized, cpi);
+        Constant typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, isInitialized, cpi);
         Value object = frameState.apop();
         if (typeInstruction != null) {
-            frameState.ipush(append(new InstanceOf(type, typeInstruction, object, graph)));
+            frameState.ipush(append(new MaterializeNode(new InstanceOf(typeInstruction, object, graph), graph)));
         } else {
             frameState.ipush(appendConstant(CiConstant.INT_0));
         }
@@ -874,7 +875,7 @@
         }
     }
 
-    private Value genTypeOrDeopt(RiType.Representation representation, RiType holder, boolean initialized, int cpi) {
+    private Constant genTypeOrDeopt(RiType.Representation representation, RiType holder, boolean initialized, int cpi) {
         if (initialized) {
             return appendConstant(holder.getEncoding(representation));
         } else {
@@ -993,42 +994,8 @@
     }
 
     private void callRegisterFinalizer() {
-        Value receiver = frameState.loadLocal(0);
-        RiType declaredType = receiver.declaredType();
-        RiType receiverType = declaredType;
-        RiType exactType = receiver.exactType();
-        if (exactType == null && declaredType != null) {
-            exactType = declaredType.exactType();
-        }
-        if (exactType == null && receiver instanceof Local && ((Local) receiver).index() == 0) {
-            // the exact type isn't known, but the receiver is parameter 0 => use holder
-            receiverType = method.holder();
-            exactType = receiverType.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 (compilation.recordNoFinalizableSubclassAssumption(declaredType)) {
-                    needsCheck = false;
-                }
-            }
-
-            if (receiverType != null && !receiverType.hasFinalizableSubclass()) {
-                if (compilation.recordNoFinalizableSubclassAssumption(receiverType)) {
-                    needsCheck = false;
-                }
-            }
-        }
-
-        if (needsCheck) {
-            // append a call to the finalizer registration
-            append(new RegisterFinalizer(frameState.loadLocal(0), graph));
-            GraalMetrics.InlinedFinalizerChecks++;
-        }
+        // append a call to the finalizer registration
+        append(new RegisterFinalizer(frameState.loadLocal(0), graph));
     }
 
     private void genReturn(Value x) {
@@ -1124,11 +1091,44 @@
         append(lookupSwitch);
     }
 
-    private Value appendConstant(CiConstant constant) {
-        return append(new Constant(constant, graph));
+    private Constant appendConstant(CiConstant constant) {
+        return new Constant(constant, graph);
     }
 
     private Value append(FixedNode fixed) {
+        if (fixed instanceof Deoptimize && lastInstr.predecessors().size() > 0) {
+            Node cur = lastInstr;
+            Node prev = cur;
+            while (cur != cur.graph().start() && !(cur instanceof ControlSplit)) {
+                assert cur.predecessors().size() == 1;
+                prev = cur;
+                cur = cur.predecessors().get(0);
+                if (cur.predecessors().size() == 0) {
+                    break;
+                }
+
+                if (cur instanceof ExceptionObject) {
+                    break;
+                }
+            }
+
+            if (cur instanceof If) {
+                If ifNode = (If) cur;
+                if (ifNode.falseSuccessor() == prev) {
+                    FixedNode successor = ifNode.trueSuccessor();
+                    BooleanNode condition = ifNode.compare();
+                    FixedGuard fixedGuard = new FixedGuard(condition, graph);
+                    fixedGuard.setNext(successor);
+                    ifNode.replaceAndDelete(fixedGuard);
+                    lastInstr = null;
+                    return fixed;
+                }
+            } else if (prev != cur) {
+                prev.replaceAtPredecessors(fixed);
+                lastInstr = null;
+                return fixed;
+            }
+        }
         lastInstr.setNext(fixed);
         lastInstr = null;
         return fixed;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Fri Jul 01 19:39:29 2011 +0200
@@ -128,6 +128,10 @@
         if (!checkInvokeConditions(invoke)) {
             return null;
         }
+        if (invoke.target.hasIntrinsicGraph() && GraalOptions.Intrinsify) {
+            // Always intrinsify.
+            return invoke.target;
+        }
         if (invoke.opcode() == Bytecodes.INVOKESPECIAL || invoke.target.canBeStaticallyBound()) {
             if (checkTargetConditions(invoke.target, iterations) && checkSizeConditions(invoke.target, invoke, profile, ratio)) {
                 return invoke.target;
@@ -173,8 +177,7 @@
                 concrete = profile.types[0].resolveMethodImpl(invoke.target);
                 if (concrete != null && checkTargetConditions(concrete, iterations) && checkSizeConditions(concrete, invoke, profile, ratio)) {
                     IsType isType = new IsType(invoke.receiver(), profile.types[0], compilation.graph);
-                    FixedGuard guard = new FixedGuard(graph);
-                    guard.setNode(isType);
+                    FixedGuard guard = new FixedGuard(isType, graph);
                     assert invoke.predecessors().size() == 1;
                     invoke.predecessors().get(0).successors().replace(invoke, guard);
                     guard.setNext(invoke);
@@ -327,21 +330,6 @@
             exceptionEdge = ((Placeholder) exceptionEdge).next();
         }
 
-        CompilerGraph graph;
-        Object stored = GraphBuilderPhase.cachedGraphs.get(method);
-        if (stored != null) {
-            if (GraalOptions.TraceInlining) {
-                TTY.println("Reusing graph for %s, locals: %d, stack: %d", methodName(method, invoke), method.maxLocals(), method.maxStackSize());
-            }
-            graph = (CompilerGraph) stored;
-        } else {
-            if (GraalOptions.TraceInlining) {
-                TTY.println("Building graph for %s, locals: %d, stack: %d", methodName(method, invoke), method.maxLocals(), method.maxStackSize());
-            }
-            graph = new CompilerGraph(null);
-            new GraphBuilderPhase(compilation, method, true, true).apply(graph);
-        }
-
         boolean withReceiver = !Modifier.isStatic(method.accessFlags());
 
         int argumentCount = method.signature().argumentCount(false);
@@ -356,6 +344,28 @@
             parameters[0] = invoke.argument(0);
         }
 
+        CompilerGraph graph = null;
+        if (GraalOptions.Intrinsify) {
+            graph = (CompilerGraph) method.intrinsicGraph(parameters);
+        }
+        if (graph != null) {
+            TTY.println("Using intrinsic graph");
+        } else {
+            graph = GraphBuilderPhase.cachedGraphs.get(method);
+        }
+
+        if (graph != null) {
+            if (GraalOptions.TraceInlining) {
+                TTY.println("Reusing graph for %s, locals: %d, stack: %d", methodName(method, invoke), method.maxLocals(), method.maxStackSize());
+            }
+        } else {
+            if (GraalOptions.TraceInlining) {
+                TTY.println("Building graph for %s, locals: %d, stack: %d", methodName(method, invoke), method.maxLocals(), method.maxStackSize());
+            }
+            graph = new CompilerGraph(null);
+            new GraphBuilderPhase(compilation, method, true, true).apply(graph);
+        }
+
         invoke.inputs().clearAll();
 
         HashMap<Node, Node> replacements = new HashMap<Node, Node>();
@@ -389,9 +399,7 @@
         assert invoke.predecessors().size() == 1 : "size: " + invoke.predecessors().size();
         FixedNodeWithNext pred;
         if (withReceiver) {
-            FixedGuard clipNode = new FixedGuard(compilation.graph);
-            clipNode.setNode(new IsNonNull(parameters[0], compilation.graph));
-            pred = clipNode;
+            pred = new FixedGuard(new IsNonNull(parameters[0], compilation.graph), compilation.graph);
         } else {
             pred = new Placeholder(compilation.graph);
         }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ReadEliminationPhase.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ReadEliminationPhase.java	Fri Jul 01 19:39:29 2011 +0200
@@ -38,7 +38,7 @@
             Node memoryInput = n.inputs().variablePart().get(0);
             if (memoryInput instanceof WriteNode) {
                 WriteNode other = (WriteNode) memoryInput;
-                if (other.object() == n.object() && other.location().same(n.location())) {
+                if (other.object() == n.object() && other.location() == n.location()) {
                     if (GraalOptions.TraceReadElimination) {
                         TTY.println("Eliminated memory read " + n + "and replaced with node " + other.value());
                     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java	Fri Jul 01 19:39:29 2011 +0200
@@ -439,22 +439,11 @@
 
     private boolean assertEmitBranch(LIRBranch op) {
         assert op.block() == null || op.block().label() == op.label() : "wrong label";
-        if (op.block() != null) {
-            branchTargetBlocks.add(op.block());
-        }
-        if (op.unorderedBlock() != null) {
-            branchTargetBlocks.add(op.unorderedBlock());
-        }
         return true;
     }
 
     private boolean assertEmitTableSwitch(LIRTableSwitch op) {
         assert op.defaultTarget != null;
-        branchTargetBlocks.add(op.defaultTarget);
-        for (LIRBlock target : op.targets) {
-            assert target != null;
-            branchTargetBlocks.add(target);
-        }
         return true;
     }
 
@@ -537,9 +526,14 @@
             masm.jmp(op.label());
         } else {
             ConditionFlag acond = ConditionFlag.zero;
+            Label unorderedLabel = null;
             if (op.code == LIROpcode.CondFloatBranch) {
-                assert op.unorderedBlock() != null : "must have unordered successor";
-                masm.jcc(ConditionFlag.parity, op.unorderedBlock().label());
+                if (op.unorderedBlock() == null) {
+                    unorderedLabel = new Label();
+                } else {
+                    unorderedLabel = op.unorderedBlock().label;
+                }
+                masm.jcc(ConditionFlag.parity, unorderedLabel);
                 // Checkstyle: off
                 switch (op.cond()) {
                     case EQ : acond = ConditionFlag.equal; break;
@@ -565,6 +559,9 @@
                 // Checkstyle: on
             }
             masm.jcc(acond, op.label());
+            if (unorderedLabel != null) {
+                masm.bind(unorderedLabel);
+            }
         }
     }
 
@@ -1597,11 +1594,34 @@
     protected void emitXir(LIRXirInstruction instruction) {
         XirSnippet snippet = instruction.snippet;
 
+
+        Label endLabel = null;
         Label[] labels = new Label[snippet.template.labels.length];
         for (int i = 0; i < labels.length; i++) {
             labels[i] = new Label();
+            if (snippet.template.labels[i].name == XirLabel.TrueSuccessor) {
+                if (instruction.trueSuccessor() == null) {
+                    assert endLabel == null;
+                    endLabel = new Label();
+                    labels[i] = endLabel;
+                } else {
+                    labels[i] = instruction.trueSuccessor().label;
+                }
+            } else if (snippet.template.labels[i].name == XirLabel.FalseSuccessor) {
+                if (instruction.falseSuccessor() == null) {
+                    assert endLabel == null;
+                    endLabel = new Label();
+                    labels[i] = endLabel;
+                } else {
+                    labels[i] = instruction.falseSuccessor().label;
+                }
+            }
         }
         emitXirInstructions(instruction, snippet.template.fastPath, labels, instruction.getOperands(), snippet.marks);
+        if (endLabel != null) {
+            masm.bind(endLabel);
+        }
+
         if (snippet.template.slowPath != null) {
             addSlowPath(new SlowPath(instruction, labels, snippet.marks));
         }
@@ -2090,6 +2110,9 @@
             default:
                 throw Util.shouldNotReachHere();
         }
+        if (code == 0) {
+            throw new RuntimeException();
+        }
         masm.movq(rscratch1, code);
         directCall(CiRuntimeCall.Deoptimize, stub.info);
         shouldNotReachHere();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Fri Jul 01 19:39:29 2011 +0200
@@ -475,11 +475,10 @@
         XirArgument obj = toXirArgument(x.exception());
         XirArgument clazz = toXirArgument(riType.getEncoding(Representation.ObjectHub));
         XirSnippet snippet = xir.genInstanceOf(site(x), obj, clazz, riType);
-        CiValue result = emitXir(snippet, x, stateFor(x), null, true);
+        emitXir(snippet, x, stateFor(x), null, false);
 
-        lir.cmp(Condition.EQ, result, CiConstant.TRUE);
-        lir.branch(Condition.EQ, getLIRBlock(x.catchSuccessor()));
-
+        LIRXirInstruction instr = (LIRXirInstruction) lir.instructionsList().get(lir.instructionsList().size() - 1);
+        instr.setTrueSuccessor(getLIRBlock(x.catchSuccessor()));
         lir.jump(getLIRBlock(x.otherSuccessor()));
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirAssembler.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirAssembler.java	Fri Jul 01 19:39:29 2011 +0200
@@ -200,7 +200,7 @@
             }
         }
         for (XirLabel label : labels) {
-            assert boundLabels.contains(label) : "label " + label.name + " is not bound!";
+            assert label.name == XirLabel.TrueSuccessor || label.name == XirLabel.FalseSuccessor || boundLabels.contains(label) : "label " + label.name + " is not bound!";
         }
         XirInstruction[] fp = fastPath.toArray(new XirInstruction[fastPath.size()]);
         XirInstruction[] sp = slowPath.size() > 0 ? slowPath.toArray(new XirInstruction[slowPath.size()]) : null;
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java	Fri Jul 01 19:39:29 2011 +0200
@@ -223,4 +223,14 @@
             }
         }
     }
+
+    @Override
+    public Graph intrinsicGraph(Node[] parameters) {
+        return null;
+    }
+
+    @Override
+    public boolean hasIntrinsicGraph() {
+        return false;
+    }
 }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodUnresolved.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodUnresolved.java	Fri Jul 01 19:39:29 2011 +0200
@@ -177,4 +177,14 @@
     public int branchProbability(int bci) {
         return -1;
     }
+
+    @Override
+    public Graph intrinsicGraph(Node[] parameters) {
+        return null;
+    }
+
+    @Override
+    public boolean hasIntrinsicGraph() {
+        return false;
+    }
 }
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java	Fri Jul 01 19:39:29 2011 +0200
@@ -251,7 +251,7 @@
             Graph graph = field.graph();
             int displacement = ((HotSpotField) field.field()).offset();
             assert field.kind != CiKind.Illegal;
-            ReadNode memoryRead = new ReadNode(field.field().kind().stackKind(), field.object(), new LocationNode(field.field(), field.field().kind(), displacement, graph), graph);
+            ReadNode memoryRead = new ReadNode(field.field().kind().stackKind(), field.object(), LocationNode.create(field.field(), field.field().kind(), displacement, graph), graph);
             memoryRead.setGuard((GuardNode) tool.createGuard(new IsNonNull(field.object(), graph)));
             memoryRead.setNext(field.next());
             field.replaceAndDelete(memoryRead);
@@ -262,7 +262,7 @@
             }
             Graph graph = field.graph();
             int displacement = ((HotSpotField) field.field()).offset();
-            WriteNode memoryWrite = new WriteNode(CiKind.Illegal, field.object(), field.value(), new LocationNode(field.field(), field.field().kind(), displacement, graph), graph);
+            WriteNode memoryWrite = new WriteNode(CiKind.Illegal, field.object(), field.value(), LocationNode.create(field.field(), field.field().kind(), displacement, graph), graph);
             memoryWrite.setGuard((GuardNode) tool.createGuard(new IsNonNull(field.object(), graph)));
             memoryWrite.setStateAfter(field.stateAfter());
             memoryWrite.setNext(field.next());
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotXirGenerator.java	Fri Jul 01 19:00:37 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotXirGenerator.java	Fri Jul 01 19:39:29 2011 +0200
@@ -636,32 +636,32 @@
 
         @Override
         protected XirTemplate create(CiXirAssembler asm, long flags) {
-            XirOperand result = asm.restart(CiKind.Boolean);
+            asm.restart(CiKind.Void);
             XirParameter object = asm.createInputParameter("object", CiKind.Object);
             final XirOperand hub;
             hub = asm.createConstantInputParameter("hub", CiKind.Object);
 
             XirOperand objHub = asm.createTemp("objHub", CiKind.Object);
 
-            XirLabel end = asm.createInlineLabel("end");
             XirLabel slowPath = asm.createOutOfLineLabel("slow path");
+            XirLabel trueSucc = asm.createInlineLabel(XirLabel.TrueSuccessor);
+            XirLabel falseSucc = asm.createInlineLabel(XirLabel.FalseSuccessor);
 
             if (is(NULL_CHECK, flags)) {
                 // null isn't "instanceof" anything
-                asm.mov(result, asm.b(false));
-                asm.jeq(end, object, asm.o(null));
+                asm.jeq(falseSucc, object, asm.o(null));
             }
 
             asm.pload(CiKind.Object, objHub, object, asm.i(config.hubOffset), false);
             // if we get an exact match: succeed immediately
-            asm.mov(result, asm.b(true));
-            asm.jneq(slowPath, objHub, hub);
-            asm.bindInline(end);
+            asm.jeq(trueSucc, objHub, hub);
+            asm.jmp(slowPath);
 
             // -- out of line -------------------------------------------------------
             asm.bindOutOfLine(slowPath);
-            checkSubtype(asm, result, objHub, hub);
-            asm.jmp(end);
+            checkSubtype(asm, objHub, objHub, hub);
+            asm.jeq(falseSucc, objHub, asm.o(null));
+            asm.jmp(trueSucc);
 
             return asm.finishTemplate("instanceof");
         }
--- a/runfop.sh	Fri Jul 01 19:00:37 2011 +0200
+++ b/runfop.sh	Fri Jul 01 19:39:29 2011 +0200
@@ -15,4 +15,4 @@
   echo "DACAPO is not defined. It must point to a Dacapo benchmark directory."
   exit 1;
 fi
-${JDK7}/bin/java -client -d64 -graal -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar -XX:-GraalBailoutIsFatal $* Harness --preserve -n 5 fop 
+${JDK7}/bin/java -client -d64 -graal -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar -XX:-GraalBailoutIsFatal $* Harness --preserve -n 20 fop