# HG changeset patch # User Doug Simon # Date 1403688644 -7200 # Node ID c238f67f074585bf45edfed58ee05e46b9271d44 # Parent bf0e3ff4b2c426d82ed5a864b7f0f4db1eff2fab# Parent 518a221dbbdef04dd08016a8094b2219a82bdd94 Merge. diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- 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) { diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java --- 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); } } diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugVerifyHandler.java --- 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 extract(Class 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; + } } diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java --- 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); } } } diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java --- 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; diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java --- 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); + } + } } diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariable.java --- 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() { + } } diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java --- 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(); + } + } } diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java --- 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 lirLoop; + private final Loop loop; private LoopFragmentInside inside; private LoopFragmentWhole whole; private CountedLoopInfo counted; // TODO (gd) detect private LoopsData data; private InductionVariables ivs; - LoopEx(Loop lirLoop, LoopsData data) { - this.lirLoop = lirLoop; + LoopEx(Loop loop, LoopsData data) { + this.loop = loop; this.data = data; } - public Loop lirLoop() { - return lirLoop; + public Loop 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(); + } + } } diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java --- 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)) { diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java --- 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 lirLoop = loop().lirLoop(); - nodes = LoopFragment.computeNodes(graph(), LoopFragment.toHirBlocks(lirLoop.getBlocks()), LoopFragment.toHirExits(lirLoop.getExits())); + Loop loop = loop().loop(); + nodes = LoopFragment.computeNodes(graph(), LoopFragment.toHirBlocks(loop.getBlocks()), LoopFragment.toHirExits(loop.getExits())); } return nodes; } diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java --- 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, LoopEx> lirLoopToEx = newIdentityMap(); + private Map, LoopEx> loopToEx = newIdentityMap(); private Map loopBeginToEx = newNodeIdentityMap(); private ControlFlowGraph cfg; @@ -45,15 +45,15 @@ throw Debug.handle(e); } - for (Loop lirLoop : cfg.getLoops()) { - LoopEx ex = new LoopEx(lirLoop, this); - lirLoopToEx.put(lirLoop, ex); + for (Loop 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 loops() { - return lirLoopToEx.values(); + return loopToEx.values(); } - public List outterFirst() { + public List outerFirst() { ArrayList loops = new ArrayList<>(loops()); Collections.sort(loops, new Comparator() { @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(); + } + } } diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopFullUnrollPhase.java --- 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); } } diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java --- 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(); } } diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformHighPhase.java --- 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 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(); } } } diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java --- 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; diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java --- 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); } diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java --- 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); } } diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java --- 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); } } diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java --- 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()); diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java --- 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); diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java --- 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); diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/NoDeadCodeVerifyHandler.java --- /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 NDCV = new OptionValue<>(false); + @Option(help = "Issues caught by NoDeadCodeVerifyHandler raise an error") + public static final OptionValue NDCVFatal = new OptionValue<>(false); + // @formatter:on + } + + private static final Map, 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 before = graph.getNodes().snapshot(); + new DeadCodeEliminationPhase().run(graph); + List 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); + } + } + } + } + } +} diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java --- 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); + } + } } } } diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- 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; diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java --- 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 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; } diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java --- 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; diff -r 518a221dbbde -r c238f67f0745 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- 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; diff -r 518a221dbbde -r c238f67f0745 mx/mx_graal.py --- 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