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

Unified Diff: runtime/vm/intermediate_language.cc

Issue 10972003: Fix convergence issues in range analysis. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 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.cc
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 3faaeedc1789330d4dc67c1d02052dacc1b3703c..1daa3b1733a4e0a018a382be4653e155bda9edc1 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -1870,7 +1870,25 @@ void Environment::DeepCopyToOuter(Instruction* instr) const {
}
-bool Definition::InferRange() {
+RangeBoundary RangeBoundary::LowerBound() const {
+ if (IsConstant()) return *this;
+ if (symbol()->range() == NULL) return MinSmi();
+ return Add(symbol()->range()->min().LowerBound(),
+ RangeBoundary::FromConstant(offset_),
+ MinSmi());
+}
+
+
+RangeBoundary RangeBoundary::UpperBound() const {
+ if (IsConstant()) return *this;
+ if (symbol()->range() == NULL) return MaxSmi();
+ return Add(symbol()->range()->max().UpperBound(),
+ RangeBoundary::FromConstant(offset_),
+ MaxSmi());
+}
+
+
+bool Definition::InferRange(RangeOperator op) {
ASSERT(GetPropagatedCid() == kSmiCid); // Has meaning only for smis.
if (range_ == NULL) {
range_ = Range::Unknown();
@@ -1880,7 +1898,7 @@ bool Definition::InferRange() {
}
-bool ConstantInstr::InferRange() {
+bool ConstantInstr::InferRange(RangeOperator op) {
ASSERT(value_.IsSmi());
if (range_ == NULL) {
intptr_t value = Smi::Cast(value_).Value();
@@ -1892,25 +1910,7 @@ bool ConstantInstr::InferRange() {
}
-RangeBoundary RangeBoundary::LowerBound() const {
- if (IsConstant()) return *this;
- if (symbol()->range() == NULL) return MinSmi();
- return Add(symbol()->range()->min().LowerBound(),
- RangeBoundary::FromConstant(offset_),
- MinSmi());
-}
-
-
-RangeBoundary RangeBoundary::UpperBound() const {
- if (IsConstant()) return *this;
- if (symbol()->range() == NULL) return MaxSmi();
- return Add(symbol()->range()->max().UpperBound(),
- RangeBoundary::FromConstant(offset_),
- MaxSmi());
-}
-
-
-bool ConstraintInstr::InferRange() {
+bool ConstraintInstr::InferRange(RangeOperator op) {
Range* value_range = value()->definition()->range();
// Compute intersection of constraint and value ranges.
@@ -1922,15 +1922,13 @@ bool ConstraintInstr::InferRange() {
}
-bool PhiInstr::InferRange() {
+bool PhiInstr::InferRange(RangeOperator op) {
RangeBoundary new_min;
RangeBoundary new_max;
- bool has_inputs_without_range = false;
for (intptr_t i = 0; i < InputCount(); i++) {
Range* input_range = InputAt(i)->definition()->range();
if (input_range == NULL) {
- has_inputs_without_range = true;
continue;
}
@@ -1949,23 +1947,25 @@ bool PhiInstr::InferRange() {
ASSERT(new_min.IsUnknown() == new_max.IsUnknown());
if (new_min.IsUnknown()) {
- ASSERT(range_ == NULL);
+ range_ = Range::Unknown();
return false;
}
- if ((range_ != NULL) && !has_inputs_without_range_) {
- // If phi's range is growing widen it in the direction of growth to
- // speedup convergence.
+ if (op == Definition::kRangeWiden) {
+ // Apply widening operator.
new_min = RangeBoundary::WidenMin(range_->min(), new_min);
new_max = RangeBoundary::WidenMax(range_->max(), new_max);
+ } else if (op == Definition::kRangeNarrow) {
+ // Apply narrowing operator.
+ new_min = RangeBoundary::NarrowMin(range_->min(), new_min);
+ new_max = RangeBoundary::NarrowMax(range_->max(), new_max);
}
- has_inputs_without_range_ = has_inputs_without_range;
return Range::Update(&range_, new_min, new_max);
}
-bool BinarySmiOpInstr::InferRange() {
+bool BinarySmiOpInstr::InferRange(RangeOperator op) {
Range* left_range = left()->definition()->range();
Range* right_range = right()->definition()->range();
@@ -2010,6 +2010,12 @@ bool BinarySmiOpInstr::InferRange() {
ASSERT(!new_min.IsUnknown() && !new_max.IsUnknown());
set_overflow(new_min.Overflowed() || new_max.Overflowed());
+
+ if (op == Definition::kRangeNarrow) {
+ new_min = new_min.Clamp();
+ new_max = new_max.Clamp();
+ }
+
return Range::Update(&range_, new_min, new_max);
}

Powered by Google App Engine
This is Rietveld 408576698