Mercurial > hg > graal-jvmci-8
changeset 10768:058abc2b59a5
Merge
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Mon, 15 Jul 2013 17:54:00 +0200 |
parents | 88d0dc388450 (diff) dd7a8807378b (current diff) |
children | 395d34c10e26 f0fdbb2b7135 |
files | graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java |
diffstat | 16 files changed, 194 insertions(+), 59 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java Mon Jul 15 16:53:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java Mon Jul 15 17:54:00 2013 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.java.MethodCallTargetNode.*; import com.oracle.graal.phases.common.*; /** @@ -172,4 +173,24 @@ assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0); } } + + public static int testInvokeSnippet(Number n) { + if (n instanceof Integer) { + return n.intValue(); + } else { + return 1; + } + } + + @Test + public void testInvoke() { + test("testInvokeSnippet", new Integer(16)); + StructuredGraph graph = parse("testInvokeSnippet"); + new CanonicalizerPhase.Instance(runtime(), null, true).apply(graph); + new ConditionalEliminationPhase(runtime()).apply(graph); + + InvokeNode invoke = graph.getNodes(InvokeNode.class).first(); + assertEquals(InvokeKind.Special, ((MethodCallTargetNode) invoke.callTarget()).invokeKind()); + } + }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Mon Jul 15 16:53:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Mon Jul 15 17:54:00 2013 +0200 @@ -507,6 +507,7 @@ } private StructuredGraph parse0(Method m, GraphBuilderConfiguration conf) { + assert m.getAnnotation(Test.class) == null : "shouldn't parse method with @Test annotation: " + m; ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(m); StructuredGraph graph = new StructuredGraph(javaMethod); new GraphBuilderPhase(runtime, conf, OptimisticOptimizations.ALL).apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Mon Jul 15 16:53:35 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Mon Jul 15 17:54:00 2013 +0200 @@ -24,8 +24,6 @@ import static org.junit.Assert.*; -import java.util.concurrent.*; - import org.junit.*; import com.oracle.graal.api.code.*; @@ -43,7 +41,7 @@ public static Object staticField; - public static class TestObject implements Callable<Integer> { + public static class TestObject { public int x; public int y; @@ -52,11 +50,6 @@ this.x = x; this.y = y; } - - @Override - public Integer call() throws Exception { - return x; - } } public static class TestObject2 { @@ -70,6 +63,16 @@ } } + public static class TestObject3 extends TestObject { + + public int z; + + public TestObject3(int x, int y, int z) { + super(x, y); + this.z = z; + } + } + @SuppressWarnings("all") public static int testSimpleSnippet(TestObject a) { a.x = 2; @@ -213,6 +216,24 @@ assertEquals(1, graph.getNodes().filter(StoreFieldNode.class).count()); } + public static int testValueProxySnippet(boolean b, TestObject o) { + int sum = 0; + if (b) { + sum += o.x; + } else { + TestObject3 p = (TestObject3) o; + sum += p.x; + } + sum += o.x; + return sum; + } + + @Test + public void testValueProxy() { + processMethod("testValueProxySnippet"); + assertEquals(2, graph.getNodes().filter(LoadFieldNode.class).count()); + } + final ReturnNode getReturn(String snippet) { processMethod(snippet); assertEquals(1, graph.getNodes(ReturnNode.class).count());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/FixedValueAnchorNode.java Mon Jul 15 16:53:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/FixedValueAnchorNode.java Mon Jul 15 17:54:00 2013 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -public final class FixedValueAnchorNode extends FixedWithNextNode implements LIRLowerable { +public final class FixedValueAnchorNode extends FixedWithNextNode implements LIRLowerable, ValueProxy { @Input private ValueNode object; @@ -53,4 +53,9 @@ generator.setResult(this, generator.operand(object)); } + @Override + public ValueNode getOriginalValue() { + return object; + } + }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java Mon Jul 15 16:53:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java Mon Jul 15 17:54:00 2013 +0200 @@ -34,7 +34,7 @@ * * A GuardedValueNode will only go away if its guard is null or {@link StructuredGraph#start()}. */ -public class GuardedValueNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, Node.IterableNodeType, GuardingNode, Canonicalizable { +public class GuardedValueNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, Node.IterableNodeType, GuardingNode, Canonicalizable, ValueProxy { @Input private ValueNode object; @@ -81,4 +81,9 @@ } return this; } + + @Override + public ValueNode getOriginalValue() { + return object; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Mon Jul 15 16:53:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Mon Jul 15 17:54:00 2013 +0200 @@ -34,7 +34,7 @@ * A node that changes the stamp of its input based on some condition being true. */ @NodeInfo(nameTemplate = "GuardingPi(!={p#negated}) {p#reason/s}") -public class GuardingPiNode extends FixedWithNextNode implements Lowerable, GuardingNode, Canonicalizable { +public class GuardingPiNode extends FixedWithNextNode implements Lowerable, GuardingNode, Canonicalizable, ValueProxy { @Input private ValueNode object; @Input private LogicNode condition; @@ -109,4 +109,9 @@ public ValueNode asNode() { return this; } + + @Override + public ValueNode getOriginalValue() { + return object; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Mon Jul 15 16:53:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Mon Jul 15 17:54:00 2013 +0200 @@ -36,7 +36,7 @@ * is as narrow or narrower than the PiNode's type. The PiNode, and therefore also the scheduling * restriction enforced by the anchor, will go away. */ -public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, Node.IterableNodeType, GuardingNode, Canonicalizable { +public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, Node.IterableNodeType, GuardingNode, Canonicalizable, ValueProxy { @Input private ValueNode object; @@ -82,4 +82,9 @@ } return this; } + + @Override + public ValueNode getOriginalValue() { + return object; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java Mon Jul 15 16:53:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java Mon Jul 15 17:54:00 2013 +0200 @@ -27,7 +27,6 @@ import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; /** * A value proxy that is inserted in the frame state of a loop exit for any value that is created @@ -35,7 +34,7 @@ * loop. */ @NodeInfo(nameTemplate = "{p#type/s}Proxy") -public class ProxyNode extends FloatingNode implements Node.IterableNodeType, ValueNumberable, Canonicalizable, Virtualizable, LIRLowerable { +public class ProxyNode extends FloatingNode implements Node.IterableNodeType, ValueNumberable, Canonicalizable, Virtualizable, LIRLowerable, ValueProxy { @Input(notDataflow = true) private AbstractBeginNode proxyPoint; @Input private ValueNode value; @@ -60,11 +59,6 @@ return updateStamp(value.stamp()); } - @Override - public Stamp stamp() { - return value().stamp(); - } - public AbstractBeginNode proxyPoint() { return proxyPoint; } @@ -116,4 +110,8 @@ return graph.unique(new ProxyNode(value, exit, PhiType.Memory, location)); } + @Override + public ValueNode getOriginalValue() { + return value; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Mon Jul 15 16:53:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Mon Jul 15 17:54:00 2013 +0200 @@ -27,12 +27,11 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; /** * A node that attaches a type profile to a proxied input node. */ -public final class TypeProfileProxyNode extends FloatingNode implements Canonicalizable, Node.IterableNodeType { +public final class TypeProfileProxyNode extends FloatingNode implements Canonicalizable, Node.IterableNodeType, ValueProxy { @Input private ValueNode object; private final JavaTypeProfile profile; @@ -67,12 +66,7 @@ @Override public boolean inferStamp() { - return object.inferStamp(); - } - - @Override - public Stamp stamp() { - return object.stamp(); + return updateStamp(object.stamp()); } @Override @@ -130,4 +124,9 @@ } assert graph.getNodes(TypeProfileProxyNode.class).count() == 0; } + + @Override + public ValueNode getOriginalValue() { + return object; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Mon Jul 15 16:53:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Mon Jul 15 17:54:00 2013 +0200 @@ -44,7 +44,7 @@ this.stamp = stamp; } - public Stamp stamp() { + public final Stamp stamp() { return stamp; } @@ -80,7 +80,7 @@ return false; } - public Kind kind() { + public final Kind kind() { return stamp().kind(); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Mon Jul 15 16:53:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Mon Jul 15 17:54:00 2013 +0200 @@ -37,7 +37,7 @@ /** * Implements a type check against a compile-time known type. */ -public final class CheckCastNode extends FixedWithNextNode implements Canonicalizable, Lowerable, Node.IterableNodeType, Virtualizable { +public final class CheckCastNode extends FixedWithNextNode implements Canonicalizable, Lowerable, Node.IterableNodeType, Virtualizable, ValueProxy { @Input private ValueNode object; private final ResolvedJavaType type; @@ -193,4 +193,9 @@ } } } + + @Override + public ValueNode getOriginalValue() { + return object; + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ValueProxy.java Mon Jul 15 17:54:00 2013 +0200 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013, 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.nodes.spi; + +import com.oracle.graal.nodes.*; + +public interface ValueProxy { + + ValueNode getOriginalValue(); + +}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Mon Jul 15 16:53:35 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Mon Jul 15 17:54:00 2013 +0200 @@ -30,6 +30,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; public class GraphUtil { @@ -257,14 +258,6 @@ return null; } - public static ValueNode unProxify(ValueNode proxy) { - ValueNode v = proxy; - while (v instanceof ProxyNode) { - v = ((ProxyNode) v).value(); - } - return v; - } - /** * Returns a string representation of the given collection of objects. * @@ -285,16 +278,31 @@ } /** + * Gets the original value by iterating through all {@link ValueProxy ValueProxies}. + * + * @param value The start value. + * @return The first non-proxy value encountered. + */ + public static ValueNode unproxify(ValueNode value) { + ValueNode result = value; + while (result instanceof ValueProxy) { + result = ((ValueProxy) result).getOriginalValue(); + } + return result; + } + + /** * Tries to find an original value of the given node by traversing through proxies and - * unambiguous phis. + * unambiguous phis. Note that this method will perform an exhaustive search through phis. It is + * intended to be used during graph building, when phi nodes aren't yet canonicalized. * * @param proxy The node whose original value should be determined. */ public static ValueNode originalValue(ValueNode proxy) { ValueNode v = proxy; do { - if (v instanceof ProxyNode) { - v = ((ProxyNode) v).value(); + if (v instanceof ValueProxy) { + v = ((ValueProxy) v).getOriginalValue(); } else if (v instanceof PhiNode) { v = ((PhiNode) v).singleValue(); } else { @@ -308,8 +316,8 @@ NodeWorkList worklist = proxy.graph().createNodeWorkList(); worklist.add(proxy); for (Node node : worklist) { - if (node instanceof ProxyNode) { - worklist.add(((ProxyNode) node).value()); + if (node instanceof ValueProxy) { + worklist.add(((ValueProxy) node).getOriginalValue()); } else if (node instanceof PhiNode) { worklist.addAll(((PhiNode) node).values()); } else {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Mon Jul 15 16:53:35 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Mon Jul 15 17:54:00 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.phases.common; +import java.lang.reflect.*; import java.util.*; import com.oracle.graal.api.meta.*; @@ -33,6 +34,7 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.java.MethodCallTargetNode.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; @@ -193,16 +195,16 @@ } public ResolvedJavaType getNodeType(ValueNode node) { - ResolvedJavaType result = knownTypes.get(node); + ResolvedJavaType result = knownTypes.get(GraphUtil.unproxify(node)); return result == null ? node.objectStamp().type() : result; } public boolean isNull(ValueNode value) { - return value.objectStamp().alwaysNull() || knownNull.contains(value); + return value.objectStamp().alwaysNull() || knownNull.contains(GraphUtil.unproxify(value)); } public boolean isNonNull(ValueNode value) { - return value.objectStamp().nonNull() || knownNonNull.contains(value); + return value.objectStamp().nonNull() || knownNonNull.contains(GraphUtil.unproxify(value)); } @Override @@ -245,25 +247,27 @@ * to be null, otherwise the value is known to be non-null. */ public void addNullness(boolean isNull, ValueNode value) { + ValueNode original = GraphUtil.unproxify(value); if (isNull) { - if (!isNull(value)) { + if (!isNull(original)) { metricNullnessRegistered.increment(); - knownNull.add(value); + knownNull.add(original); } } else { - if (!isNonNull(value)) { + if (!isNonNull(original)) { metricNullnessRegistered.increment(); - knownNonNull.add(value); + knownNonNull.add(original); } } } public void addType(ResolvedJavaType type, ValueNode value) { - ResolvedJavaType knownType = getNodeType(value); + ValueNode original = GraphUtil.unproxify(value); + ResolvedJavaType knownType = getNodeType(original); ResolvedJavaType newType = tighten(type, knownType); if (newType != knownType) { - knownTypes.put(value, newType); + knownTypes.put(original, newType); metricTypeRegistered.increment(); } } @@ -575,6 +579,25 @@ } } } + } else if (node instanceof Invoke) { + Invoke invoke = (Invoke) node; + if (invoke.callTarget() instanceof MethodCallTargetNode) { + MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget(); + ValueNode receiver = callTarget.receiver(); + if (receiver != null && (callTarget.invokeKind() == InvokeKind.Interface || callTarget.invokeKind() == InvokeKind.Virtual)) { + ResolvedJavaType type = state.getNodeType(receiver); + if (type != receiver.objectStamp().type()) { + ResolvedJavaMethod method = type.resolveMethod(callTarget.targetMethod()); + if (method != null) { + if ((method.getModifiers() & Modifier.FINAL) != 0 || (type.getModifiers() & Modifier.FINAL) != 0) { + callTarget.setInvokeKind(InvokeKind.Special); + callTarget.setTargetMethod(method); + } + } + } + } + } + } } }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationPEClosure.java Mon Jul 15 16:53:35 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationPEClosure.java Mon Jul 15 17:54:00 2013 +0200 @@ -34,6 +34,7 @@ import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.virtual.phases.ea.ReadEliminationPEBlockState.ReadCacheEntry; @@ -54,24 +55,26 @@ if (!deleted) { if (node instanceof LoadFieldNode) { LoadFieldNode load = (LoadFieldNode) node; - ValueNode cachedValue = state.getReadCache(load.object(), load.field()); + ValueNode object = GraphUtil.unproxify(load.object()); + ValueNode cachedValue = state.getReadCache(object, load.field()); if (cachedValue != null) { effects.replaceAtUsages(load, cachedValue); state.addScalarAlias(load, cachedValue); + deleted = true; } else { - state.addReadCache(load.object(), load.field(), load); + state.addReadCache(object, load.field(), load); } - deleted = true; } else if (node instanceof StoreFieldNode) { StoreFieldNode store = (StoreFieldNode) node; - ValueNode cachedValue = state.getReadCache(store.object(), store.field()); + ValueNode object = GraphUtil.unproxify(store.object()); + ValueNode cachedValue = state.getReadCache(object, store.field()); if (state.getScalarAlias(store.value()) == cachedValue) { effects.deleteFixedNode(store); deleted = true; } state.killReadCache(store.field()); - state.addReadCache(store.object(), store.field(), store.value()); + state.addReadCache(object, store.field(), store.value()); } else if (node instanceof MemoryCheckpoint.Single) { METRIC_MEMORYCHECKOINT.increment(); LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity();
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Mon Jul 15 16:53:35 2013 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Mon Jul 15 17:54:00 2013 +0200 @@ -70,15 +70,20 @@ @Override protected void run(StructuredGraph graph) { for (Node n : GraphOrder.forwardGraph(graph)) { - if (n instanceof ValueNode) { + if (n instanceof ValueNode && !(n instanceof PhiNode && ((PhiNode) n).isLoopPhi())) { ValueNode valueNode = (ValueNode) n; if (isWord(valueNode)) { changeToWord(valueNode); } } } + for (PhiNode phi : graph.getNodes(PhiNode.class)) { + if (phi.isLoopPhi() && isWord(phi)) { + changeToWord(phi); + } + } - // Remove casts between different word types (which are by now no longer have kind Object) + // Remove casts between different word types (which by now no longer have kind Object) for (CheckCastNode checkCastNode : graph.getNodes().filter(CheckCastNode.class).snapshot()) { if (!checkCastNode.isDeleted() && checkCastNode.kind() == wordKind) { checkCastNode.replaceAtUsages(checkCastNode.object());