# HG changeset patch # User Lukas Stadler # Date 1373903555 -7200 # Node ID 88d0dc38845018726dc062443e8df35be8ad9a8d # Parent 3a044e575466c94e4e3ca1497cfa9bb86785eabb let ConditionalEliminationPhase change invokes to InvokeKind.Special based on type information diff -r 3a044e575466 -r 88d0dc388450 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java Mon Jul 15 17:32:12 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java Mon Jul 15 17:52:35 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()); + } + } diff -r 3a044e575466 -r 88d0dc388450 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Mon Jul 15 17:32:12 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Mon Jul 15 17:52:35 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); + } + } + } + } + } + } } }