# HG changeset patch # User Tom Rodriguez # Date 1400647213 25200 # Node ID c9f913e5a93b249362a3107d5b4f165f27ca584e # Parent 240cc9a901fb6d56b8cec8246e26e363458fa629 handle expected phis when converting to trapping null checks diff -r 240cc9a901fb -r c9f913e5a93b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java --- 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 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 reasons = null; + int expectedPhis = 0; + + if (reason instanceof ValuePhiNode) { + reasonPhi = (ValuePhiNode) reason; + if (reasonPhi.merge() != merge) { + return; + } + reasons = reasonPhi.values().snapshot(); + expectedPhis++; + } else if (!reason.isConstant()) { + return; + } - 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); - } + ValueNode speculation = deopt.getSpeculation(); + ValuePhiNode speculationPhi = null; + List 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); } } }