# HG changeset patch # User Tom Rodriguez # Date 1445725678 25200 # Node ID 2fe4e3511d9792d79ec81b6eaef3a6067c6b0143 # Parent 39b9743b82741a10c1be9bfb921597f4b083bc0f Look into expressions when performing conditional elimination diff -r 39b9743b8274 -r 2fe4e3511d97 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java Sat Oct 24 12:18:09 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java Sat Oct 24 15:27:58 2015 -0700 @@ -86,6 +86,10 @@ return null; } + public Stamp tryFoldStamp(Stamp xStamp, Stamp yStamp) { + return getOp(getX(), getY()).foldStamp(xStamp, yStamp); + } + @Override public boolean inferStamp() { return updateStamp(getOp(getX(), getY()).foldStamp(getX().stamp(), getY().stamp())); diff -r 39b9743b8274 -r 2fe4e3511d97 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java Sat Oct 24 12:18:09 2015 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java Sat Oct 24 15:27:58 2015 -0700 @@ -62,6 +62,7 @@ import com.oracle.graal.nodes.StructuredGraph; import com.oracle.graal.nodes.UnaryOpLogicNode; import com.oracle.graal.nodes.ValueNode; +import com.oracle.graal.nodes.calc.BinaryArithmeticNode; import com.oracle.graal.nodes.cfg.Block; import com.oracle.graal.nodes.cfg.ControlFlowGraph; import com.oracle.graal.nodes.extended.GuardingNode; @@ -416,6 +417,25 @@ return rewireGuards(infoElement.getGuard(), result.toBoolean(), rewireGuardFunction); } } + /* + * For complex expressions involving constants, see if it's possible to fold the + * tests by using stamps one level up in the expression. For instance, (x + n < y) + * might fold if something is known about x and y is a constant. + */ + if (x instanceof BinaryArithmeticNode && y.isConstant()) { + BinaryArithmeticNode binary = (BinaryArithmeticNode) x; + for (InfoElement infoElement : getInfoElements(binary.getX())) { + Stamp newStampX = binary.tryFoldStamp(infoElement.getStamp(), binary.getY().stamp()); + TriState result = binaryOpLogicNode.tryFold(newStampX, y.stamp()); + if (result.isKnown()) { + return rewireGuards(infoElement.getGuard(), result.toBoolean(), rewireGuardFunction); + } + } + /* + * In all the interesting cases binary.getY() seems to be a constant so it's + * doesn't seem worth checking that case here.s + */ + } } else if (node instanceof ShortCircuitOrNode) { final ShortCircuitOrNode shortCircuitOrNode = (ShortCircuitOrNode) node; if (this.loopExits.isEmpty()) {