Mercurial > hg > graal-compiler
changeset 23006:9551cbb2b317
Canonicalize x - y < 0 to x < y when possible
author | Tom Rodriguez <tom.rodriguez@oracle.com> |
---|---|
date | Tue, 17 Nov 2015 12:36:33 -0800 |
parents | 6ec03d3b8369 |
children | 029b961c2668 |
files | graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java |
diffstat | 1 files changed, 26 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Tue Nov 17 19:02:13 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Tue Nov 17 12:36:33 2015 -0800 @@ -83,6 +83,20 @@ return this; } + public static boolean subtractMayUnderflow(long x, long y, long minValue) { + long r = x - y; + // HD 2-12 Overflow iff the arguments have different signs and + // the sign of the result is different than the sign of x + return (((x ^ y) & (x ^ r)) < 0) || r <= minValue; + } + + public static boolean subtractMayOverflow(long x, long y, long maxValue) { + long r = x - y; + // HD 2-12 Overflow iff the arguments have different signs and + // the sign of the result is different than the sign of x + return (((x ^ y) & (x ^ r)) < 0) || r > maxValue; + } + @Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { ValueNode result = super.canonical(tool, forX, forY); @@ -98,6 +112,18 @@ return new IntegerBelowNode(forX, forY); } } + if (forY.isConstant() && forY.asConstant().isDefaultForKind() && forX instanceof SubNode) { + // (x - y) < 0 when x - y is known not to underflow == x < y + SubNode sub = (SubNode) forX; + IntegerStamp xStamp = (IntegerStamp) sub.getX().stamp(); + IntegerStamp yStamp = (IntegerStamp) sub.getY().stamp(); + long minValue = CodeUtil.minValue(xStamp.getBits()); + long maxValue = CodeUtil.maxValue(xStamp.getBits()); + + if (!subtractMayUnderflow(xStamp.lowerBound(), yStamp.upperBound(), minValue) && !subtractMayOverflow(xStamp.upperBound(), yStamp.lowerBound(), maxValue)) { + return new IntegerLessThanNode(sub.getX(), sub.getY()); + } + } return this; }