changeset 10767:88d0dc388450

let ConditionalEliminationPhase change invokes to InvokeKind.Special based on type information
author Lukas Stadler <lukas.stadler@jku.at>
date Mon, 15 Jul 2013 17:52:35 +0200
parents 3a044e575466
children 058abc2b59a5
files graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java
diffstat 2 files changed, 53 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- 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());
+    }
+
 }
--- 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);
+                                }
+                            }
+                        }
+                    }
+                }
+
             }
         }
     }