Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(386)

Unified Diff: runtime/vm/intermediate_language.h

Issue 328503003: Extend Range analysis to 64-bit range and mint operations (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/intermediate_language.h
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index d6bb77b5201ee8bca016a7ecd9c6eeadb1c85a01..03af68a6fbeea719ac55e6f885d6a06038e95fe4 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -2511,24 +2511,33 @@ class RangeBoundary : public ValueObject {
return *this;
}
+ static const intptr_t kMin = kIntptrMin;
+ static const intptr_t kMax = kIntptrMax;
+
+ // Construct a RangeBoundary for a constant value.
static RangeBoundary FromConstant(intptr_t val) {
return RangeBoundary(kConstant, val, 0);
}
+ // Construct a RangeBoundary for -inf.
static RangeBoundary NegativeInfinity() {
return RangeBoundary(kNegativeInfinity, 0, 0);
}
+ // Construct a RangeBoundary for +inf.
static RangeBoundary PositiveInfinity() {
return RangeBoundary(kPositiveInfinity, 0, 0);
}
+ // Construct a RangeBoundary from a definition and offset.
static RangeBoundary FromDefinition(Definition* defn, intptr_t offs = 0);
+ // Construct a RangeBoundary for the constant MinSmi value.
static RangeBoundary MinSmi() {
return FromConstant(Smi::kMinValue);
}
+ // Construct a RangeBoundary for the constant MaxSmi value.
static RangeBoundary MaxSmi() {
return FromConstant(Smi::kMaxValue);
}
@@ -2537,23 +2546,34 @@ class RangeBoundary : public ValueObject {
static RangeBoundary Max(RangeBoundary a, RangeBoundary b);
+ // Returns true when this is a constant that is outside of range or is +/-inf.
bool Overflowed() const {
- // If the value is a constant outside of Smi range or infinity.
- return (IsConstant() && !Smi::IsValid(value())) || IsInfinity();
+ // TODO(johnmccutchan): Support overflow testing to non-smi ranges.
+ return (IsConstant() && !Smi::IsValid(ConstantValue())) || IsInfinity();
}
+ // Clamps this into a representable constant or symbol RangeBoundary.
+ // +/- infinity are clamped to MinSmi/MaxSmi.
RangeBoundary Clamp() const {
+ // TODO(johnmccutchan): Support clamping to non-smi ranges.
if (IsNegativeInfinity()) {
return MinSmi();
- } else if (IsPositiveInfinity()) {
+ }
+ if (IsPositiveInfinity()) {
return MaxSmi();
- } else if (IsConstant()) {
- if (value() < Smi::kMinValue) return MinSmi();
- if (value() > Smi::kMaxValue) return MaxSmi();
+ }
+ if (IsConstant()) {
+ if (ConstantValue() < Smi::kMinValue) return MinSmi();
+ if (ConstantValue() > Smi::kMaxValue) return MaxSmi();
}
return *this;
}
+ intptr_t kind() const {
+ return kind_;
+ }
+
+ // Kind tests.
bool IsUnknown() const { return kind_ == kUnknown; }
bool IsConstant() const { return kind_ == kConstant; }
bool IsSymbol() const { return kind_ == kSymbol; }
@@ -2562,22 +2582,34 @@ class RangeBoundary : public ValueObject {
bool IsInfinity() const {
return IsNegativeInfinity() || IsPositiveInfinity();
}
-
- intptr_t value() const {
- ASSERT(IsConstant());
- return value_;
+ bool IsConstantOrInfinity() const {
+ return IsConstant() || IsInfinity();
}
+ // Returns the value of a kConstant RangeBoundary.
+ intptr_t ConstantValue() const;
+
+ // Returns the Definition associated with a kSymbol RangeBoundary.
Definition* symbol() const {
ASSERT(IsSymbol());
return reinterpret_cast<Definition*>(value_);
}
+ // Offset from symbol.
intptr_t offset() const {
return offset_;
}
+ // Computes the LowerBound of this. Three cases:
+ // IsInfinity() -> NegativeInfinity().
+ // IsConstant() -> value().
+ // IsSymbol() -> lower bound computed from definition + offset.
RangeBoundary LowerBound() const;
+
+ // Computes the UpperBound of this. Three cases:
+ // IsInfinity() -> PositiveInfinity().
+ // IsConstant() -> value().
+ // IsSymbol() -> upper bound computed from definition + offset.
RangeBoundary UpperBound() const;
void PrintTo(BufferFormatter* f) const;
@@ -2585,27 +2617,30 @@ 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);
+
+ // Attempts to calculate a + b when:
+ // a is a symbol and b is a constant OR
+ // a is a constant and b is a symbol
+ // returns true if it succeeds, output is in result.
+ static bool SymbolicAdd(const RangeBoundary& a,
+ const RangeBoundary& b,
+ RangeBoundary* result);
+
+ // Attempts to calculate a - b when:
+ // a is a symbol and b is a constant
+ // returns true if it succeeds, output is in result.
+ static bool SymbolicSub(const RangeBoundary& a,
+ const RangeBoundary& b,
+ RangeBoundary* result);
+
+ bool Equals(const RangeBoundary& other) const;
+
- intptr_t result = a.value() - b.value();
- if (!Smi::IsValid(result)) {
- return overflow;
- }
- return RangeBoundary::FromConstant(result);
- }
private:
RangeBoundary(Kind kind, intptr_t value, intptr_t offset)
@@ -2654,6 +2689,9 @@ class Range : public ZoneAllocated {
// [-inf, val].
bool OnlyLessThanOrEqualTo(intptr_t val) const;
+ // [val, +inf].
+ bool OnlyGreaterThanOrEqualTo(intptr_t val) const;
+
// Inclusive.
bool IsWithin(intptr_t min_int, intptr_t max_int) const;
@@ -2662,6 +2700,28 @@ class Range : public ZoneAllocated {
bool IsUnsatisfiable() const;
+ // Returns true if range is NULL or includes -inf.
+ static bool IncludesNegativeInfinity(const Range* range);
+
+ // Returns true if range is NULL or includes +inf.
+ static bool IncludesPositiveInfinity(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_;

Powered by Google App Engine
This is Rietveld 408576698