Index: runtime/vm/intermediate_language.h |
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h |
index 67aebb069c5ab492d7069094f2c84e5a161b4725..d1f245321166f5de428cca7d621e51f09f407fa8 100644 |
--- a/runtime/vm/intermediate_language.h |
+++ b/runtime/vm/intermediate_language.h |
@@ -2507,6 +2507,9 @@ class RangeBoundary : public ValueObject { |
return *this; |
} |
+ static const intptr_t kMin = kIntptrMin; |
+ static const intptr_t kMax = kIntptrMax; |
+ |
static RangeBoundary FromConstant(intptr_t val) { |
return RangeBoundary(kConstant, val, 0); |
} |
@@ -2535,17 +2538,16 @@ class RangeBoundary : public ValueObject { |
bool Overflowed() const { |
// If the value is a constant outside of Smi range or infinity. |
- return (IsConstant() && !Smi::IsValid(value())) || IsInfinity(); |
+ return (IsConstant() && !Smi::IsValid(Value())) || IsInfinity(); |
} |
RangeBoundary Clamp() const { |
- if (IsNegativeInfinity()) { |
- return MinSmi(); |
- } else if (IsPositiveInfinity()) { |
- return MaxSmi(); |
- } else if (IsConstant()) { |
- if (value() < Smi::kMinValue) return MinSmi(); |
- if (value() > Smi::kMaxValue) return MaxSmi(); |
+ if (IsInfinity()) { |
+ return *this; |
+ } |
+ if (IsConstant()) { |
+ if (Value() < Smi::kMinValue) return MinSmi(); |
+ if (Value() > Smi::kMaxValue) return MaxSmi(); |
} |
return *this; |
} |
@@ -2558,12 +2560,12 @@ class RangeBoundary : public ValueObject { |
bool IsInfinity() const { |
return IsNegativeInfinity() || IsPositiveInfinity(); |
} |
- |
- intptr_t value() const { |
- ASSERT(IsConstant()); |
- return value_; |
+ bool IsConstantOrInfinity() const { |
+ return IsConstant() || IsInfinity(); |
} |
+ intptr_t Value() const; |
+ |
Definition* symbol() const { |
ASSERT(IsSymbol()); |
return reinterpret_cast<Definition*>(value_); |
@@ -2581,27 +2583,13 @@ class RangeBoundary : public ValueObject { |
static RangeBoundary Add(const RangeBoundary& a, |
const RangeBoundary& b, |
- const RangeBoundary& overflow) { |
- ASSERT(a.IsConstant() && b.IsConstant()); |
- |
- intptr_t result = a.value() + b.value(); |
- if (!Smi::IsValid(result)) { |
- return overflow; |
- } |
- return RangeBoundary::FromConstant(result); |
- } |
+ const RangeBoundary& overflow); |
static RangeBoundary Sub(const RangeBoundary& a, |
const RangeBoundary& b, |
- const RangeBoundary& overflow) { |
- ASSERT(a.IsConstant() && b.IsConstant()); |
+ const RangeBoundary& overflow); |
- intptr_t result = a.value() - b.value(); |
- if (!Smi::IsValid(result)) { |
- return overflow; |
- } |
- return RangeBoundary::FromConstant(result); |
- } |
+ bool Equals(const RangeBoundary& other) const; |
private: |
RangeBoundary(Kind kind, intptr_t value, intptr_t offset) |
@@ -2658,6 +2646,28 @@ class Range : public ZoneAllocated { |
bool IsUnsatisfiable() const; |
+ // Returns true if range is at or below the minimum smi value. |
+ static bool IsSmiMinimumOrUnderflow(const Range* range); |
+ |
+ // Returns true if range is at or above the maximum smi value. |
+ static bool IsSmiMaximumOrOverflow(const Range* range); |
+ |
+ // Both the a and b ranges are >= 0. |
+ static bool OnlyPositiveOrZero(const Range& a, const Range& b); |
+ |
+ // Both the a and b ranges are <= 0. |
+ static bool OnlyNegativeOrZero(const Range& a, const Range& b); |
+ |
+ // Return the maximum absolute value included in range. |
+ static int64_t ConstantAbsMax(const Range* range); |
+ |
+ static Range* BinaryOp(const Token::Kind op, |
+ const RangeBoundary& left_min, |
+ const RangeBoundary& left_max, |
+ const Range* left_range, |
+ const Range* right_range, |
+ const Range* original_range); |
+ |
private: |
RangeBoundary min_; |
RangeBoundary max_; |