changeset 14746:7544068e1a91

Perform de-virtualization of calls only in canonicalizer and not in graph builder
author Christian Wimmer <christian.wimmer@oracle.com>
date Tue, 25 Mar 2014 13:32:32 -0700
parents 65b005b58825
children a836fed0e270
files graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java
diffstat 3 files changed, 25 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Tue Mar 25 11:50:57 2014 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Tue Mar 25 13:32:32 2014 -0700
@@ -321,6 +321,7 @@
         Assumptions assumptions = new Assumptions(false);
         HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
+        canonicalizer.apply(graph, context);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
         if (loopPeeling) {
             new LoopTransformHighPhase().apply(graph);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Mar 25 11:50:57 2014 -0700
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Mar 25 13:32:32 2014 -0700
@@ -1113,7 +1113,7 @@
         private void genInvokeInterface(JavaMethod target) {
             if (target instanceof ResolvedJavaMethod) {
                 ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(true), target.getSignature().getParameterCount(true));
-                genInvokeIndirect(InvokeKind.Interface, (ResolvedJavaMethod) target, args);
+                appendInvoke(InvokeKind.Interface, (ResolvedJavaMethod) target, args);
             } else {
                 handleUnresolvedInvoke(target, InvokeKind.Interface);
             }
@@ -1148,7 +1148,7 @@
                 }
                 ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(hasReceiver), target.getSignature().getParameterCount(hasReceiver));
                 if (hasReceiver) {
-                    genInvokeIndirect(InvokeKind.Virtual, (ResolvedJavaMethod) target, args);
+                    appendInvoke(InvokeKind.Virtual, (ResolvedJavaMethod) target, args);
                 } else {
                     appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args);
                 }
@@ -1163,47 +1163,12 @@
                 assert target != null;
                 assert target.getSignature() != null;
                 ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(true), target.getSignature().getParameterCount(true));
-                invokeDirect((ResolvedJavaMethod) target, args);
+                appendInvoke(InvokeKind.Special, (ResolvedJavaMethod) target, args);
             } else {
                 handleUnresolvedInvoke(target, InvokeKind.Special);
             }
         }
 
-        private void genInvokeIndirect(InvokeKind invokeKind, ResolvedJavaMethod target, ValueNode[] args) {
-            ValueNode receiver = args[0];
-            // attempt to devirtualize the call
-            ResolvedJavaType klass = target.getDeclaringClass();
-
-            // 0. check for trivial cases
-            if (target.canBeStaticallyBound()) {
-                // check for trivial cases (e.g. final methods, nonvirtual methods)
-                invokeDirect(target, args);
-                return;
-            }
-            // 1. check if the exact type of the receiver can be determined
-            ResolvedJavaType exact = klass.asExactType();
-            if (exact == null && receiver.stamp() instanceof ObjectStamp) {
-                ObjectStamp receiverStamp = (ObjectStamp) receiver.stamp();
-                if (receiverStamp.isExactType()) {
-                    exact = receiverStamp.type();
-                }
-            }
-            if (exact != null) {
-                // either the holder class is exact, or the receiver object has an exact type
-                ResolvedJavaMethod exactMethod = exact.resolveMethod(target);
-                if (exactMethod != null) {
-                    invokeDirect(exactMethod, args);
-                    return;
-                }
-            }
-            // devirtualization failed, produce an actual invokevirtual
-            appendInvoke(invokeKind, target, args);
-        }
-
-        private void invokeDirect(ResolvedJavaMethod target, ValueNode[] args) {
-            appendInvoke(InvokeKind.Special, target, args);
-        }
-
         private void appendInvoke(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args) {
             Kind resultType = targetMethod.getSignature().getReturnKind();
             if (DeoptALot.getValue()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Tue Mar 25 11:50:57 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Tue Mar 25 13:32:32 2014 -0700
@@ -126,15 +126,28 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        if (!isStatic()) {
+        if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) {
+            // attempt to devirtualize the call
+
+            // check for trivial cases (e.g. final methods, nonvirtual methods)
+            if (targetMethod.canBeStaticallyBound()) {
+                invokeKind = InvokeKind.Special;
+                return this;
+            }
+
+            // check if the exact type of the receiver can be determined
             ValueNode receiver = receiver();
-            if (receiver != null && ObjectStamp.isExactType(receiver) && ObjectStamp.typeOrNull(receiver) != null) {
-                if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) {
-                    ResolvedJavaMethod method = ObjectStamp.typeOrNull(receiver).resolveMethod(targetMethod);
-                    if (method != null) {
-                        invokeKind = InvokeKind.Special;
-                        targetMethod = method;
-                    }
+            ResolvedJavaType exact = targetMethod.getDeclaringClass().asExactType();
+            if (exact == null && ObjectStamp.isExactType(receiver)) {
+                exact = ObjectStamp.typeOrNull(receiver);
+            }
+            if (exact != null) {
+                // either the holder class is exact, or the receiver object has an exact type
+                ResolvedJavaMethod exactMethod = exact.resolveMethod(targetMethod);
+                if (exactMethod != null) {
+                    invokeKind = InvokeKind.Special;
+                    targetMethod = exactMethod;
+                    return this;
                 }
             }
         }