changeset 15807:c9f913e5a93b

handle expected phis when converting to trapping null checks
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Tue, 20 May 2014 21:40:13 -0700
parents 240cc9a901fb
children 5656cfe34979
files graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java
diffstat 1 files changed, 41 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java	Tue May 20 21:35:32 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java	Tue May 20 21:40:13 2014 -0700
@@ -57,27 +57,53 @@
     }
 
     private static void tryUseTrappingNullCheck(MetaAccessProvider metaAccessProvider, DynamicDeoptimizeNode deopt) {
-        ValueNode speculation = deopt.getSpeculation();
-        if (!speculation.isConstant() || !speculation.asConstant().equals(Constant.NULL_OBJECT)) {
-            return;
-        }
         Node predecessor = deopt.predecessor();
         if (predecessor instanceof MergeNode) {
             MergeNode merge = (MergeNode) predecessor;
 
-            if (merge.phis().isEmpty()) {
-                // Process each predecessor at the merge, unpacking the reasons as needed.
-                ValueNode reason = deopt.getActionAndReason();
-                List<ValueNode> values = reason instanceof ValuePhiNode ? ((ValuePhiNode) reason).values().snapshot() : null;
+            // Process each predecessor at the merge, unpacking the reasons and speculations as
+            // needed.
+            ValueNode reason = deopt.getActionAndReason();
+            ValuePhiNode reasonPhi = null;
+            List<ValueNode> reasons = null;
+            int expectedPhis = 0;
 
-                int index = 0;
-                for (AbstractEndNode end : merge.cfgPredecessors().snapshot()) {
-                    ValueNode thisReason = values != null ? values.get(index++) : reason;
-                    if (thisReason.isConstant()) {
-                        DeoptimizationReason deoptimizationReason = metaAccessProvider.decodeDeoptReason(thisReason.asConstant());
-                        tryUseTrappingNullCheck(deopt, end.predecessor(), deoptimizationReason, null);
-                    }
+            if (reason instanceof ValuePhiNode) {
+                reasonPhi = (ValuePhiNode) reason;
+                if (reasonPhi.merge() != merge) {
+                    return;
                 }
+                reasons = reasonPhi.values().snapshot();
+                expectedPhis++;
+            } else if (!reason.isConstant()) {
+                return;
+            }
+
+            ValueNode speculation = deopt.getSpeculation();
+            ValuePhiNode speculationPhi = null;
+            List<ValueNode> speculations = null;
+            if (speculation instanceof ValuePhiNode) {
+                speculationPhi = (ValuePhiNode) speculation;
+                if (speculationPhi.merge() != merge) {
+                    return;
+                }
+                speculations = speculationPhi.values().snapshot();
+                expectedPhis++;
+            }
+
+            if (merge.phis().count() != expectedPhis) {
+                return;
+            }
+
+            int index = 0;
+            for (AbstractEndNode end : merge.cfgPredecessors().snapshot()) {
+                ValueNode thisReason = reasons != null ? reasons.get(index) : reason;
+                ValueNode thisSpeculation = speculations != null ? speculations.get(index++) : speculation;
+                if (!thisReason.isConstant() || !thisSpeculation.isConstant() || !thisSpeculation.asConstant().equals(Constant.NULL_OBJECT)) {
+                    continue;
+                }
+                DeoptimizationReason deoptimizationReason = metaAccessProvider.decodeDeoptReason(thisReason.asConstant());
+                tryUseTrappingNullCheck(deopt, end.predecessor(), deoptimizationReason, null);
             }
         }
     }