# HG changeset patch # User Lukas Stadler # Date 1403525581 -7200 # Node ID 866438171d1dea43b7f5596a9c7a2eb27988571d # Parent d3f949fbdf3074ec6cd2fa666e445966e7317b58 infer stamps for BitScanForwardNode and BitScanReverseNode diff -r d3f949fbdf30 -r 866438171d1d graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java Mon Jun 23 14:11:54 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java Mon Jun 23 14:13:01 2014 +0200 @@ -24,29 +24,34 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; -public class BitScanForwardNode extends UnaryNode implements LIRLowerable, Canonicalizable { +public class BitScanForwardNode extends UnaryNode implements LIRLowerable { public BitScanForwardNode(ValueNode value) { super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value); + assert value.getKind() == Kind.Int || value.getKind() == Kind.Long; } @Override - public Node canonical(CanonicalizerTool tool) { - if (getValue().isConstant()) { - Constant c = getValue().asConstant(); - if (c.getKind() == Kind.Int) { - return ConstantNode.forInt(Integer.numberOfTrailingZeros(c.asInt()), graph()); - } else if (c.getKind() == Kind.Long) { - return ConstantNode.forInt(Long.numberOfTrailingZeros(c.asLong()), graph()); - } + public boolean inferStamp() { + IntegerStamp valueStamp = (IntegerStamp) getValue().stamp(); + int min; + int max; + long mask = IntegerStamp.defaultMask(valueStamp.getBits()); + int firstAlwaysSetBit = scan(valueStamp.downMask() & mask); + if (firstAlwaysSetBit == -1) { + int lastMaybeSetBit = BitScanReverseNode.scan(valueStamp.upMask() & mask); + min = -1; + max = lastMaybeSetBit; + } else { + int firstMaybeSetBit = scan(valueStamp.upMask() & mask); + min = firstMaybeSetBit; + max = firstAlwaysSetBit; } - return this; + return updateStamp(StampFactory.forInteger(Kind.Int, min, max)); } @NodeIntrinsic diff -r d3f949fbdf30 -r 866438171d1d graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java Mon Jun 23 14:11:54 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java Mon Jun 23 14:13:01 2014 +0200 @@ -24,29 +24,32 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; -public class BitScanReverseNode extends UnaryNode implements LIRLowerable, Canonicalizable { +public class BitScanReverseNode extends UnaryNode implements LIRLowerable { public BitScanReverseNode(ValueNode value) { super(StampFactory.forInteger(Kind.Int, 0, ((PrimitiveStamp) value.stamp()).getBits()), value); + assert value.getKind() == Kind.Int || value.getKind() == Kind.Long; } @Override - public Node canonical(CanonicalizerTool tool) { - if (getValue().isConstant()) { - Constant c = getValue().asConstant(); - if (c.getKind() == Kind.Int) { - return ConstantNode.forInt(31 - Integer.numberOfLeadingZeros(c.asInt()), graph()); - } else if (c.getKind() == Kind.Long) { - return ConstantNode.forInt(63 - Long.numberOfLeadingZeros(c.asLong()), graph()); - } + public boolean inferStamp() { + IntegerStamp valueStamp = (IntegerStamp) getValue().stamp(); + int min; + int max; + long mask = IntegerStamp.defaultMask(valueStamp.getBits()); + int lastAlwaysSetBit = scan(valueStamp.downMask() & mask); + if (lastAlwaysSetBit == -1) { + min = -1; + } else { + min = lastAlwaysSetBit; } - return this; + int lastMaybeSetBit = scan(valueStamp.upMask() & mask); + max = lastMaybeSetBit; + return updateStamp(StampFactory.forInteger(Kind.Int, min, max)); } @NodeIntrinsic