| Index: src/hydrogen-instructions.cc
|
| ===================================================================
|
| --- src/hydrogen-instructions.cc (revision 15070)
|
| +++ src/hydrogen-instructions.cc (working copy)
|
| @@ -285,16 +285,8 @@
|
| }
|
|
|
|
|
| -int32_t Range::Mask() const {
|
| - if (lower_ == upper_) return lower_;
|
| - if (lower_ >= 0) {
|
| - int32_t res = 1;
|
| - while (res < upper_) {
|
| - res = (res << 1) | 1;
|
| - }
|
| - return res;
|
| - }
|
| - return 0xffffffff;
|
| +void Range::ToBitRange(BitRange* bits) const {
|
| + BitRange::SetFromRange(bits, lower_, upper_);
|
| }
|
|
|
|
|
| @@ -2363,50 +2355,38 @@
|
|
|
|
|
| Range* HBitwise::InferRange(Zone* zone) {
|
| - if (op() == Token::BIT_XOR) {
|
| - if (left()->HasRange() && right()->HasRange()) {
|
| - // The maximum value has the high bit, and all bits below, set:
|
| - // (1 << high) - 1.
|
| - // If the range can be negative, the minimum int is a negative number with
|
| - // the high bit, and all bits below, unset:
|
| - // -(1 << high).
|
| - // If it cannot be negative, conservatively choose 0 as minimum int.
|
| - int64_t left_upper = left()->range()->upper();
|
| - int64_t left_lower = left()->range()->lower();
|
| - int64_t right_upper = right()->range()->upper();
|
| - int64_t right_lower = right()->range()->lower();
|
| + if (representation().IsInteger32()) {
|
| + BitRange left_bits, right_bits;
|
|
|
| - if (left_upper < 0) left_upper = ~left_upper;
|
| - if (left_lower < 0) left_lower = ~left_lower;
|
| - if (right_upper < 0) right_upper = ~right_upper;
|
| - if (right_lower < 0) right_lower = ~right_lower;
|
| + if (left()->HasRange()) {
|
| + left()->range()->ToBitRange(&left_bits);
|
| + }
|
|
|
| - int high = MostSignificantBit(
|
| - static_cast<uint32_t>(
|
| - left_upper | left_lower | right_upper | right_lower));
|
| + if (right()->HasRange()) {
|
| + right()->range()->ToBitRange(&right_bits);
|
| + }
|
|
|
| - int64_t limit = 1;
|
| - limit <<= high;
|
| - int32_t min = (left()->range()->CanBeNegative() ||
|
| - right()->range()->CanBeNegative())
|
| - ? static_cast<int32_t>(-limit) : 0;
|
| - return new(zone) Range(min, static_cast<int32_t>(limit - 1));
|
| + BitRange result;
|
| + switch (op()) {
|
| + case Token::BIT_AND:
|
| + result = BitRange::And(left_bits, right_bits);
|
| + break;
|
| + case Token::BIT_OR:
|
| + result = BitRange::Or(left_bits, right_bits);
|
| + break;
|
| + case Token::BIT_XOR:
|
| + result = BitRange::Xor(left_bits, right_bits);
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| }
|
| +
|
| + int32_t lower = kMaxInt, upper = kMinInt; // 'empty' range.
|
| + result.ExtendRange(&lower, &upper);
|
| + return new(zone) Range(lower, upper);
|
| + } else {
|
| return HValue::InferRange(zone);
|
| }
|
| - const int32_t kDefaultMask = static_cast<int32_t>(0xffffffff);
|
| - int32_t left_mask = (left()->range() != NULL)
|
| - ? left()->range()->Mask()
|
| - : kDefaultMask;
|
| - int32_t right_mask = (right()->range() != NULL)
|
| - ? right()->range()->Mask()
|
| - : kDefaultMask;
|
| - int32_t result_mask = (op() == Token::BIT_AND)
|
| - ? left_mask & right_mask
|
| - : left_mask | right_mask;
|
| - return (result_mask >= 0)
|
| - ? new(zone) Range(0, result_mask)
|
| - : HValue::InferRange(zone);
|
| }
|
|
|
|
|
|
|