changeset 15515:2eb6330e13a3

[flow-sensitive] fix in knownNotToConform
author Miguel Garcia <miguel.m.garcia@oracle.com>
date Mon, 05 May 2014 16:59:02 +0200
parents 229537218983
children 8653634b9d11
files graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CheckCastReduction.java 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 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/State.java
diffstat 4 files changed, 43 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CheckCastReduction.java	Mon May 05 11:55:34 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CheckCastReduction.java	Mon May 05 16:59:02 2014 +0200
@@ -122,7 +122,7 @@
         assert !StampTool.isObjectAlwaysNull(subject) : "Null as per stamp subjects should have been handled above";
 
         // --------- checkCast deemed unsatisfiable by subject-stamp alone ---------
-        if (state.knownNotToConform(subject, toType)) {
+        if (state.knownNotToPassCheckCast(subject, toType)) {
             postponedDeopts.addDeoptBefore(checkCast, checkCast.isForStoreCheck() ? ArrayStoreException : ClassCastException);
             state.impossiblePath();
             // let FixedGuardNode(false).simplify() prune the dead-code control-path
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/EquationalReasoner.java	Mon May 05 11:55:34 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/EquationalReasoner.java	Mon May 05 16:59:02 2014 +0200
@@ -474,6 +474,11 @@
         if (state.isNull(scrutinee)) {
             metricInstanceOfRemoved.increment();
             return falseConstant;
+        } else if (state.knownNotToPassInstanceOf(scrutinee, instanceOf.type())) {
+            // scrutinee turns out to be null -> falseConstant right answer
+            // scrutinee not null, but known-not-to-conform -> falseConstant
+            metricInstanceOfRemoved.increment();
+            return falseConstant;
         } else if (state.isNonNull(scrutinee) && state.knownToConform(scrutinee, instanceOf.type())) {
             metricInstanceOfRemoved.increment();
             return trueConstant;
@@ -547,7 +552,7 @@
         if (cast != null) {
             if (state.knownToConform(cast.subject, cast.type)) {
                 return trueConstant;
-            } else if (state.knownNotToConform(cast.subject, cast.type)) {
+            } else if (state.knownNotToPassCheckCast(cast.subject, cast.type)) {
                 return falseConstant;
             }
             return orNode;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReduction.java	Mon May 05 11:55:34 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReduction.java	Mon May 05 16:59:02 2014 +0200
@@ -232,13 +232,8 @@
                 // `begin` denotes the default case of the TypeSwitchNode
                 return;
             }
-            if (state.knownNotToConform(loadHub.object(), type)) {
-                postponedDeopts.addDeoptAfter(begin, UnreachedCode);
-                state.impossiblePath();
-                return;
-            }
             // it's unwarranted to assume loadHub.object() to be non-null
-            // it also seems unwarranted state.trackCC(loadHub.object(), type, begin);
+            state.trackCC(loadHub.object(), type, begin);
         }
     }
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/State.java	Mon May 05 11:55:34 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/State.java	Mon May 05 16:59:02 2014 +0200
@@ -408,7 +408,8 @@
     }
 
     /**
-     * @return true iff the argument is known to stand for an object conforming to the given type.
+     * @return true iff the argument definitely stands for an object-value that conforms to the
+     *         given type.
      */
     public boolean knownToConform(ValueNode object, ResolvedJavaType to) {
         assert FlowUtil.hasLegalObjectStamp(object);
@@ -430,15 +431,16 @@
     }
 
     /**
-     * @return true iff the argument is known to stand for an object that definitely does not
-     *         conform to the given type.
+     * @return true iff the argument is known to stand for an object that is definitely non-null and
+     *         moreover does not conform to the given type.
      */
-    public boolean knownNotToConform(ValueNode object, ResolvedJavaType to) {
+    public boolean knownNotToPassCheckCast(ValueNode object, ResolvedJavaType to) {
         assert FlowUtil.hasLegalObjectStamp(object);
         assert !to.isPrimitive();
         final ValueNode scrutinee = GraphUtil.unproxify(object);
         if (isNull(scrutinee)) {
             // known-null means it conforms to whatever `to`
+            // and thus passes the check-cast
             return false;
         }
         if (!isNonNull(scrutinee)) {
@@ -457,6 +459,34 @@
         return false;
     }
 
+    /**
+     * @return true iff the argument is known to stand for an object that definitely does not
+     *         conform to the given type (no matter whether the object turns out to be null or
+     *         non-null).
+     */
+    public boolean knownNotToPassInstanceOf(ValueNode object, ResolvedJavaType to) {
+        assert FlowUtil.hasLegalObjectStamp(object);
+        assert !to.isPrimitive();
+        final ValueNode scrutinee = GraphUtil.unproxify(object);
+        if (isNull(scrutinee)) {
+            return true;
+        }
+        ResolvedJavaType stampType = StampTool.typeOrNull(object);
+        if (stampType != null && knownNotToConform(stampType, to)) {
+            // object turns out to be null, positive answer is correct
+            // object turns out non-null, positive answer is also correct
+            return true;
+        }
+        Witness w = typeInfo(scrutinee);
+        boolean witnessAnswer = w != null && !w.cluelessAboutType() && knownNotToConform(w.type(), to);
+        if (witnessAnswer) {
+            // object turns out to be null, positive answer is correct
+            // object turns out non-null, positive answer is also correct
+            return true;
+        }
+        return false;
+    }
+
     // @formatter:off
     /**
      *   \   |     |     |     |
@@ -699,7 +729,7 @@
     private void addFactInstanceOf(boolean isTrue, InstanceOfNode instanceOf, GuardingNode anchor) {
         ValueNode object = instanceOf.object();
         if (isTrue) {
-            if (knownNotToConform(object, instanceOf.type())) {
+            if (knownNotToPassInstanceOf(object, instanceOf.type())) {
                 impossiblePath();
                 return;
             }