# HG changeset patch # User Christian Haeubl # Date 1371230012 -7200 # Node ID e90e48dae0ab31a1f7a8b794eb3494525129b8d7 # Parent a323a9e20f9dde07920764a0088a39e43e0c9570# Parent 10fbede11db00651a836952350cc31a1496ac5c4 Merge. diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java Fri Jun 14 19:13:32 2013 +0200 @@ -53,7 +53,7 @@ * @return {@code true} if the value is a power of two; {@code false} otherwise */ public static boolean isPowerOf2(int val) { - return val != 0 && (val & val - 1) == 0; + return val > 0 && (val & val - 1) == 0; } /** @@ -63,7 +63,7 @@ * @return {@code true} if the value is a power of two; {@code false} otherwise */ public static boolean isPowerOf2(long val) { - return val != 0 && (val & val - 1) == 0; + return val > 0 && (val & val - 1) == 0; } /** @@ -74,7 +74,7 @@ * @return the log base 2 of the value */ public static int log2(int val) { - assert val > 0 && isPowerOf2(val); + assert val > 0; return 31 - Integer.numberOfLeadingZeros(val); } @@ -86,7 +86,7 @@ * @return the log base 2 of the value */ public static int log2(long val) { - assert val > 0 && isPowerOf2(val); + assert val > 0; return 63 - Long.numberOfLeadingZeros(val); } diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Fri Jun 14 19:13:32 2013 +0200 @@ -310,7 +310,6 @@ HighTierContext context = new HighTierContext(runtime(), assumptions, replacements); new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context); - new CullFrameStatesPhase().apply(graph); } private void compareGraphs(final String snippet, final String referenceSnippet) { @@ -335,7 +334,6 @@ canonicalizer.apply(graph, context); new PartialEscapePhase(false, canonicalizer).apply(graph, context); - new CullFrameStatesPhase().apply(graph); new DeadCodeEliminationPhase().apply(graph); canonicalizer.apply(graph, context); diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java Fri Jun 14 19:13:32 2013 +0200 @@ -96,6 +96,17 @@ testZeroReturn("divStamp2"); } + public static int distinctMask(int a, int b) { + int x = a & 0xaaaa; + int y = (b & 0x5555) | 0x1; + return x == y ? 1 : 0; + } + + @Test + public void testDistinctMask() { + testZeroReturn("distinctMask"); + } + private void testZeroReturn(String methodName) { StructuredGraph graph = parse(methodName); new CanonicalizerPhase.Instance(runtime(), new Assumptions(false), true).apply(graph); diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Fri Jun 14 19:13:32 2013 +0200 @@ -168,7 +168,9 @@ canonicalizer.apply(graph, context); new PartialEscapePhase(false, canonicalizer).apply(graph, context); - new CullFrameStatesPhase().apply(graph); + for (MergeNode merge : graph.getNodes(MergeNode.class)) { + merge.setStateAfter(null); + } new DeadCodeEliminationPhase().apply(graph); canonicalizer.apply(graph, context); return graph; diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Fri Jun 14 19:13:32 2013 +0200 @@ -60,10 +60,6 @@ } appendPhase(new RemoveValueProxyPhase()); - if (CullFrameStates.getValue()) { - appendPhase(new CullFrameStatesPhase()); - } - if (OptCanonicalizer.getValue()) { appendPhase(canonicalizer); } diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeFlood.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeFlood.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeFlood.java Fri Jun 14 19:13:32 2013 +0200 @@ -43,7 +43,7 @@ } } - public void addAll(Iterable nodes) { + public void addAll(Iterable nodes) { for (Node node : nodes) { this.add(node); } diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java Fri Jun 14 19:13:32 2013 +0200 @@ -48,7 +48,7 @@ @Override protected InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) { HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method; - HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, true); + HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, true, null); HotSpotCompiledNmethod compiledNmethod = new HotSpotCompiledNmethod(hsMethod, StructuredGraph.INVOCATION_ENTRY_BCI, compResult); CodeInstallResult result = graalRuntime().getCompilerToVM().installCode(compiledNmethod, installedCode, null); Assert.assertEquals("Error installing method " + method + ": " + result, result, CodeInstallResult.OK); diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Fri Jun 14 19:13:32 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; /** * Implementation of {@link InstalledCode} for code installed as an nmethod. The nmethod stores a @@ -44,16 +45,22 @@ private final HotSpotResolvedJavaMethod method; private final boolean isDefault; + private final Graph graph; - public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault) { + public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault, Graph graph) { this.method = method; this.isDefault = isDefault; + this.graph = graph; } public boolean isDefault() { return isDefault; } + public Graph getGraph() { + return graph; + } + @Override public ResolvedJavaMethod getMethod() { return method; diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri Jun 14 19:13:32 2013 +0200 @@ -927,15 +927,20 @@ } public HotSpotInstalledCode installMethod(HotSpotResolvedJavaMethod method, int entryBCI, CompilationResult compResult) { - HotSpotInstalledCode installedCode = new HotSpotNmethod(method, true); + HotSpotInstalledCode installedCode = new HotSpotNmethod(method, true, null); graalRuntime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(method, entryBCI, compResult), installedCode, method.getSpeculationLog()); return installedCode; } @Override public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) { + return addMethod(method, compResult, null); + } + + @Override + public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph) { HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method; - HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, false); + HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, false, graph); CodeInstallResult result = graalRuntime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(hotspotMethod, -1, compResult), code, null); if (result != CodeInstallResult.OK) { return null; diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotNmethodExecuteNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotNmethodExecuteNode.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotNmethodExecuteNode.java Fri Jun 14 19:13:32 2013 +0200 @@ -33,6 +33,7 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.phases.common.*; public class HotSpotNmethodExecuteNode extends AbstractCallNode implements Lowerable { @@ -52,7 +53,16 @@ @Override public void lower(LoweringTool tool, LoweringType loweringType) { - replaceWithInvoke(tool.getRuntime()); + if (code.isConstant() && code.asConstant().asObject() instanceof HotSpotNmethod) { + HotSpotNmethod nmethod = (HotSpotNmethod) code.asConstant().asObject(); + InvokeNode invoke = replaceWithInvoke(tool.getRuntime()); + StructuredGraph graph = (StructuredGraph) nmethod.getGraph(); + if (graph != null) { + InliningUtil.inline(invoke, graph, false); + } + } else { + replaceWithInvoke(tool.getRuntime()); + } } protected InvokeNode replaceWithInvoke(MetaAccessProvider tool) { diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Fri Jun 14 19:13:32 2013 +0200 @@ -89,7 +89,7 @@ } // Don't throw away the code as we assume this is a rare event // that will periodically occur. - DeoptimizeNode.deopt(InvalidateReprofile, OptimizedTypeCheckViolated); + DeoptimizeNode.deopt(DeoptimizationAction.None, OptimizedTypeCheckViolated); return falseValue; } diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Fri Jun 14 19:13:32 2013 +0200 @@ -95,7 +95,7 @@ if (condition() instanceof LogicConstantNode) { LogicConstantNode c = (LogicConstantNode) condition(); if (c.getValue() != negated) { - return getGuard().asNode(); + return graph().start(); } } return this; diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Fri Jun 14 19:13:32 2013 +0200 @@ -32,10 +32,9 @@ * A node that changes the type of its input, usually narrowing it. For example, a PI node refines * the type of a receiver during type-guarded inlining to be the type tested by the guard. */ -public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, Node.IterableNodeType, GuardingNode { +public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, Node.IterableNodeType, GuardingNode, Canonicalizable { @Input private ValueNode object; - @Input private FixedNode anchor; public ValueNode object() { return object; @@ -46,10 +45,9 @@ this.object = object; } - public PiNode(ValueNode object, Stamp stamp, FixedNode anchor) { - super(stamp); + public PiNode(ValueNode object, Stamp stamp, GuardingNode anchor) { + super(stamp, anchor); this.object = object; - this.anchor = anchor; } @Override @@ -71,4 +69,15 @@ tool.replaceWithVirtual(state.getVirtualObject()); } } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + if (getGuard() == graph().start()) { + inferStamp(); + if (stamp().equals(object().stamp())) { + return object(); + } + } + return this; + } } diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Fri Jun 14 19:13:32 2013 +0200 @@ -64,7 +64,7 @@ return graph.unique(new IndexedLocationNode(identity, kind, displacement, index, indexScaling)); } - private IndexedLocationNode(LocationIdentity identity, Kind kind, long displacement, ValueNode index, int indexScaling) { + public IndexedLocationNode(LocationIdentity identity, Kind kind, long displacement, ValueNode index, int indexScaling) { super(StampFactory.extension()); assert kind != Kind.Illegal && kind != Kind.Void; this.valueKind = kind; diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeArrayCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeArrayCastNode.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeArrayCastNode.java Fri Jun 14 19:13:32 2013 +0200 @@ -42,11 +42,15 @@ this.length = length; } - public UnsafeArrayCastNode(ValueNode object, ValueNode length, Stamp stamp, ValueNode anchor) { + public UnsafeArrayCastNode(ValueNode object, ValueNode length, Stamp stamp, GuardingNode anchor) { super(object, stamp, anchor); this.length = length; } + private UnsafeArrayCastNode(ValueNode object, ValueNode length, Stamp stamp, ValueNode anchor) { + this(object, length, stamp, (GuardingNode) anchor); + } + @Override public ValueNode canonical(CanonicalizerTool tool) { if (!(object() instanceof ArrayLengthProvider) || length() != ((ArrayLengthProvider) object()).length()) { diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Fri Jun 14 19:13:32 2013 +0200 @@ -36,8 +36,12 @@ super(object, stamp); } + public UnsafeCastNode(ValueNode object, Stamp stamp, GuardingNode anchor) { + super(object, stamp, anchor); + } + public UnsafeCastNode(ValueNode object, Stamp stamp, ValueNode anchor) { - super(object, stamp, (FixedNode) anchor); + this(object, stamp, (GuardingNode) anchor); } public UnsafeCastNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) { @@ -100,7 +104,7 @@ public static native T unsafeCast(Object object, @ConstantNodeParameter Stamp stamp); @NodeIntrinsic - public static native T unsafeCast(Object object, @ConstantNodeParameter Stamp stamp, ValueNode anchor); + public static native T unsafeCast(Object object, @ConstantNodeParameter Stamp stamp, GuardingNode anchor); @SuppressWarnings("unused") @NodeIntrinsic diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java Fri Jun 14 19:13:32 2013 +0200 @@ -37,10 +37,11 @@ * * @param method a method to which the executable code is begin added * @param compResult the compilation result to be added + * @param graph the graph that represents the method * @return a reference to the compiled and ready-to-run code or null if the code installation * failed */ - InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult); + InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph); void lower(Node n, LoweringTool tool); } diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java Fri Jun 14 19:13:32 2013 +0200 @@ -129,7 +129,15 @@ @Override public boolean alwaysDistinct(Stamp otherStamp) { IntegerStamp other = (IntegerStamp) otherStamp; - return lowerBound > other.upperBound || upperBound < other.lowerBound; + if (lowerBound > other.upperBound || upperBound < other.lowerBound) { + return true; + } else { + if ((mask & other.mask) == 0) { + // zero is the only common value if the masks don't overlap => check for non-zero + return lowerBound > 0 || upperBound < 0 || other.lowerBound > 0 || other.upperBound < 0; + } + return false; + } } @Override diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java Fri Jun 14 19:13:32 2013 +0200 @@ -101,6 +101,10 @@ private static final long LONG_SIGN_BIT = 0x8000000000000000L; private static Stamp stampForMask(Kind kind, long mask) { + return stampForMask(kind, mask, 0); + } + + private static Stamp stampForMask(Kind kind, long mask, long alwaysSetBits) { long lowerBound; long upperBound; if (kind == Kind.Int && (mask & INTEGER_SIGN_BIT) != 0) { @@ -112,7 +116,7 @@ lowerBound = Long.MIN_VALUE; upperBound = mask ^ LONG_SIGN_BIT; } else { - lowerBound = 0; + lowerBound = alwaysSetBits; upperBound = mask; } return StampFactory.forInteger(kind, lowerBound, upperBound, mask); @@ -127,7 +131,11 @@ public static Stamp or(IntegerStamp stamp1, IntegerStamp stamp2) { Kind kind = stamp1.kind(); long mask = stamp1.mask() | stamp2.mask(); - return stampForMask(kind, mask); + if (stamp1.lowerBound() >= 0 && stamp2.lowerBound() >= 0) { + return stampForMask(kind, mask, stamp1.lowerBound() | stamp2.lowerBound()); + } else { + return stampForMask(kind, mask); + } } public static Stamp xor(IntegerStamp stamp1, IntegerStamp stamp2) { diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CullFrameStatesPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CullFrameStatesPhase.java Fri Jun 14 19:12:56 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2012, 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.phases.common; - -import java.util.*; - -import com.oracle.graal.debug.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.util.*; -import com.oracle.graal.phases.*; -import com.oracle.graal.phases.graph.*; - -/** - * This phase culls unused FrameStates from the graph. It does a post order iteration over the - * graph, and - */ -public class CullFrameStatesPhase extends Phase { - - private static final DebugMetric metricFrameStatesCulled = Debug.metric("FrameStatesCulled"); - private static final DebugMetric metricNodesRemoved = Debug.metric("NodesRemoved"); - private static final DebugMetric metricMergesTraversed = Debug.metric("MergesTraversed"); - - @Override - protected void run(StructuredGraph graph) { - int initialNodes = graph.getNodeCount(); - new CullFrameStates(graph.start(), new State(null)).apply(); - metricNodesRemoved.add(initialNodes - graph.getNodeCount()); - } - - public static class State implements MergeableState { - - private FrameState lastFrameState; - - public State(FrameState lastFrameState) { - this.lastFrameState = lastFrameState; - } - - @Override - public boolean merge(MergeNode merge, List withStates) { - FrameState stateAfter = merge.stateAfter(); - if (merge instanceof LoopBeginNode) { - if (stateAfter != null) { - lastFrameState = stateAfter; - } - return true; - } - metricMergesTraversed.increment(); - if (stateAfter != null) { - for (State other : withStates) { - if (other.lastFrameState != lastFrameState) { - lastFrameState = stateAfter; - return true; - } - } - metricFrameStatesCulled.increment(); - merge.setStateAfter(null); - if (stateAfter.usages().isEmpty()) { - GraphUtil.killWithUnusedFloatingInputs(stateAfter); - } - } - return true; - } - - @Override - public void loopBegin(LoopBeginNode loopBegin) { - } - - @Override - public void loopEnds(LoopBeginNode loopBegin, List loopEndStates) { - } - - @Override - public void afterSplit(AbstractBeginNode node) { - } - - @Override - public State clone() { - return new State(lastFrameState); - } - } - - public static class CullFrameStates extends PostOrderNodeIterator { - - public CullFrameStates(FixedNode start, State initialState) { - super(start, initialState); - } - - @Override - protected void node(FixedNode node) { - if (node instanceof StateSplit) { - FrameState stateAfter = ((StateSplit) node).stateAfter(); - if (stateAfter != null) { - state.lastFrameState = stateAfter; - } - } - } - } - -} diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Fri Jun 14 19:13:32 2013 +0200 @@ -91,6 +91,16 @@ this.optimisticOpts = optimisticOpts; } + public InliningPhase(MetaAccessProvider runtime, Replacements replacements, Assumptions assumptions, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts, InliningPolicy policy) { + this.runtime = runtime; + this.replacements = replacements; + this.compilationAssumptions = assumptions; + this.cache = cache; + this.plan = plan; + this.inliningPolicy = policy; + this.optimisticOpts = optimisticOpts; + } + public void setCustomCanonicalizer(CustomCanonicalizer customCanonicalizer) { this.customCanonicalizer = customCanonicalizer; } @@ -312,9 +322,6 @@ new CanonicalizerPhase.Instance(runtime, assumptions, !AOTCompilation.getValue()).apply(newGraph); } - if (CullFrameStates.getValue()) { - new CullFrameStatesPhase().apply(newGraph); - } if (CacheGraphs.getValue() && cache != null) { cache.put(newGraph.copy(), hasMatureProfilingInfo); } diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Jun 14 19:13:32 2013 +0200 @@ -491,15 +491,13 @@ LoadHubNode receiverHub = graph.add(new LoadHubNode(receiver, typeHub.kind())); CompareNode typeCheck = CompareNode.createCompareNode(Condition.EQ, receiverHub, typeHub); FixedGuardNode guard = graph.add(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile)); - ValueAnchorNode anchor = graph.add(new ValueAnchorNode()); assert invoke.predecessor() != null; - ValueNode anchoredReceiver = createAnchoredReceiver(graph, anchor, type, receiver, true); + ValueNode anchoredReceiver = createAnchoredReceiver(graph, guard, type, receiver, true); invoke.callTarget().replaceFirstInput(receiver, anchoredReceiver); graph.addBeforeFixed(invoke.asNode(), receiverHub); graph.addBeforeFixed(invoke.asNode(), guard); - graph.addBeforeFixed(invoke.asNode(), anchor); } @Override @@ -1227,9 +1225,13 @@ } } - private static PiNode createAnchoredReceiver(StructuredGraph graph, FixedNode anchor, ResolvedJavaType commonType, ValueNode receiver, boolean exact) { + private static PiNode createAnchoredReceiver(StructuredGraph graph, GuardingNode anchor, ResolvedJavaType commonType, ValueNode receiver, boolean exact) { + return createAnchoredReceiver(graph, anchor, receiver, exact ? StampFactory.exactNonNull(commonType) : StampFactory.declaredNonNull(commonType)); + } + + private static PiNode createAnchoredReceiver(StructuredGraph graph, GuardingNode anchor, ValueNode receiver, Stamp stamp) { // to avoid that floating reads on receiver fields float above the type check - return graph.unique(new PiNode(receiver, exact ? StampFactory.exactNonNull(commonType) : StampFactory.declaredNonNull(commonType), anchor)); + return graph.unique(new PiNode(receiver, stamp, anchor)); } // TODO (chaeubl): cleanup this method @@ -1298,9 +1300,17 @@ FrameState stateAfter = invoke.stateAfter(); assert stateAfter == null || stateAfter.isAlive(); - GuardingNode receiverNullCheckNode = null; if (receiverNullCheck) { - receiverNullCheckNode = receiverNullCheck(invoke); + GuardingNode receiverNullCheckNode = receiverNullCheck(invoke); + if (receiverNullCheckNode != null) { + ValueNode receiver = invoke.callTarget().arguments().get(0); + Stamp piStamp = receiver.stamp(); + if (piStamp instanceof ObjectStamp) { + piStamp = piStamp.join(StampFactory.objectNonNull()); + } + ValueNode anchoredReceiver = createAnchoredReceiver(graph, receiverNullCheckNode, receiver, piStamp); + invoke.callTarget().replaceFirstInput(receiver, anchoredReceiver); + } } IdentityHashMap replacements = new IdentityHashMap<>(); @@ -1313,18 +1323,7 @@ if (node == entryPointNode || node == entryPointNode.stateAfter()) { // Do nothing. } else if (node instanceof LocalNode) { - int localIndex = ((LocalNode) node).index(); - ValueNode parameter = parameters.get(localIndex); - if (receiverNullCheckNode != null && localIndex == 0) { - Stamp piStamp = parameter.stamp(); - if (piStamp instanceof ObjectStamp) { - piStamp = piStamp.join(StampFactory.objectNonNull()); - } - PiNode piReceiver = graph.add(new PiNode(parameter, piStamp)); - piReceiver.setGuard(receiverNullCheckNode); - parameter = piReceiver; - } - replacements.put(node, parameter); + replacements.put(node, parameters.get(((LocalNode) node).index())); } else { nodes.add(node); if (node instanceof ReturnNode) { diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Fri Jun 14 19:13:32 2013 +0200 @@ -198,8 +198,6 @@ @Option(help = "") public static final OptionValue ConditionalElimination = new OptionValue<>(true); @Option(help = "") - public static final OptionValue CullFrameStates = new OptionValue<>(false); - @Option(help = "") public static final OptionValue UseProfilingInformation = new OptionValue<>(true); @Option(help = "") static final OptionValue RemoveNeverExecutedCode = new OptionValue<>(true); diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Fri Jun 14 19:13:32 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.virtual.phases.ea; +import static com.oracle.graal.phases.GraalOptions.*; + import java.util.*; import com.oracle.graal.debug.*; @@ -82,7 +84,9 @@ @Override protected Void processBlock(Block block, Void currentState) { apply(blockEffects.get(block), block); - Debug.dump(graph, "after processing block %s", block); + if (TraceEscapeAnalysis.getValue()) { + Debug.dump(graph, "after processing block %s", block); + } return currentState; } @@ -109,7 +113,7 @@ @Override protected BlockT processBlock(Block block, BlockT state) { - VirtualUtil.trace("\nBlock: %s (", block); + VirtualUtil.trace("\nBlock: %s, preds: %s, succ: %s (", block, block.getPredecessors(), block.getSuccessors()); GraphEffectList effects = blockEffects.get(block); FixedWithNextNode lastFixedNode = null; @@ -130,6 +134,7 @@ assert blockEffects.get(merge).isEmpty(); MergeProcessor processor = createMergeProcessor(merge); processor.merge(states); + processor.commitEnds(states); blockEffects.get(merge).addAll(processor.mergeEffects); blockEffects.get(merge).addAll(processor.afterMergeEffects); return processor.newState; @@ -138,7 +143,7 @@ @Override protected final List processLoop(Loop loop, BlockT initialState) { BlockT loopEntryState = initialState; - BlockT lastMergedState = initialState; + BlockT lastMergedState = cloneState(initialState); MergeProcessor mergeProcessor = createMergeProcessor(loop.header); for (int iteration = 0; iteration < 10; iteration++) { LoopInfo info = ReentrantBlockIterator.processLoop(this, loop, cloneState(lastMergedState)); @@ -154,6 +159,8 @@ Debug.log("%s", lastMergedState); if (mergeProcessor.newState.equivalentTo(lastMergedState)) { + mergeProcessor.commitEnds(states); + blockEffects.get(loop.header).insertAll(mergeProcessor.mergeEffects, 0); loopMergeEffects.put(loop, mergeProcessor.afterMergeEffects); @@ -198,6 +205,12 @@ protected void merge(List states) { newState = getInitialState(); newState.meetAliases(states); + mergeEffects.clear(); + afterMergeEffects.clear(); + } + + @SuppressWarnings("unused") + protected void commitEnds(List states) { } } } diff -r a323a9e20f9d -r e90e48dae0ab graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Fri Jun 14 19:12:56 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Fri Jun 14 19:13:32 2013 +0200 @@ -349,9 +349,7 @@ locksMatch &= obj.locksEqual(startObj); } - assert virtual < states.size() || locksMatch : "mismatching lock counts at " + merge; - - if (virtual < states.size()) { + if (virtual < states.size() || !locksMatch) { if (singleValue == null) { PhiNode materializedValuePhi = getCachedPhi(object, Kind.Object); mergeEffects.addFloatingNode(materializedValuePhi, "materializedPhi"); diff -r a323a9e20f9d -r e90e48dae0ab mxtool/mx.py --- a/mxtool/mx.py Fri Jun 14 19:12:56 2013 +0200 +++ b/mxtool/mx.py Fri Jun 14 19:13:32 2013 +0200 @@ -2652,6 +2652,7 @@ shutil.rmtree(join(p.dir, 'nbproject'), ignore_errors=True) rm(join(p.dir, '.classpath')) rm(join(p.dir, '.project')) + rm(join(p.dir, '.factorypath')) rm(join(p.dir, 'build.xml')) rm(join(p.dir, 'eclipse-build.xml')) try: