changeset 15517:4f603d776ecc

[flow-sensitive] too many type-refinements didn't improve performance
author Miguel Garcia <miguel.m.garcia@oracle.com>
date Mon, 05 May 2014 17:45:20 +0200
parents 8653634b9d11
children fbe9e7088e35
files graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/EquationalReasoner.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReduction.java
diffstat 2 files changed, 26 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/EquationalReasoner.java	Mon May 05 17:06:02 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/EquationalReasoner.java	Mon May 05 17:45:20 2014 +0200
@@ -237,6 +237,17 @@
             // picked cached substitution
             return result;
         }
+        if (FlowUtil.hasLegalObjectStamp(v) && state.isNull(v)) {
+            // it's ok to return nullConstant in deverbosify unlike in downcast
+            metricNullInserted.increment();
+            return nullConstant;
+        }
+        if (v instanceof ValueProxy) {
+            return v;
+        }
+        if (!(n instanceof FloatingNode)) {
+            return n;
+        }
         if ((visited != null && visited.contains(n)) || added.contains(v)) {
             return v;
         }
@@ -254,30 +265,13 @@
          * Past this point, if we ever want `n` to be deverbosified, it must be looked-up by one of
          * the cases above. One sure way to achieve that is with `rememberSubstitution(old, new)`
          */
-        if (v instanceof ValueProxy) {
-            return downcast(v);
-        }
 
-        if (n instanceof FloatingNode) {
-            /*
-             * `deverbosifyFloatingNode()` will drill down over floating inputs, when that not
-             * possible anymore it resorts to calling `downcast()`. Thus it's ok to take the
-             * `deverbosifyFloatingNode()` route first, as no downcasting opportunity will be
-             * missed.
-             */
-            return deverbosifyFloatingNode((FloatingNode) n);
-        }
-
-        if (FlowUtil.hasLegalObjectStamp(v)) {
-            if (state.isNull(v)) {
-                // it's ok to return nullConstant in deverbosify unlike in downcast
-                metricNullInserted.increment();
-                return nullConstant;
-            }
-            return downcast(v);
-        }
-
-        return n;
+        /*
+         * `deverbosifyFloatingNode()` will drill down over floating inputs, when that not possible
+         * anymore it resorts to calling `downcast()`. Thus it's ok to take the
+         * `deverbosifyFloatingNode()` route first, as no downcasting opportunity will be missed.
+         */
+        return deverbosifyFloatingNode((FloatingNode) n);
     }
 
     /**
@@ -341,16 +335,7 @@
         }
         if (changed == null) {
             assert visited.contains(f) || added.contains(f);
-            if (FlowUtil.hasLegalObjectStamp(f)) {
-                /*
-                 * No input has changed doesn't imply there's no witness to refine the
-                 * floating-object value.
-                 */
-                ValueNode d = downcast(f);
-                return d;
-            } else {
-                return f;
-            }
+            return f;
         }
         FlowUtil.inferStampAndCheck(changed);
         added.add(changed);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReduction.java	Mon May 05 17:06:02 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReduction.java	Mon May 05 17:45:20 2014 +0200
@@ -305,9 +305,16 @@
      *
      */
     private MethodCallTargetNode deverbosifyInputsCopyOnWrite(MethodCallTargetNode parent) {
+        final MethodCallTargetNode.InvokeKind ik = parent.invokeKind();
+        final boolean shouldTryDevirt = (ik == MethodCallTargetNode.InvokeKind.Interface || ik == MethodCallTargetNode.InvokeKind.Virtual);
+        boolean shouldDowncastReceiver = shouldTryDevirt;
         MethodCallTargetNode changed = null;
         for (ValueNode i : FlowUtil.distinctValueAndConditionInputs(parent)) {
-            Node j = reasoner.deverbosify(i);
+            ValueNode j = (ValueNode) reasoner.deverbosify(i);
+            if (shouldDowncastReceiver) {
+                shouldDowncastReceiver = false;
+                j = reasoner.downcast(j);
+            }
             if (i != j) {
                 assert j != parent;
                 if (changed == null) {