# HG changeset patch # User Thomas Wuerthinger # Date 1433427314 -7200 # Node ID ce6b8ee2c6f25cd04a46c0c639fa60873c5c6a06 # Parent 7f3381e97cf790155449e23c634f1fa56ca27d2e Improve implicit null check elimination to be aware of guards. diff -r 7f3381e97cf7 -r ce6b8ee2c6f2 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Thu Jun 04 15:16:14 2015 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Thu Jun 04 16:15:14 2015 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.phases.common; import com.oracle.jvmci.meta.JavaConstant; + import static com.oracle.graal.compiler.common.GraalOptions.*; import java.util.*; @@ -62,7 +63,7 @@ private static class UseImplicitNullChecks extends ScheduledNodeIterator { - private final Map nullGuarded = Node.newIdentityMap(); + private final Map nullGuarded = Node.newIdentityMap(); private final int implicitNullCheckLimit; UseImplicitNullChecks(int implicitNullCheckLimit) { @@ -75,48 +76,85 @@ processGuard(node); } else if (node instanceof Access) { processAccess((Access) node); + } else if (node instanceof PiNode) { + processPi((PiNode) node); } if (node instanceof StateSplit && ((StateSplit) node).stateAfter() != null) { nullGuarded.clear(); } else { - Iterator> it = nullGuarded.entrySet().iterator(); + Iterator> it = nullGuarded.entrySet().iterator(); while (it.hasNext()) { - Entry entry = it.next(); - GuardNode guard = entry.getValue(); + Entry entry = it.next(); + ValueNode guard = entry.getValue(); if (guard.usages().contains(node)) { it.remove(); + } else if (guard instanceof PiNode && guard != node) { + PiNode piNode = (PiNode) guard; + if (piNode.getGuard().asNode().usages().contains(node)) { + it.remove(); + } } } } } + private boolean processPi(PiNode node) { + ValueNode guardNode = nullGuarded.get(node.object()); + if (guardNode != null && node.getGuard() == guardNode) { + nullGuarded.put(node, node); + return true; + } + return false; + } + private void processAccess(Access access) { if (access.canNullCheck()) { - GuardNode guard = nullGuarded.get(access.object()); - if (guard != null && isImplicitNullCheck(access.accessLocation())) { - metricImplicitNullCheck.increment(); - access.setGuard(null); - FixedAccessNode fixedAccess; - if (access instanceof FloatingAccessNode) { - FloatingAccessNode floatingAccessNode = (FloatingAccessNode) access; - MemoryNode lastLocationAccess = floatingAccessNode.getLastLocationAccess(); - fixedAccess = floatingAccessNode.asFixedNode(); - replaceCurrent(fixedAccess); - if (lastLocationAccess != null) { - // fixed accesses are not currently part of the memory graph - GraphUtil.tryKillUnused(lastLocationAccess.asNode()); - } - } else { - fixedAccess = (FixedAccessNode) access; + ValueNode object = access.object(); + check(access, object); + } + } + + private void check(Access access, ValueNode object) { + ValueNode guard = nullGuarded.get(object); + if (guard != null && isImplicitNullCheck(access.accessLocation())) { + if (object instanceof PiNode) { + PiNode piNode = (PiNode) object; + if (access.object() == object) { + access.asNode().replaceFirstInput(object, piNode.getOriginalNode()); + } + if (!(piNode.getGuard() instanceof GuardNode)) { + return; } - fixedAccess.setNullCheck(true); - LogicNode condition = guard.condition(); - guard.replaceAndDelete(fixedAccess); - if (condition.hasNoUsages()) { - GraphUtil.killWithUnusedFloatingInputs(condition); + } + metricImplicitNullCheck.increment(); + access.setGuard(null); + FixedAccessNode fixedAccess; + if (access instanceof FloatingAccessNode) { + FloatingAccessNode floatingAccessNode = (FloatingAccessNode) access; + MemoryNode lastLocationAccess = floatingAccessNode.getLastLocationAccess(); + fixedAccess = floatingAccessNode.asFixedNode(); + replaceCurrent(fixedAccess); + if (lastLocationAccess != null) { + // fixed accesses are not currently part of the memory graph + GraphUtil.tryKillUnused(lastLocationAccess.asNode()); } - nullGuarded.remove(fixedAccess.object()); + } else { + fixedAccess = (FixedAccessNode) access; } + fixedAccess.setNullCheck(true); + GuardNode guardNode = null; + if (guard instanceof GuardNode) { + guardNode = (GuardNode) guard; + } else { + PiNode piNode = (PiNode) guard; + guardNode = (GuardNode) piNode.getGuard(); + } + LogicNode condition = guardNode.condition(); + guardNode.replaceAndDelete(fixedAccess); + if (condition.hasNoUsages()) { + GraphUtil.killWithUnusedFloatingInputs(condition); + } + nullGuarded.remove(fixedAccess.object()); } }