From ff6190946c67a10d77dbad384e9bad076dd91bf4 Mon Sep 17 00:00:00 2001 From: "fschneider@chromium.org" Date: Fri, 4 Mar 2011 12:09:54 +0000 Subject: [PATCH] Reorganize code for range analysis and suppress unnecessary debug printing of unknown ranges. Review URL: http://codereview.chromium.org/6611020 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7060 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/hydrogen-instructions.cc | 132 ++++++++++++++++++++++++++----------------- src/hydrogen-instructions.h | 73 +++++++----------------- src/hydrogen.cc | 4 +- 3 files changed, 101 insertions(+), 108 deletions(-) diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index 49e5257..c2e5c8b 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -120,6 +120,44 @@ void Range::AddConstant(int32_t value) { } +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 @@ void HInstruction::PrintTo(StringStream* stream) { 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 @@ Range* HValue::InferRange() { } 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 @@ Range* HConstant::InferRange() { result->set_can_be_minus_zero(false); return result; } - return HInstruction::InferRange(); + return HValue::InferRange(); } @@ -784,7 +826,7 @@ Range* HAdd::InferRange() { res->set_can_be_minus_zero(m0); return res; } else { - return HArithmeticBinaryOperation::InferRange(); + return HValue::InferRange(); } } @@ -800,7 +842,7 @@ Range* HSub::InferRange() { res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero()); return res; } else { - return HArithmeticBinaryOperation::InferRange(); + return HValue::InferRange(); } } @@ -818,7 +860,7 @@ Range* HMul::InferRange() { res->set_can_be_minus_zero(m0); return res; } else { - return HArithmeticBinaryOperation::InferRange(); + return HValue::InferRange(); } } @@ -843,7 +885,7 @@ Range* HDiv::InferRange() { } return result; } else { - return HArithmeticBinaryOperation::InferRange(); + return HValue::InferRange(); } } @@ -860,7 +902,7 @@ Range* HMod::InferRange() { } return result; } else { - return HArithmeticBinaryOperation::InferRange(); + return HValue::InferRange(); } } @@ -1021,34 +1063,30 @@ void HBinaryOperation::PrintDataTo(StringStream* stream) { 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 @@ Range* HSar::InferRange() { 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 @@ Range* HShl::InferRange() { 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(); } diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 371bc4a..cc75354 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -190,81 +190,48 @@ class LChunkBuilder; class Range: public ZoneObject { public: - Range() : lower_(kMinInt), - upper_(kMaxInt), - next_(NULL), - can_be_minus_zero_(false) { } + Range() + : lower_(kMinInt), + upper_(kMaxInt), + next_(NULL), + can_be_minus_zero_(false) { } Range(int32_t lower, int32_t upper) - : lower_(lower), upper_(upper), next_(NULL), can_be_minus_zero_(false) { } + : lower_(lower), + upper_(upper), + next_(NULL), + can_be_minus_zero_(false) { } - bool IsInSmiRange() const { - return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue; - } - void KeepOrder(); - void Verify() const; int32_t upper() const { return upper_; } int32_t lower() const { return lower_; } Range* next() const { return next_; } Range* CopyClearLower() const { return new Range(kMinInt, upper_); } Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); } - void ClearLower() { lower_ = kMinInt; } - void ClearUpper() { upper_ = kMaxInt; } Range* Copy() const { return new Range(lower_, upper_); } - bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; } int32_t Mask() const; void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; } bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; } bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; } bool CanBeNegative() const { return lower_ < 0; } - bool Includes(int value) const { - return lower_ <= value && upper_ >= value; - } - - void Sar(int32_t value) { - int32_t bits = value & 0x1F; - lower_ = lower_ >> bits; - upper_ = upper_ >> bits; - set_can_be_minus_zero(false); - } - - void 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 Includes(int value) const { return lower_ <= value && upper_ >= value; } + bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; } + bool IsInSmiRange() const { + return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue; } - - // Adds a constant to the lower and upper bound of the range. - void AddConstant(int32_t value); + void KeepOrder(); + void Verify() const; void StackUpon(Range* other) { Intersect(other); next_ = other; } - void 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 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 Intersect(Range* other); + void Union(Range* other); - // Compute a new result range and return true, if the operation - // can overflow. + void AddConstant(int32_t value); + void Sar(int32_t value); + void Shl(int32_t value); bool AddAndCheckOverflow(Range* other); bool SubAndCheckOverflow(Range* other); bool MulAndCheckOverflow(Range* other); diff --git a/src/hydrogen.cc b/src/hydrogen.cc index e18b53e..6bd1a6b 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -867,8 +867,8 @@ void HRangeAnalysis::InferControlFlowRange(HTest* test, HBasicBlock* dest) { void HRangeAnalysis::InferControlFlowRange(Token::Value op, HValue* value, HValue* other) { - Range* range = other->range(); - if (range == NULL) range = new Range(); + Range temp_range; + Range* range = other->range() != NULL ? other->range() : &temp_range; Range* new_range = NULL; TraceRange("Control flow range infer %d %s %d\n", -- 2.7.4