| Index: src/hydrogen-instructions.cc
|
| ===================================================================
|
| --- src/hydrogen-instructions.cc (revision 7046)
|
| +++ src/hydrogen-instructions.cc (working copy)
|
| @@ -120,6 +120,44 @@
|
| }
|
|
|
|
|
| +void Range::Intersect(Range* other) {
|
| + upper_ = Min(upper_, other->upper_);
|
| + lower_ = Max(lower_, other->lower_);
|
| + bool b = CanBeMinusZero() && other->CanBeMinusZero();
|
| + set_can_be_minus_zero(b);
|
| +}
|
| +
|
| +
|
| +void Range::Union(Range* other) {
|
| + upper_ = Max(upper_, other->upper_);
|
| + lower_ = Min(lower_, other->lower_);
|
| + bool b = CanBeMinusZero() || other->CanBeMinusZero();
|
| + set_can_be_minus_zero(b);
|
| +}
|
| +
|
| +
|
| +void Range::Sar(int32_t value) {
|
| + int32_t bits = value & 0x1F;
|
| + lower_ = lower_ >> bits;
|
| + upper_ = upper_ >> bits;
|
| + set_can_be_minus_zero(false);
|
| +}
|
| +
|
| +
|
| +void Range::Shl(int32_t value) {
|
| + int32_t bits = value & 0x1F;
|
| + int old_lower = lower_;
|
| + int old_upper = upper_;
|
| + lower_ = lower_ << bits;
|
| + upper_ = upper_ << bits;
|
| + if (old_lower != lower_ >> bits || old_upper != upper_ >> bits) {
|
| + upper_ = kMaxInt;
|
| + lower_ = kMinInt;
|
| + }
|
| + set_can_be_minus_zero(false);
|
| +}
|
| +
|
| +
|
| bool Range::AddAndCheckOverflow(Range* other) {
|
| bool may_overflow = false;
|
| lower_ = AddWithoutOverflow(lower_, other->lower(), &may_overflow);
|
| @@ -415,7 +453,9 @@
|
| stream->Add(" ");
|
| PrintDataTo(stream);
|
|
|
| - if (range() != NULL) {
|
| + if (range() != NULL &&
|
| + !range()->IsMostGeneric() &&
|
| + !range()->CanBeMinusZero()) {
|
| stream->Add(" range[%d,%d,m0=%d]",
|
| range()->lower(),
|
| range()->upper(),
|
| @@ -739,6 +779,8 @@
|
| } else if (representation().IsNone()) {
|
| return NULL;
|
| } else {
|
| + // Untagged integer32 cannot be -0 and we don't compute ranges for
|
| + // untagged doubles.
|
| return new Range();
|
| }
|
| }
|
| @@ -750,7 +792,7 @@
|
| result->set_can_be_minus_zero(false);
|
| return result;
|
| }
|
| - return HInstruction::InferRange();
|
| + return HValue::InferRange();
|
| }
|
|
|
|
|
| @@ -784,7 +826,7 @@
|
| res->set_can_be_minus_zero(m0);
|
| return res;
|
| } else {
|
| - return HArithmeticBinaryOperation::InferRange();
|
| + return HValue::InferRange();
|
| }
|
| }
|
|
|
| @@ -800,7 +842,7 @@
|
| res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero());
|
| return res;
|
| } else {
|
| - return HArithmeticBinaryOperation::InferRange();
|
| + return HValue::InferRange();
|
| }
|
| }
|
|
|
| @@ -818,7 +860,7 @@
|
| res->set_can_be_minus_zero(m0);
|
| return res;
|
| } else {
|
| - return HArithmeticBinaryOperation::InferRange();
|
| + return HValue::InferRange();
|
| }
|
| }
|
|
|
| @@ -843,7 +885,7 @@
|
| }
|
| return result;
|
| } else {
|
| - return HArithmeticBinaryOperation::InferRange();
|
| + return HValue::InferRange();
|
| }
|
| }
|
|
|
| @@ -860,7 +902,7 @@
|
| }
|
| return result;
|
| } else {
|
| - return HArithmeticBinaryOperation::InferRange();
|
| + return HValue::InferRange();
|
| }
|
| }
|
|
|
| @@ -1021,34 +1063,30 @@
|
|
|
|
|
| Range* HBitAnd::InferRange() {
|
| - Range* a = left()->range();
|
| - Range* b = right()->range();
|
| - int32_t a_mask = 0xffffffff;
|
| - int32_t b_mask = 0xffffffff;
|
| - if (a != NULL) a_mask = a->Mask();
|
| - if (b != NULL) b_mask = b->Mask();
|
| - int32_t result_mask = a_mask & b_mask;
|
| - if (result_mask >= 0) {
|
| - return new Range(0, result_mask);
|
| - } else {
|
| - return HBinaryOperation::InferRange();
|
| - }
|
| + int32_t left_mask = (left()->range() != NULL)
|
| + ? left()->range()->Mask()
|
| + : 0xffffffff;
|
| + int32_t right_mask = (right()->range() != NULL)
|
| + ? right()->range()->Mask()
|
| + : 0xffffffff;
|
| + int32_t result_mask = left_mask & right_mask;
|
| + return (result_mask >= 0)
|
| + ? new Range(0, result_mask)
|
| + : HValue::InferRange();
|
| }
|
|
|
|
|
| Range* HBitOr::InferRange() {
|
| - Range* a = left()->range();
|
| - Range* b = right()->range();
|
| - int32_t a_mask = 0xffffffff;
|
| - int32_t b_mask = 0xffffffff;
|
| - if (a != NULL) a_mask = a->Mask();
|
| - if (b != NULL) b_mask = b->Mask();
|
| - int32_t result_mask = a_mask | b_mask;
|
| - if (result_mask >= 0) {
|
| - return new Range(0, result_mask);
|
| - } else {
|
| - return HBinaryOperation::InferRange();
|
| - }
|
| + int32_t left_mask = (left()->range() != NULL)
|
| + ? left()->range()->Mask()
|
| + : 0xffffffff;
|
| + int32_t right_mask = (right()->range() != NULL)
|
| + ? right()->range()->Mask()
|
| + : 0xffffffff;
|
| + int32_t result_mask = left_mask | right_mask;
|
| + return (result_mask >= 0)
|
| + ? new Range(0, result_mask)
|
| + : HValue::InferRange();
|
| }
|
|
|
|
|
| @@ -1056,20 +1094,14 @@
|
| if (right()->IsConstant()) {
|
| HConstant* c = HConstant::cast(right());
|
| if (c->HasInteger32Value()) {
|
| - int32_t val = c->Integer32Value();
|
| - Range* result = NULL;
|
| - Range* left_range = left()->range();
|
| - if (left_range == NULL) {
|
| - result = new Range();
|
| - } else {
|
| - result = left_range->Copy();
|
| - }
|
| - result->Sar(val);
|
| + Range* result = (left()->range() != NULL)
|
| + ? left()->range()->Copy()
|
| + : new Range();
|
| + result->Sar(c->Integer32Value());
|
| return result;
|
| }
|
| }
|
| -
|
| - return HBinaryOperation::InferRange();
|
| + return HValue::InferRange();
|
| }
|
|
|
|
|
| @@ -1077,20 +1109,14 @@
|
| if (right()->IsConstant()) {
|
| HConstant* c = HConstant::cast(right());
|
| if (c->HasInteger32Value()) {
|
| - int32_t val = c->Integer32Value();
|
| - Range* result = NULL;
|
| - Range* left_range = left()->range();
|
| - if (left_range == NULL) {
|
| - result = new Range();
|
| - } else {
|
| - result = left_range->Copy();
|
| - }
|
| - result->Shl(val);
|
| + Range* result = (left()->range() != NULL)
|
| + ? left()->range()->Copy()
|
| + : new Range();
|
| + result->Shl(c->Integer32Value());
|
| return result;
|
| }
|
| }
|
| -
|
| - return HBinaryOperation::InferRange();
|
| + return HValue::InferRange();
|
| }
|
|
|
|
|
|
|