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(); |
} |