changeset 16204:c238f67f0745

Merge.
author Doug Simon <doug.simon@oracle.com>
date Wed, 25 Jun 2014 11:30:44 +0200
parents bf0e3ff4b2c4 (diff) 518a221dbbde (current diff)
children d078a3239653 ec17c588abf9
files
diffstat 29 files changed, 283 insertions(+), 110 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Wed Jun 25 11:30:44 2014 +0200
@@ -269,7 +269,7 @@
             }
             result.append("\n");
             for (Node node : schedule.getBlockToNodesMap().get(block)) {
-                if (node.recordsUsages()) {
+                if (node.isAlive() && node.recordsUsages()) {
                     if (!excludeVirtual || !(node instanceof VirtualObjectNode || node instanceof ProxyNode)) {
                         int id;
                         if (canonicalId.get(node) != null) {
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Wed Jun 25 11:30:44 2014 +0200
@@ -90,7 +90,7 @@
      * Determines if verification is enabled in the current method, regardless of the
      * {@linkplain Debug#currentScope() current debug scope}.
      *
-     * @see Debug#verify(Object, String)
+     * @see Debug#verify(Object, Object)
      */
     public static boolean isVerifyEnabledForMethod() {
         if (!ENABLED) {
@@ -107,7 +107,7 @@
      * Determines if verification is enabled in the {@linkplain Debug#currentScope() current debug
      * scope}.
      *
-     * @see Debug#verify(Object, String)
+     * @see Debug#verify(Object, Object)
      */
     public static boolean isVerifyEnabled() {
         return ENABLED && DebugScope.getInstance().isVerifyEnabled();
@@ -490,12 +490,14 @@
      * Calls all {@link DebugVerifyHandler}s in the current {@linkplain DebugScope#getConfig()
      * config} to perform verification on a given object.
      *
-     * @param object the object to be verified
-     * @param msg denoting context of verification
+     * @param object object to verify
+     * @param context object describing the context of verification
+     *
+     * @see DebugVerifyHandler#verify(Object, Object...)
      */
-    public static void verify(Object object, String msg) {
+    public static void verify(Object object, Object context) {
         if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) {
-            DebugScope.getInstance().verify(object, msg);
+            DebugScope.getInstance().verify(object, context);
         }
     }
 
@@ -503,45 +505,29 @@
      * Calls all {@link DebugVerifyHandler}s in the current {@linkplain DebugScope#getConfig()
      * config} to perform verification on a given object.
      *
-     * @param object the object to be verified
-     * @param format format string for message denoting context of verification
-     * @param arg argument to format string
+     * @param object object to verify
+     * @param context1 first object describing the context of verification
+     * @param context2 second object describing the context of verification
+     *
+     * @see DebugVerifyHandler#verify(Object, Object...)
      */
-    public static void verify(Object object, String format, Object arg) {
+    public static void verify(Object object, Object context1, Object context2) {
         if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) {
-            DebugScope.getInstance().verify(object, format, arg);
-        }
-    }
-
-    /**
-     * @see Debug#verify(Object, String, Object)
-     */
-    public static void verify(Object object, String format, Object arg1, Object arg2) {
-        if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) {
-            DebugScope.getInstance().verify(object, format, arg1, arg2);
+            DebugScope.getInstance().verify(object, context1, context2);
         }
     }
 
     /**
-     * @see Debug#verify(Object, String, Object)
-     */
-    public static void verify(Object object, String format, Object arg1, Object arg2, Object arg3) {
-        if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) {
-            DebugScope.getInstance().verify(object, format, arg1, arg2, arg3);
-        }
-    }
-
-    /**
-     * This override exists to catch cases when {@link #verify(Object, String, Object)} is called
-     * with one argument bound to a varargs method parameter. It will bind to this method instead of
-     * the single arg variant and produce a deprecation warning instead of silently wrapping the
+     * This override exists to catch cases when {@link #verify(Object, Object)} is called with one
+     * argument bound to a varargs method parameter. It will bind to this method instead of the
+     * single arg variant and produce a deprecation warning instead of silently wrapping the
      * Object[] inside of another Object[].
      */
     @Deprecated
-    public static void verify(Object object, String format, Object[] args) {
+    public static void verify(Object object, Object[] args) {
         assert false : "shouldn't use this";
         if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) {
-            DebugScope.getInstance().verify(object, format, args);
+            DebugScope.getInstance().verify(object, args);
         }
     }
 
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugVerifyHandler.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugVerifyHandler.java	Wed Jun 25 11:30:44 2014 +0200
@@ -29,6 +29,27 @@
 
     /**
      * Verifies that a given object satisfies some invariants.
+     *
+     * @param object object to verify
+     * @param context object(s) describing the context of verification
      */
-    void verify(Object object, String message);
+    void verify(Object object, Object... context);
+
+    /**
+     * Extracts the first object of a given type from a verification input object.
+     */
+    default <T> T extract(Class<T> type, Object input) {
+        if (type.isInstance(input)) {
+            return type.cast(input);
+        }
+        if (input instanceof Object[]) {
+            for (Object nestedContext : (Object[]) input) {
+                T object = extract(type, nestedContext);
+                if (object != null) {
+                    return object;
+                }
+            }
+        }
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java	Wed Jun 25 11:30:44 2014 +0200
@@ -218,15 +218,14 @@
     }
 
     /**
-     * @see Debug#verify(Object, String, Object)
+     * @see Debug#verify(Object, Object)
      */
-    public void verify(Object object, String formatString, Object... args) {
+    public void verify(Object object, Object... ctx) {
         if (isVerifyEnabled()) {
             DebugConfig config = getConfig();
             if (config != null) {
-                String message = String.format(formatString, args);
                 for (DebugVerifyHandler handler : config.verifyHandlers()) {
-                    handler.verify(object, message);
+                    handler.verify(object, ctx);
                 }
             }
         }
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java	Wed Jun 25 11:30:44 2014 +0200
@@ -67,9 +67,13 @@
             assert parameterTypes.length == args.length;
             for (int i = 0; i < args.length; i++) {
                 ParameterNode param = graph.getParameter(i);
-                Constant c = getSnippetReflection().forBoxed(parameterTypes[i].getKind(), args[i]);
-                ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph);
-                param.replaceAtUsages(replacement);
+                if (param != null) {
+                    Constant c = getSnippetReflection().forBoxed(parameterTypes[i].getKind(), args[i]);
+                    ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph);
+                    param.replaceAtUsages(replacement);
+                } else {
+                    // Parameter is not used and has been dead-code eliminated
+                }
             }
         }
         return graph;
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java	Wed Jun 25 11:30:44 2014 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.util.*;
 
 public class DerivedScaledInductionVariable extends InductionVariable {
 
@@ -119,4 +120,11 @@
     public long constantExtremum() {
         return base.constantExtremum() * scale.asConstant().asLong();
     }
+
+    @Override
+    public void deleteUnusedNodes() {
+        if (scale.isAlive() && scale.usages().isEmpty()) {
+            GraphUtil.killWithUnusedFloatingInputs(scale);
+        }
+    }
 }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariable.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariable.java	Wed Jun 25 11:30:44 2014 +0200
@@ -62,7 +62,7 @@
     public abstract Direction direction();
 
     /**
-     * Returns the value node that is described by this InductionVariable instance.
+     * Returns the value node that is described by this induction variable.
      */
     public abstract ValueNode valueNode();
 
@@ -104,4 +104,10 @@
      * induction variable at the loop exit.
      */
     public abstract ValueNode exitValueNode();
+
+    /**
+     * Deletes any nodes created within the scope of this object that have no usages.
+     */
+    public void deleteUnusedNodes() {
+    }
 }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java	Wed Jun 25 11:30:44 2014 +0200
@@ -121,4 +121,13 @@
         }
         return null;
     }
+
+    /**
+     * Deletes any nodes created within the scope of this object that have no usages.
+     */
+    public void deleteUnusedNodes() {
+        for (InductionVariable iv : ivs.values()) {
+            iv.deleteUnusedNodes();
+        }
+    }
 }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java	Wed Jun 25 11:30:44 2014 +0200
@@ -39,20 +39,20 @@
 
 public class LoopEx {
 
-    private final Loop<Block> lirLoop;
+    private final Loop<Block> loop;
     private LoopFragmentInside inside;
     private LoopFragmentWhole whole;
     private CountedLoopInfo counted; // TODO (gd) detect
     private LoopsData data;
     private InductionVariables ivs;
 
-    LoopEx(Loop<Block> lirLoop, LoopsData data) {
-        this.lirLoop = lirLoop;
+    LoopEx(Loop<Block> loop, LoopsData data) {
+        this.loop = loop;
         this.data = data;
     }
 
-    public Loop<Block> lirLoop() {
-        return lirLoop;
+    public Loop<Block> loop() {
+        return loop;
     }
 
     public LoopFragmentInside inside() {
@@ -91,7 +91,7 @@
     }
 
     public LoopBeginNode loopBegin() {
-        return (LoopBeginNode) lirLoop().getHeader().getBeginNode();
+        return (LoopBeginNode) loop().getHeader().getBeginNode();
     }
 
     public FixedNode predecessor() {
@@ -111,10 +111,10 @@
     }
 
     public LoopEx parent() {
-        if (lirLoop.getParent() == null) {
+        if (loop.getParent() == null) {
             return null;
         }
-        return data.loop(lirLoop.getParent());
+        return data.loop(loop.getParent());
     }
 
     public int size() {
@@ -123,7 +123,7 @@
 
     @Override
     public String toString() {
-        return (isCounted() ? "CountedLoop [" + counted() + "] " : "Loop ") + "(depth=" + lirLoop().getDepth() + ") " + loopBegin();
+        return (isCounted() ? "CountedLoop [" + counted() + "] " : "Loop ") + "(depth=" + loop().getDepth() + ") " + loopBegin();
     }
 
     private class InvariantPredicate implements NodePredicate {
@@ -237,9 +237,9 @@
             if (b == untilBlock) {
                 continue;
             }
-            if (lirLoop().getExits().contains(b)) {
+            if (loop().getExits().contains(b)) {
                 exits.add((LoopExitNode) b.getBeginNode());
-            } else if (lirLoop().getBlocks().contains(b)) {
+            } else if (loop().getBlocks().contains(b)) {
                 blocks.add(b.getBeginNode());
                 work.addAll(b.getDominated());
             }
@@ -253,4 +253,13 @@
         }
         return ivs;
     }
+
+    /**
+     * Deletes any nodes created within the scope of this object that have no usages.
+     */
+    public void deleteUnusedNodes() {
+        if (ivs != null) {
+            ivs.deleteUnusedNodes();
+        }
+    }
 }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java	Wed Jun 25 11:30:44 2014 +0200
@@ -302,7 +302,7 @@
     protected void mergeEarlyExits() {
         assert isDuplicate();
         StructuredGraph graph = graph();
-        for (BeginNode earlyExit : LoopFragment.toHirBlocks(original().loop().lirLoop().getExits())) {
+        for (BeginNode earlyExit : LoopFragment.toHirBlocks(original().loop().loop().getExits())) {
             LoopExitNode loopEarlyExit = (LoopExitNode) earlyExit;
             FixedNode next = loopEarlyExit.next();
             if (loopEarlyExit.isDeleted() || !this.original().contains(loopEarlyExit)) {
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java	Wed Jun 25 11:30:44 2014 +0200
@@ -56,8 +56,8 @@
     @Override
     public NodeBitMap nodes() {
         if (nodes == null) {
-            Loop<Block> lirLoop = loop().lirLoop();
-            nodes = LoopFragment.computeNodes(graph(), LoopFragment.toHirBlocks(lirLoop.getBlocks()), LoopFragment.toHirExits(lirLoop.getExits()));
+            Loop<Block> loop = loop().loop();
+            nodes = LoopFragment.computeNodes(graph(), LoopFragment.toHirBlocks(loop.getBlocks()), LoopFragment.toHirExits(loop.getExits()));
         }
         return nodes;
     }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java	Wed Jun 25 11:30:44 2014 +0200
@@ -34,7 +34,7 @@
 
 public class LoopsData {
 
-    private Map<Loop<Block>, LoopEx> lirLoopToEx = newIdentityMap();
+    private Map<Loop<Block>, LoopEx> loopToEx = newIdentityMap();
     private Map<LoopBeginNode, LoopEx> loopBeginToEx = newNodeIdentityMap();
     private ControlFlowGraph cfg;
 
@@ -45,15 +45,15 @@
             throw Debug.handle(e);
         }
 
-        for (Loop<Block> lirLoop : cfg.getLoops()) {
-            LoopEx ex = new LoopEx(lirLoop, this);
-            lirLoopToEx.put(lirLoop, ex);
+        for (Loop<Block> loop : cfg.getLoops()) {
+            LoopEx ex = new LoopEx(loop, this);
+            loopToEx.put(loop, ex);
             loopBeginToEx.put(ex.loopBegin(), ex);
         }
     }
 
-    public LoopEx loop(Loop<?> lirLoop) {
-        return lirLoopToEx.get(lirLoop);
+    public LoopEx loop(Loop<?> loop) {
+        return loopToEx.get(loop);
     }
 
     public LoopEx loop(LoopBeginNode loopBegin) {
@@ -61,16 +61,16 @@
     }
 
     public Collection<LoopEx> loops() {
-        return lirLoopToEx.values();
+        return loopToEx.values();
     }
 
-    public List<LoopEx> outterFirst() {
+    public List<LoopEx> outerFirst() {
         ArrayList<LoopEx> loops = new ArrayList<>(loops());
         Collections.sort(loops, new Comparator<LoopEx>() {
 
             @Override
             public int compare(LoopEx o1, LoopEx o2) {
-                return o1.lirLoop().getDepth() - o2.lirLoop().getDepth();
+                return o1.loop().getDepth() - o2.loop().getDepth();
             }
         });
         return loops;
@@ -82,7 +82,7 @@
 
             @Override
             public int compare(LoopEx o1, LoopEx o2) {
-                return o2.lirLoop().getDepth() - o1.lirLoop().getDepth();
+                return o2.loop().getDepth() - o1.loop().getDepth();
             }
         });
         return loops;
@@ -121,4 +121,13 @@
         }
         return match;
     }
+
+    /**
+     * Deletes any nodes created within the scope of this object that have no usages.
+     */
+    public void deleteUnusedNodes() {
+        for (LoopEx loop : loops()) {
+            loop.deleteUnusedNodes();
+        }
+    }
 }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopFullUnrollPhase.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopFullUnrollPhase.java	Wed Jun 25 11:30:44 2014 +0200
@@ -56,6 +56,7 @@
                         break;
                     }
                 }
+                dataCounted.deleteUnusedNodes();
             } while (peeled);
         }
     }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java	Wed Jun 25 11:30:44 2014 +0200
@@ -37,7 +37,7 @@
         if (context.getOptimisticOptimizations().useLoopLimitChecks()) {
             loops.detectedCountedLoops();
             for (LoopEx loop : loops.countedLoops()) {
-                if (loop.lirLoop().getChildren().isEmpty() && loop.counted().getStamp().getBits() <= 32) {
+                if (loop.loop().getChildren().isEmpty() && loop.counted().getStamp().getBits() <= 32) {
                     boolean hasSafepoint = false;
                     for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) {
                         hasSafepoint |= loopEnd.canSafepoint();
@@ -54,7 +54,7 @@
         for (LoopEx loop : loops.countedLoops()) {
             for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) {
                 Block b = loops.controlFlowGraph().blockFor(loopEnd);
-                blocks: while (b != loop.lirLoop().getHeader()) {
+                blocks: while (b != loop.loop().getHeader()) {
                     assert b != null;
                     for (FixedNode node : b.getNodes()) {
                         if (node instanceof Invoke || node instanceof ForeignCallNode) {
@@ -66,5 +66,6 @@
                 }
             }
         }
+        loops.deleteUnusedNodes();
     }
 }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformHighPhase.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformHighPhase.java	Wed Jun 25 11:30:44 2014 +0200
@@ -40,13 +40,14 @@
             if (LoopPeeling.getValue()) {
                 ToDoubleFunction<FixedNode> probabilities = new FixedNodeProbabilityCache();
                 LoopsData data = new LoopsData(graph);
-                for (LoopEx loop : data.outterFirst()) {
+                for (LoopEx loop : data.outerFirst()) {
                     if (LoopPolicies.shouldPeel(loop, probabilities)) {
                         Debug.log("Peeling %s", loop);
                         LoopTransformations.peel(loop);
                         Debug.dump(graph, "After peeling %s", loop);
                     }
                 }
+                data.deleteUnusedNodes();
             }
         }
     }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java	Wed Jun 25 11:30:44 2014 +0200
@@ -47,6 +47,7 @@
                 } catch (Throwable e) {
                     throw Debug.handle(e);
                 }
+                dataReassociate.deleteUnusedNodes();
             }
             if (LoopUnswitch.getValue()) {
                 boolean unswitched;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java	Wed Jun 25 11:30:44 2014 +0200
@@ -94,8 +94,10 @@
     public void lower(LoweringTool tool) {
         GuardingNode guard = tool.createGuard(next(), condition, reason, action, negated);
         ValueAnchorNode anchor = graph().add(new ValueAnchorNode((ValueNode) guard));
-        PiNode pi = graph().unique(new PiNode(object, stamp(), (ValueNode) guard));
-        replaceAtUsages(pi);
+        if (usages().isNotEmpty()) {
+            PiNode pi = graph().unique(new PiNode(object, stamp(), (ValueNode) guard));
+            replaceAtUsages(pi);
+        }
         graph().replaceFixedWithFixed(this, anchor);
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Wed Jun 25 11:30:44 2014 +0200
@@ -165,9 +165,9 @@
         } else {
             graph().replaceFixed(this, node);
         }
-        call.safeDelete();
+        GraphUtil.killWithUnusedFloatingInputs(call);
         if (stateAfter.usages().isEmpty()) {
-            stateAfter.safeDelete();
+            GraphUtil.killWithUnusedFloatingInputs(stateAfter);
         }
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Wed Jun 25 11:30:44 2014 +0200
@@ -189,9 +189,9 @@
         } else {
             graph().replaceSplit(this, node, next());
         }
-        call.safeDelete();
+        GraphUtil.killWithUnusedFloatingInputs(call);
         if (state.usages().isEmpty()) {
-            state.safeDelete();
+            GraphUtil.killWithUnusedFloatingInputs(state);
         }
     }
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java	Wed Jun 25 11:30:44 2014 +0200
@@ -33,7 +33,7 @@
     private static final DebugMetric metricNodesRemoved = Debug.metric("NodesRemoved");
 
     @Override
-    protected void run(StructuredGraph graph) {
+    public void run(StructuredGraph graph) {
         NodeFlood flood = graph.createNodeFlood();
 
         flood.add(graph.start());
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java	Wed Jun 25 11:30:44 2014 +0200
@@ -94,12 +94,15 @@
 
     public final void apply(final StructuredGraph graph, final C context, final boolean dumpGraph) {
         try (TimerCloseable a = timer.start(); Scope s = Debug.scope(getClass(), this); Closeable c = memUseTracker.start()) {
-            BasePhase.this.run(graph, context);
+            this.run(graph, context);
             executionCount.increment();
             inputNodesCount.add(graph.getNodeCount());
             if (dumpGraph && Debug.isDumpEnabled()) {
                 Debug.dump(graph, "After phase %s", getName());
             }
+            if (Debug.isVerifyEnabled()) {
+                Debug.verify(graph, this, "After phase " + getName());
+            }
             assert graph.verify();
         } catch (Throwable t) {
             throw Debug.handle(t);
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java	Wed Jun 25 11:30:44 2014 +0200
@@ -67,6 +67,9 @@
         if (verifyFilter == null && assertionsEnabled()) {
             verifyFilter = "";
         }
+        if (verifyFilter != null) {
+            verifyHandlers.add(new NoDeadCodeVerifyHandler());
+        }
         GraalDebugConfig debugConfig = new GraalDebugConfig(Log.getValue(), Meter.getValue(), TrackMemUse.getValue(), Time.getValue(), Dump.getValue(), verifyFilter, MethodFilter.getValue(), log,
                         dumpHandlers, verifyHandlers);
         Debug.setConfig(debugConfig);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/NoDeadCodeVerifyHandler.java	Wed Jun 25 11:30:44 2014 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014, 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.graal.printer;
+
+import static com.oracle.graal.printer.NoDeadCodeVerifyHandler.Options.*;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.options.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+
+/**
+ * Verifies that graphs have no dead code.
+ */
+public class NoDeadCodeVerifyHandler implements DebugVerifyHandler {
+
+    // The options below will be removed once all phases clean up their own dead code.
+
+    static class Options {
+        // @formatter:off
+        @Option(help = "Enable NoDeadCodeVerifyHandler")
+        public static final OptionValue<Boolean> NDCV = new OptionValue<>(false);
+        @Option(help = "Issues caught by NoDeadCodeVerifyHandler raise an error")
+        public static final OptionValue<Boolean> NDCVFatal = new OptionValue<>(false);
+        // @formatter:on
+    }
+
+    private static final Map<Class<?>, Boolean> discovered = new ConcurrentHashMap<>();
+
+    public void verify(Object object, Object... context) {
+        if (NDCV.getValue()) {
+            StructuredGraph graph = extract(StructuredGraph.class, object);
+            BasePhase<?> phase = extract(BasePhase.class, context);
+            if (graph != null) {
+                List<Node> before = graph.getNodes().snapshot();
+                new DeadCodeEliminationPhase().run(graph);
+                List<Node> after = graph.getNodes().snapshot();
+                assert after.size() <= before.size();
+                if (before.size() != after.size()) {
+                    before.removeAll(after);
+                    if (NDCVFatal.getValue() || discovered.put(phase.getClass(), Boolean.TRUE) == null) {
+                        String message = extract(String.class, context);
+                        String prefix = message == null ? "" : message + ": ";
+                        String phaseClass = phase == null ? null : phase.getClass().getName();
+                        GraalInternalError error = new GraalInternalError("%sfound dead nodes in %s (phase class=%s): %s", prefix, graph, phaseClass, before);
+                        if (NDCVFatal.getValue()) {
+                            throw error;
+                        }
+                        error.printStackTrace(System.out);
+                    }
+                }
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java	Wed Jun 25 11:30:44 2014 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.replacements;
 
+import static com.oracle.graal.api.code.BytecodeFrame.*;
+
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
@@ -129,15 +131,15 @@
                 FrameState frameState = stateSplit.stateAfter();
                 if (frameState != null) {
                     if (stateSplit.hasSideEffect()) {
-                        stateSplit.setStateAfter(createInvalidFrameState(node));
+                        setStateAfter(node.graph(), stateSplit, INVALID_FRAMESTATE_BCI, false);
                         state = state.addSideEffect(stateSplit);
                     } else if (currentState.invalid) {
-                        stateSplit.setStateAfter(createInvalidFrameState(node));
+                        setStateAfter(node.graph(), stateSplit, INVALID_FRAMESTATE_BCI, false);
                     } else {
                         stateSplit.setStateAfter(null);
-                    }
-                    if (frameState.usages().isEmpty()) {
-                        GraphUtil.killWithUnusedFloatingInputs(frameState);
+                        if (frameState.usages().isEmpty()) {
+                            GraphUtil.killWithUnusedFloatingInputs(frameState);
+                        }
                     }
                 }
             }
@@ -176,18 +178,14 @@
             for (Node returnSideEffect : returnSideEffects) {
                 if (!unwindSideEffects.contains(returnSideEffect) && !maskedSideEffects.contains(returnSideEffect)) {
                     StateSplit split = (StateSplit) returnSideEffect;
-                    if (split.stateAfter() != null) {
-                        split.setStateAfter(graph.add(new FrameState(BytecodeFrame.AFTER_BCI)));
-                    }
+                    setStateAfter(graph, split, AFTER_BCI, true);
                 }
             }
 
             for (Node unwindSideEffect : unwindSideEffects) {
                 if (!returnSideEffects.contains(unwindSideEffect) && !maskedSideEffects.contains(unwindSideEffect)) {
                     StateSplit split = (StateSplit) unwindSideEffect;
-                    if (split.stateAfter() != null) {
-                        split.setStateAfter(graph.add(new FrameState(BytecodeFrame.AFTER_EXCEPTION_BCI)));
-                    }
+                    setStateAfter(graph, split, AFTER_EXCEPTION_BCI, true);
                 }
             }
         }
@@ -207,15 +205,34 @@
             }
 
             if (isNowInvalid) {
-                loop.setStateAfter(createInvalidFrameState(loop));
+                setStateAfter(loop.graph(), loop, INVALID_FRAMESTATE_BCI, false);
             }
 
             IterationState endState = IterationState.merge(loop, info.endStates.values(), isNowInvalid);
             return ReentrantNodeIterator.processLoop(this, loop, endState).exitStates;
         }
 
-        private static FrameState createInvalidFrameState(FixedNode node) {
-            return node.graph().add(new FrameState(BytecodeFrame.INVALID_FRAMESTATE_BCI));
+        /**
+         * Creates and sets a special frame state for a node. If the existing frame state is
+         * non-null and has no other usages, it is deleted via
+         * {@link GraphUtil#killWithUnusedFloatingInputs(Node)}.
+         *
+         * @param graph the graph context
+         * @param node the node whose frame state is updated
+         * @param bci {@link BytecodeFrame#AFTER_BCI}, {@link BytecodeFrame#AFTER_EXCEPTION_BCI} or
+         *            {@link BytecodeFrame#INVALID_FRAMESTATE_BCI}
+         * @param replaceOnly only perform the update if the node currently has a non-null frame
+         *            state
+         */
+        private static void setStateAfter(StructuredGraph graph, StateSplit node, int bci, boolean replaceOnly) {
+            assert bci == AFTER_BCI || bci == AFTER_EXCEPTION_BCI || bci == INVALID_FRAMESTATE_BCI;
+            FrameState currentStateAfter = node.stateAfter();
+            if (currentStateAfter != null || !replaceOnly) {
+                node.setStateAfter(graph.add(new FrameState(bci)));
+                if (currentStateAfter != null && currentStateAfter.usages().isEmpty()) {
+                    GraphUtil.killWithUnusedFloatingInputs(currentStateAfter);
+                }
+            }
         }
     }
 }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed Jun 25 11:30:44 2014 +0200
@@ -618,6 +618,7 @@
                     Mark mark = snippetCopy.getMark();
                     LoopTransformations.fullUnroll(loop, phaseContext, new CanonicalizerPhase(true));
                     new CanonicalizerPhase(true).applyIncremental(snippetCopy, phaseContext, mark);
+                    loop.deleteUnusedNodes();
                 }
                 GraphUtil.removeFixedWithUnusedInputs(explodeLoop);
                 exploded = true;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java	Wed Jun 25 11:30:44 2014 +0200
@@ -35,18 +35,18 @@
 
     @Input private ValueNode index;
 
-    private final ParameterNode[] parameters;
+    @Input private final NodeInputList<ParameterNode> parameters;
 
     public LoadSnippetVarargParameterNode(ParameterNode[] locals, ValueNode index, Stamp stamp) {
         super(stamp);
         this.index = index;
-        this.parameters = locals;
+        this.parameters = new NodeInputList<>(this, locals);
     }
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (index.isConstant()) {
-            return parameters[index.asConstant().asInt()];
+            return parameters.get(index.asConstant().asInt());
         }
         return this;
     }
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Wed Jun 25 11:30:44 2014 +0200
@@ -120,6 +120,7 @@
                             }
                         }
                     }
+                    loopsData.deleteUnusedNodes();
                 } while (unrolled);
             }
 
@@ -138,7 +139,7 @@
 
             @Override
             public int compare(LoopEx o1, LoopEx o2) {
-                return o2.lirLoop().getDepth() - o1.lirLoop().getDepth();
+                return o2.loop().getDepth() - o1.loop().getDepth();
             }
         });
         return sortedLoops;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Tue Jun 24 15:14:35 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed Jun 25 11:30:44 2014 +0200
@@ -280,6 +280,7 @@
                             break;
                         }
                     }
+                    loopsData.deleteUnusedNodes();
                 } while (unrolled);
             } catch (Throwable e) {
                 throw Debug.handle(e);
@@ -297,7 +298,7 @@
 
             @Override
             public int compare(LoopEx o1, LoopEx o2) {
-                return o2.lirLoop().getDepth() - o1.lirLoop().getDepth();
+                return o2.loop().getDepth() - o1.loop().getDepth();
             }
         });
         return sortedLoops;
--- a/mx/mx_graal.py	Tue Jun 24 15:14:35 2014 -0700
+++ b/mx/mx_graal.py	Wed Jun 25 11:30:44 2014 +0200
@@ -505,14 +505,23 @@
             jreLibDir = join(jdks, e, 'jre', 'lib')
             if exists(jreLibDir):
                 def install(srcJar, dstDir):
-                    # do a copy and then a move to get atomic updating (on Unix)
                     name = os.path.basename(srcJar)
-                    fd, tmp = tempfile.mkstemp(suffix='', prefix=name, dir=dstDir)
-                    shutil.copyfile(srcJar, tmp)
-                    os.close(fd)
                     dstJar = join(dstDir, name)
-                    shutil.move(tmp, dstJar)
-                    os.chmod(dstJar, JDK_UNIX_PERMISSIONS)
+                    if mx.get_env('SYMLINK_GRAAL_JAR', None) == 'true':
+                        # Using symlinks is much faster than copying but may
+                        # cause issues if graal.jar is being updated while
+                        # the VM is running.
+                        if not os.path.islink(dstJar) or not os.path.realpath(dstJar) == srcJar:
+                            if exists(dstJar):
+                                os.remove(dstJar)
+                            os.symlink(srcJar, dstJar)
+                    else:
+                        # do a copy and then a move to get atomic updating (on Unix)
+                        fd, tmp = tempfile.mkstemp(suffix='', prefix=name, dir=dstDir)
+                        shutil.copyfile(srcJar, tmp)
+                        os.close(fd)
+                        shutil.move(tmp, dstJar)
+                        os.chmod(dstJar, JDK_UNIX_PERMISSIONS)
 
                 install(graalJar, jreLibDir)
                 if graalDist.sourcesPath:
@@ -1197,34 +1206,34 @@
 
     with VM('graal', 'fastdebug'):
         t = Task('BootstrapWithSystemAssertions:fastdebug')
-        vm(['-esa', '-XX:+UseGraalCompilationQueue', '-XX:-TieredCompilation', '-version'])
+        vm(['-esa', '-XX:-TieredCompilation', '-version'])
         tasks.append(t.stop())
 
     with VM('graal', 'fastdebug'):
         t = Task('BootstrapWithSystemAssertionsNoCoop:fastdebug')
-        vm(['-esa', '-XX:+UseGraalCompilationQueue', '-XX:-TieredCompilation', '-XX:-UseCompressedOops', '-version'])
+        vm(['-esa', '-XX:-TieredCompilation', '-XX:-UseCompressedOops', '-version'])
         tasks.append(t.stop())
 
     with VM('graal', 'product'):
         t = Task('BootstrapWithGCVerification:product')
         out = mx.DuplicateSuppressingStream(['VerifyAfterGC:', 'VerifyBeforeGC:']).write
-        vm(['-XX:+UseGraalCompilationQueue', '-XX:-TieredCompilation', '-XX:+UnlockDiagnosticVMOptions', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'], out=out)
+        vm(['-XX:-TieredCompilation', '-XX:+UnlockDiagnosticVMOptions', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'], out=out)
         tasks.append(t.stop())
 
     with VM('graal', 'product'):
         t = Task('BootstrapWithG1GCVerification:product')
         out = mx.DuplicateSuppressingStream(['VerifyAfterGC:', 'VerifyBeforeGC:']).write
-        vm(['-XX:+UseGraalCompilationQueue', '-XX:-TieredCompilation', '-XX:+UnlockDiagnosticVMOptions', '-XX:-UseSerialGC', '-XX:+UseG1GC', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'], out=out)
+        vm(['-XX:-TieredCompilation', '-XX:+UnlockDiagnosticVMOptions', '-XX:-UseSerialGC', '-XX:+UseG1GC', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'], out=out)
         tasks.append(t.stop())
 
     with VM('graal', 'product'):
         t = Task('BootstrapWithRegisterPressure:product')
-        vm(['-XX:+UseGraalCompilationQueue', '-XX:-TieredCompilation', '-G:RegisterPressure=rbx,r11,r10,r14,xmm3,xmm11,xmm14', '-esa', '-version'])
+        vm(['-XX:-TieredCompilation', '-G:RegisterPressure=rbx,r11,r10,r14,xmm3,xmm11,xmm14', '-esa', '-version'])
         tasks.append(t.stop())
 
     with VM('graal', 'product'):
         t = Task('BootstrapWithImmutableCode:product')
-        vm(['-XX:+UseGraalCompilationQueue', '-XX:-TieredCompilation', '-G:+ImmutableCode', '-G:+VerifyPhases', '-esa', '-version'])
+        vm(['-XX:-TieredCompilation', '-G:+ImmutableCode', '-G:+VerifyPhases', '-esa', '-version'])
         tasks.append(t.stop())
 
     with VM('server', 'product'):  # hosted mode