From 76193749791eac9032f47db2f04efd78c0e120a9 Mon Sep 17 00:00:00 2001 From: bmeurer Date: Wed, 21 Jan 2015 21:33:23 -0800 Subject: [PATCH] Revert of Steps towards unification of number bitset and range types. (patchset #4 id:60001 of https://codereview.chromium.org/837723006/) Reason for revert: Breaks test-types/Maybe, i.e. out/Release/cctest --random-seed=-707413401 test-types/Maybe started failing afterwards Original issue's description: > Steps towards unification of number bitset and range types. > > - New invariant on union types: if the union has a range then the number > bits in the bitset must be cleared. > > - Various tweaks in intersection and union to satisfy the invariant. > > - Exposed and used representation bits in range types (and the Limits > helper class). > > - Implemented Glb for ranges so that the Is predicate handles > ranges correctly. > > - Change typer weakening so that it does not rely on GetRange. > However, the code still seems to be a bit fragile. > > - Removed the Smi types from the type system core, instead introduced > Signed31, Unsigned30 and created constructors for Small(Un)Signed > that point to the right type for the architecture. > > - Punched a hole in the config to be able to get to the isolate so > that it is possible to allocate heap numbers for newly created > ranges. > > Patch by jarin@chromium.prg, original review here: > https://codereview.chromium.org/795713003/ > > TBR=jarin@chromium.org > BUG= > > Committed: https://crrev.com/2764fd8d1a266a9136c987c2483492113b0c8d80 > Cr-Commit-Position: refs/heads/master@{#26197} TBR=jkummerow@chromium.org,rossberg@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG= Review URL: https://codereview.chromium.org/868583002 Cr-Commit-Position: refs/heads/master@{#26207} --- src/compiler/change-lowering.cc | 2 +- src/compiler/typer.cc | 77 ++-- src/types-inl.h | 19 - src/types.cc | 409 +++++---------------- src/types.h | 144 ++++---- test/cctest/compiler/test-js-typed-lowering.cc | 32 +- test/cctest/test-types.cc | 71 ++-- test/cctest/types-fuzz.h | 5 - .../unittests/compiler/change-lowering-unittest.cc | 2 +- .../compiler/js-builtin-reducer-unittest.cc | 10 +- 10 files changed, 250 insertions(+), 521 deletions(-) diff --git a/src/compiler/change-lowering.cc b/src/compiler/change-lowering.cc index 93faf0f..2b369d9 100644 --- a/src/compiler/change-lowering.cc +++ b/src/compiler/change-lowering.cc @@ -163,7 +163,7 @@ Reduction ChangeLowering::ChangeInt32ToTagged(Node* value, Node* control) { machine()->Word64Shl(), graph()->NewNode(machine()->ChangeInt32ToInt64(), value), SmiShiftBitsConstant())); - } else if (NodeProperties::GetBounds(value).upper->Is(Type::Signed31())) { + } else if (NodeProperties::GetBounds(value).upper->Is(Type::SignedSmall())) { return Replace( graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant())); } diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc index 3c40fd9..737dffa 100644 --- a/src/compiler/typer.cc +++ b/src/compiler/typer.cc @@ -888,12 +888,12 @@ Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) { double rmax = rhs->Max(); if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) { // Xor-ing negative or non-negative values results in a non-negative value. - return Type::Unsigned31(); + return Type::NonNegativeSigned32(); } if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) { // Xor-ing a negative and a non-negative value results in a negative value. // TODO(jarin) Use a range here. - return Type::Negative32(); + return Type::NegativeSigned32(); } return Type::Signed32(); } @@ -1258,54 +1258,43 @@ Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) { // in the graph. In the current implementation, we are // increasing the limits to the closest power of two. Type* Typer::Visitor::Weaken(Type* current_type, Type* previous_type) { - // If the types have nothing to do with integers, return the types. - if (!current_type->Maybe(typer_->integer) || - !previous_type->Maybe(typer_->integer)) { - return current_type; - } - - Type* previous_number = - Type::Intersect(previous_type, typer_->integer, zone()); - Type* current_number = Type::Intersect(current_type, typer_->integer, zone()); - if (!current_number->IsRange() || !previous_number->IsRange()) { - return current_type; - } - - Type::RangeType* previous = previous_number->AsRange(); - Type::RangeType* current = current_number->AsRange(); - - double current_min = current->Min()->Number(); - Handle new_min = current->Min(); - - // Find the closest lower entry in the list of allowed - // minima (or negative infinity if there is no such entry). - if (current_min != previous->Min()->Number()) { - new_min = typer_->integer->AsRange()->Min(); - for (const auto val : typer_->weaken_min_limits_) { - if (val->Number() <= current_min) { - new_min = val; - break; + Type::RangeType* previous = previous_type->GetRange(); + Type::RangeType* current = current_type->GetRange(); + if (previous != NULL && current != NULL) { + double current_min = current->Min()->Number(); + Handle new_min = current->Min(); + + // Find the closest lower entry in the list of allowed + // minima (or negative infinity if there is no such entry). + if (current_min != previous->Min()->Number()) { + new_min = typer_->integer->AsRange()->Min(); + for (const auto val : typer_->weaken_min_limits_) { + if (val->Number() <= current_min) { + new_min = val; + break; + } } } - } - double current_max = current->Max()->Number(); - Handle new_max = current->Max(); - // Find the closest greater entry in the list of allowed - // maxima (or infinity if there is no such entry). - if (current_max != previous->Max()->Number()) { - new_max = typer_->integer->AsRange()->Max(); - for (const auto val : typer_->weaken_max_limits_) { - if (val->Number() >= current_max) { - new_max = val; - break; + double current_max = current->Max()->Number(); + Handle new_max = current->Max(); + // Find the closest greater entry in the list of allowed + // maxima (or infinity if there is no such entry). + if (current_max != previous->Max()->Number()) { + new_max = typer_->integer->AsRange()->Max(); + for (const auto val : typer_->weaken_max_limits_) { + if (val->Number() >= current_max) { + new_max = val; + break; + } } } - } - return Type::Union(current_type, - Type::Range(new_min, new_max, typer_->zone()), - typer_->zone()); + return Type::Union(current_type, + Type::Range(new_min, new_max, typer_->zone()), + typer_->zone()); + } + return current_type; } diff --git a/src/types-inl.h b/src/types-inl.h index 60d81bd..2e7f8a3 100644 --- a/src/types-inl.h +++ b/src/types-inl.h @@ -16,20 +16,6 @@ namespace internal { // ----------------------------------------------------------------------------- // TypeImpl -template -typename TypeImpl::bitset -TypeImpl::BitsetType::SignedSmall() { - return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32; -} - - -template -typename TypeImpl::bitset -TypeImpl::BitsetType::UnsignedSmall() { - return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31; -} - - template TypeImpl* TypeImpl::cast(typename Config::Base* object) { TypeImpl* t = static_cast(object); @@ -215,9 +201,6 @@ void ZoneTypeConfig::struct_set_value( } -// static -i::Isolate* ZoneTypeConfig::isolate(Zone* zone) { return zone->isolate(); } - // ----------------------------------------------------------------------------- // HeapTypeConfig @@ -365,8 +348,6 @@ void HeapTypeConfig::struct_set_value( structure->set(i + 1, *x); } -// static -i::Isolate* HeapTypeConfig::isolate(Isolate* isolate) { return isolate; } } } // namespace v8::internal #endif // V8_TYPES_INL_H_ diff --git a/src/types.cc b/src/types.cc index 36b2705..4f4b7fb 100644 --- a/src/types.cc +++ b/src/types.cc @@ -28,31 +28,17 @@ typename TypeImpl::Limits TypeImpl::Intersect( Limits result(lhs); if (lhs.min->Number() < rhs.min->Number()) result.min = rhs.min; if (lhs.max->Number() > rhs.max->Number()) result.max = rhs.max; - result.representation = lhs.representation & rhs.representation; return result; } -template -bool TypeImpl::IsEmpty(Limits lim) { - return lim.representation == BitsetType::kNone || - lim.min->Number() > lim.max->Number(); -} - - -template -typename TypeImpl::Limits TypeImpl::Union(Limits lhs, - Limits rhs) { +template +typename TypeImpl::Limits TypeImpl::Union( + Limits lhs, Limits rhs) { DisallowHeapAllocation no_allocation; - // Handle the case of empty operand, so that we do not stretch - // the limits/representations for them. - if (IsEmpty(lhs)) return rhs; - if (IsEmpty(rhs)) return lhs; - Limits result(lhs); if (lhs.min->Number() > rhs.min->Number()) result.min = rhs.min; if (lhs.max->Number() < rhs.max->Number()) result.max = rhs.max; - result.representation = lhs.representation | rhs.representation; return result; } @@ -63,8 +49,7 @@ bool TypeImpl::Overlap( typename TypeImpl::RangeType* rhs) { DisallowHeapAllocation no_allocation; typename TypeImpl::Limits lim = Intersect(Limits(lhs), Limits(rhs)); - return lim.min->Number() <= lim.max->Number() && - lim.representation != BitsetType::kNone; + return lim.min->Number() <= lim.max->Number(); } @@ -73,19 +58,8 @@ bool TypeImpl::Contains( typename TypeImpl::RangeType* lhs, typename TypeImpl::RangeType* rhs) { DisallowHeapAllocation no_allocation; - return rhs->Bound()->Is(lhs->Bound()) && - lhs->Min()->Number() <= rhs->Min()->Number() && - rhs->Max()->Number() <= lhs->Max()->Number(); -} - - -template -bool TypeImpl::Contains(typename TypeImpl::RangeType* lhs, - typename TypeImpl::ConstantType* rhs) { - DisallowHeapAllocation no_allocation; - return IsInteger(*rhs->Value()) && rhs->Bound()->Is(lhs->Bound()) && - lhs->Min()->Number() <= rhs->Value()->Number() && - rhs->Value()->Number() <= lhs->Max()->Number(); + return lhs->Min()->Number() <= rhs->Min()->Number() + && rhs->Max()->Number() <= lhs->Max()->Number(); } @@ -93,10 +67,9 @@ template bool TypeImpl::Contains( typename TypeImpl::RangeType* range, i::Object* val) { DisallowHeapAllocation no_allocation; - return IsInteger(val) && - BitsetType::Is(BitsetType::Lub(val), range->Bound()->AsBitset()) && - range->Min()->Number() <= val->Number() && - val->Number() <= range->Max()->Number(); + return IsInteger(val) + && range->Min()->Number() <= val->Number() + && val->Number() <= range->Max()->Number(); } @@ -152,18 +125,9 @@ TypeImpl::BitsetType::Glb(TypeImpl* type) { return type->AsBitset(); } else if (type->IsUnion()) { SLOW_DCHECK(type->AsUnion()->Wellformed()); - return type->AsUnion()->Get(0)->BitsetGlb() | - type->AsUnion()->Get(1)->BitsetGlb(); // Shortcut. - } else if (type->IsRange()) { - bitset glb = SEMANTIC(BitsetType::Glb(type->AsRange()->Min()->Number(), - type->AsRange()->Max()->Number())); - if (glb == 0) { - return kNone; - } else { - return glb | REPRESENTATION(type->BitsetLub()); - } - } else { + return type->AsUnion()->Get(0)->BitsetGlb(); // Shortcut. // (The remaining BitsetGlb's are None anyway). + } else { return kNone; } } @@ -188,7 +152,7 @@ TypeImpl::BitsetType::Lub(TypeImpl* type) { type->AsClass()->Bound(NULL)->AsBitset(); } if (type->IsConstant()) return type->AsConstant()->Bound()->AsBitset(); - if (type->IsRange()) return type->AsRange()->Bound()->AsBitset(); + if (type->IsRange()) return type->AsRange()->BitsetLub(); if (type->IsContext()) return kInternal & kTaggedPointer; if (type->IsArray()) return kArray; if (type->IsFunction()) return kOtherObject; // TODO(rossberg): kFunction @@ -320,33 +284,29 @@ TypeImpl::BitsetType::Lub(double value) { } -// Minimum values of regular numeric bitsets. -template -const typename TypeImpl::BitsetType::Boundary - TypeImpl::BitsetType::BoundariesArray[] = { - {kPlainNumber, -V8_INFINITY}, - {kNegative32, kMinInt}, - {kNegative31, -0x40000000}, - {kUnsigned30, 0}, - {kUnsigned31, 0x40000000}, - {kUnsigned32, 0x80000000}, - {kPlainNumber, static_cast(kMaxUInt32) + 1} -}; - - +// Minimum values of regular numeric bitsets when SmiValuesAre31Bits. template -const typename TypeImpl::BitsetType::Boundary* -TypeImpl::BitsetType::Boundaries() { - return BoundariesArray; -} - - +const typename TypeImpl::BitsetType::BitsetMin + TypeImpl::BitsetType::BitsetMins31[] = { + {kOtherNumber, -V8_INFINITY}, + {kOtherSigned32, kMinInt}, + {kNegativeSignedSmall, -0x40000000}, + {kUnsignedSmall, 0}, + {kOtherUnsigned31, 0x40000000}, + {kOtherUnsigned32, 0x80000000}, + {kOtherNumber, static_cast(kMaxUInt32) + 1}}; + + +// Minimum values of regular numeric bitsets when SmiValuesAre32Bits. +// OtherSigned32 and OtherUnsigned31 are empty (see the diagrams in types.h). template -size_t TypeImpl::BitsetType::BoundariesSize() { - // Windows doesn't like arraysize here. - // return arraysize(BoundariesArray); - return 7; -} +const typename TypeImpl::BitsetType::BitsetMin + TypeImpl::BitsetType::BitsetMins32[] = { + {kOtherNumber, -V8_INFINITY}, + {kNegativeSignedSmall, kMinInt}, + {kUnsignedSmall, 0}, + {kOtherUnsigned32, 0x80000000}, + {kOtherNumber, static_cast(kMaxUInt32) + 1}}; template @@ -354,71 +314,30 @@ typename TypeImpl::bitset TypeImpl::BitsetType::Lub(double min, double max) { DisallowHeapAllocation no_allocation; int lub = kNone; - const Boundary* mins = Boundaries(); + const BitsetMin* mins = BitsetMins(); // Make sure the min-max range touches 0, so we are guaranteed no holes // in unions of valid bitsets. if (max < -1) max = -1; if (min > 0) min = 0; - for (size_t i = 1; i < BoundariesSize(); ++i) { + for (size_t i = 1; i < BitsetMinsSize(); ++i) { if (min < mins[i].min) { lub |= mins[i-1].bits; if (max < mins[i].min) return lub; } } - return lub |= mins[BoundariesSize() - 1].bits; + return lub |= mins[BitsetMinsSize()-1].bits; } -template -typename TypeImpl::bitset TypeImpl::BitsetType::NumberBits( - bitset bits) { - return SEMANTIC(bits & kPlainNumber); -} - - -template -void TypeImpl::BitsetType::CheckNumberBits(bitset bits) { - // Check that the bitset does not contain any holes in number ranges. - bitset number_bits = NumberBits(bits); - if (number_bits != 0) { - bitset lub = SEMANTIC(Lub(Min(number_bits), Max(number_bits))); - CHECK(lub == number_bits); - } -} - -template -typename TypeImpl::bitset TypeImpl::BitsetType::Glb( - double min, double max) { - DisallowHeapAllocation no_allocation; - int glb = kNone; - const Boundary* mins = Boundaries(); - - // If the range does not touch 0, the bound is empty. - if (max < -1 || min > 0) return glb; - - for (size_t i = 1; i + 1 < BoundariesSize(); ++i) { - if (min <= mins[i].min) { - if (max + 1 < mins[i + 1].min) break; - glb |= mins[i].bits; - } - } - // OtherNumber also contains float numbers, so it can never be - // in the greatest lower bound. (There is also the small trouble - // of kOtherNumber having a range hole, which we can conveniently - // ignore here.) - return glb & ~(SEMANTIC(kOtherNumber)); -} - - -template +template double TypeImpl::BitsetType::Min(bitset bits) { DisallowHeapAllocation no_allocation; DCHECK(Is(bits, kNumber)); - const Boundary* mins = Boundaries(); + const BitsetMin* mins = BitsetMins(); bool mz = SEMANTIC(bits & kMinusZero); - for (size_t i = 0; i < BoundariesSize(); ++i) { + for (size_t i = 0; i < BitsetMinsSize(); ++i) { if (Is(SEMANTIC(mins[i].bits), bits)) { return mz ? std::min(0.0, mins[i].min) : mins[i].min; } @@ -432,12 +351,12 @@ template double TypeImpl::BitsetType::Max(bitset bits) { DisallowHeapAllocation no_allocation; DCHECK(Is(bits, kNumber)); - const Boundary* mins = Boundaries(); + const BitsetMin* mins = BitsetMins(); bool mz = SEMANTIC(bits & kMinusZero); - if (BitsetType::Is(SEMANTIC(mins[BoundariesSize() - 1].bits), bits)) { + if (BitsetType::Is(mins[BitsetMinsSize()-1].bits, bits)) { return +V8_INFINITY; } - for (size_t i = BoundariesSize() - 1; i-- > 0;) { + for (size_t i = BitsetMinsSize()-1; i-- > 0; ) { if (Is(SEMANTIC(mins[i].bits), bits)) { return mz ? std::max(0.0, mins[i+1].min - 1) : mins[i+1].min - 1; @@ -520,9 +439,9 @@ bool TypeImpl::SlowIs(TypeImpl* that) { } if (that->IsRange()) { - return (this->IsRange() && Contains(that->AsRange(), this->AsRange())) || - (this->IsConstant() && - Contains(that->AsRange(), this->AsConstant())); + return (this->IsRange() && Contains(that->AsRange(), this->AsRange())) + || (this->IsConstant() && + Contains(that->AsRange(), *this->AsConstant()->Value())); } if (this->IsRange()) return false; @@ -584,38 +503,23 @@ bool TypeImpl::Maybe(TypeImpl* that) { if (!BitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub())) return false; - - if (this->IsBitset() && that->IsBitset()) return true; + if (this->IsBitset() || that->IsBitset()) return true; if (this->IsClass() != that->IsClass()) return true; if (this->IsRange()) { if (that->IsConstant()) { - return Contains(this->AsRange(), that->AsConstant()); - } - if (that->IsRange()) { - return Overlap(this->AsRange(), that->AsRange()); - } - if (that->IsBitset()) { - bitset number_bits = BitsetType::NumberBits(that->AsBitset()); - if (number_bits == BitsetType::kNone) { - return false; - } - if ((REPRESENTATION(that->AsBitset()) & - REPRESENTATION(this->BitsetLub())) == BitsetType::kNone) { - return false; - } - double min = std::max(BitsetType::Min(number_bits), this->Min()); - double max = std::min(BitsetType::Max(number_bits), this->Max()); - return min <= max; + return Contains(this->AsRange(), *that->AsConstant()->Value()); } + return that->IsRange() && Overlap(this->AsRange(), that->AsRange()); } if (that->IsRange()) { - return that->Maybe(this); // This case is handled above. + if (this->IsConstant()) { + return Contains(that->AsRange(), *this->AsConstant()->Value()); + } + return this->IsRange() && Overlap(this->AsRange(), that->AsRange()); } - if (this->IsBitset() || that->IsBitset()) return true; - return this->SimplyEquals(that); } @@ -656,23 +560,15 @@ bool TypeImpl::UnionType::Wellformed() { // (even when the first element is not a bitset). // 4. No element is itself a union. // 5. No element is a subtype of any other. - // 6. If there is a range, then the bitset type does not contain - // plain number bits. DCHECK(this->Length() >= 2); // (1) - - bitset number_bits = this->Get(0)->IsBitset() - ? BitsetType::NumberBits(this->Get(0)->AsBitset()) : 0; - USE(number_bits); - for (int i = 0; i < this->Length(); ++i) { if (i != 0) DCHECK(!this->Get(i)->IsBitset()); // (2) - if (i != 1) DCHECK(!this->Get(i)->IsRange()); // (3) - DCHECK(!this->Get(i)->IsUnion()); // (4) + if (i != 1) DCHECK(!this->Get(i)->IsRange()); // (3) + DCHECK(!this->Get(i)->IsUnion()); // (4) for (int j = 0; j < this->Length(); ++j) { if (i != j) DCHECK(!this->Get(i)->Is(this->Get(j))); // (5) } } - DCHECK(!this->Get(1)->IsRange() || (number_bits == 0)); // (6) return true; } @@ -719,25 +615,20 @@ typename TypeImpl::TypeHandle TypeImpl::Intersect( // Deal with bitsets. result->Set(size++, BitsetType::New(bits, region)); - // Insert a placeholder for the range. - result->Set(size++, None(region)); - - Limits lims = Limits::Empty(region); - size = IntersectAux(type1, type2, result, size, &lims, region); - - // If the range is not empty, then insert it into the union and - // remove the number bits from the bitset. - if (!IsEmpty(lims)) { - UpdateRange(RangeType::New(lims, region), result, size, region); - - // Remove the number bits. - bitset number_bits = BitsetType::NumberBits(bits); - bits &= ~number_bits; - if (SEMANTIC(bits) == BitsetType::kNone) { - bits = BitsetType::kNone; + + // Deal with ranges. + TypeHandle range = None(region); + RangeType* range1 = type1->GetRange(); + RangeType* range2 = type2->GetRange(); + if (range1 != NULL && range2 != NULL) { + Limits lim = Intersect(Limits(range1), Limits(range2)); + if (lim.min->Number() <= lim.max->Number()) { + range = RangeType::New(lim, region); } - result->Set(0, BitsetType::New(bits, region)); } + result->Set(size++, range); + + size = IntersectAux(type1, type2, result, size, region); return NormalizeUnion(result, size); } @@ -766,51 +657,19 @@ int TypeImpl::UpdateRange( } -template -typename TypeImpl::Limits TypeImpl::ToLimits(bitset bits, - Region* region) { - bitset representation = REPRESENTATION(bits); - bitset number_bits = BitsetType::NumberBits(bits); - - if (representation == BitsetType::kNone && number_bits == BitsetType::kNone) { - return Limits::Empty(region); - } - - double bitset_min = BitsetType::Min(number_bits); - double bitset_max = BitsetType::Max(number_bits); - - // TODO(jarin) Get rid of the heap numbers. - i::Factory* f = Config::isolate(region)->factory(); - - return Limits(f->NewNumber(bitset_min), f->NewNumber(bitset_max), - representation); -} - - -template -typename TypeImpl::Limits TypeImpl::IntersectRangeAndBitset( - TypeHandle range, TypeHandle bitset, Region* region) { - Limits range_lims(range->AsRange()); - Limits bitset_lims = ToLimits(bitset->AsBitset(), region); - return Intersect(range_lims, bitset_lims); -} - - -template -int TypeImpl::IntersectAux(TypeHandle lhs, TypeHandle rhs, - UnionHandle result, int size, Limits* lims, - Region* region) { +template +int TypeImpl::IntersectAux( + TypeHandle lhs, TypeHandle rhs, + UnionHandle result, int size, Region* region) { if (lhs->IsUnion()) { for (int i = 0, n = lhs->AsUnion()->Length(); i < n; ++i) { - size = - IntersectAux(lhs->AsUnion()->Get(i), rhs, result, size, lims, region); + size = IntersectAux(lhs->AsUnion()->Get(i), rhs, result, size, region); } return size; } if (rhs->IsUnion()) { for (int i = 0, n = rhs->AsUnion()->Length(); i < n; ++i) { - size = - IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, lims, region); + size = IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, region); } return size; } @@ -820,41 +679,23 @@ int TypeImpl::IntersectAux(TypeHandle lhs, TypeHandle rhs, } if (lhs->IsRange()) { - if (rhs->IsBitset()) { - Limits lim = IntersectRangeAndBitset(lhs, rhs, region); - - if (!IsEmpty(lim)) { - *lims = Union(lim, *lims); - } - return size; + if (rhs->IsBitset() || rhs->IsClass()) { + return UpdateRange( + Config::template cast(lhs), result, size, region); } - if (rhs->IsClass()) { - *lims = Union(Limits(lhs->AsRange()), *lims); - } - if (rhs->IsConstant() && Contains(lhs->AsRange(), rhs->AsConstant())) { + if (rhs->IsConstant() && + Contains(lhs->AsRange(), *rhs->AsConstant()->Value())) { return AddToUnion(rhs, result, size, region); } - if (rhs->IsRange()) { - Limits lim = Intersect(Limits(lhs->AsRange()), Limits(rhs->AsRange())); - if (!IsEmpty(lim)) { - *lims = Union(lim, *lims); - } - } return size; } if (rhs->IsRange()) { - if (lhs->IsBitset()) { - Limits lim = IntersectRangeAndBitset(rhs, lhs, region); - - if (!IsEmpty(lim)) { - *lims = Union(lim, *lims); - } - return size; - } - if (lhs->IsClass()) { - *lims = Union(Limits(rhs->AsRange()), *lims); + if (lhs->IsBitset() || lhs->IsClass()) { + return UpdateRange( + Config::template cast(rhs), result, size, region); } - if (lhs->IsConstant() && Contains(rhs->AsRange(), lhs->AsConstant())) { + if (lhs->IsConstant() && + Contains(rhs->AsRange(), *lhs->AsConstant()->Value())) { return AddToUnion(lhs, result, size, region); } return size; @@ -873,65 +714,6 @@ int TypeImpl::IntersectAux(TypeHandle lhs, TypeHandle rhs, } -// Make sure that we produce a well-formed range and bitset: -// If the range is non-empty, the number bits in the bitset should be -// clear. Moreover, if we have a canonical range (such as Signed32(), -// we want to produce a bitset rather than a range. -template -typename TypeImpl::TypeHandle TypeImpl::NormalizeRangeAndBitset( - RangeHandle range, bitset* bits, Region* region) { - // Fast path: If the bitset does not mention numbers, we can just keep the - // range. - bitset number_bits = BitsetType::NumberBits(*bits); - if (number_bits == 0) { - return range; - } - - // If the range is contained within the bitset, return an empty range - // (but make sure we take the representation). - bitset range_lub = range->BitsetLub(); - if (BitsetType::Is(BitsetType::NumberBits(range_lub), *bits)) { - *bits |= range_lub; - return None(region); - } - - // Slow path: reconcile the bitset range and the range. - double bitset_min = BitsetType::Min(number_bits); - double bitset_max = BitsetType::Max(number_bits); - - i::Handle range_min_obj = range->Min(); - i::Handle range_max_obj = range->Max(); - double range_min = range_min_obj->Number(); - double range_max = range_max_obj->Number(); - - bitset range_representation = REPRESENTATION(range->BitsetLub()); - bitset bits_representation = REPRESENTATION(*bits); - bitset representation = - (bits_representation | range_representation) & BitsetType::kNumber; - - // Remove the number bits from the bitset, they would just confuse us now. - *bits &= ~number_bits; - if (bits_representation == *bits) { - *bits = BitsetType::kNone; - } - - if (representation == range_representation && range_min <= bitset_min && - range_max >= bitset_max) { - // Bitset is contained within the range, just return the range. - return range; - } - - if (bitset_min < range_min) { - range_min_obj = Config::isolate(region)->factory()->NewNumber(bitset_min); - } - if (bitset_max > range_max) { - range_max_obj = Config::isolate(region)->factory()->NewNumber(bitset_max); - } - return RangeType::New(range_min_obj, range_max_obj, - BitsetType::New(representation, region), region); -} - - template typename TypeImpl::TypeHandle TypeImpl::Union( TypeHandle type1, TypeHandle type2, Region* region) { @@ -959,24 +741,22 @@ typename TypeImpl::TypeHandle TypeImpl::Union( UnionHandle result = UnionType::New(size, region); size = 0; - // Compute the new bitset. - bitset new_bitset = type1->BitsetGlb() | type2->BitsetGlb(); + // Deal with bitsets. + TypeHandle bits = BitsetType::New( + type1->BitsetGlb() | type2->BitsetGlb(), region); + result->Set(size++, bits); // Deal with ranges. TypeHandle range = None(region); RangeType* range1 = type1->GetRange(); RangeType* range2 = type2->GetRange(); if (range1 != NULL && range2 != NULL) { - Limits lims = Union(Limits(range1), Limits(range2)); - RangeHandle union_range = RangeType::New(lims, region); - range = NormalizeRangeAndBitset(union_range, &new_bitset, region); + range = RangeType::New(Union(Limits(range1), Limits(range2)), region); } else if (range1 != NULL) { - range = NormalizeRangeAndBitset(handle(range1), &new_bitset, region); + range = handle(range1); } else if (range2 != NULL) { - range = NormalizeRangeAndBitset(handle(range2), &new_bitset, region); + range = handle(range2); } - TypeHandle bits = BitsetType::New(new_bitset, region); - result->Set(size++, bits); result->Set(size++, range); size = AddToUnion(type1, result, size, region); @@ -1139,8 +919,7 @@ typename TypeImpl::TypeHandle TypeImpl::Convert( return ConstantType::New(type->AsConstant()->Value(), region); } else if (type->IsRange()) { return RangeType::New( - type->AsRange()->Min(), type->AsRange()->Max(), - BitsetType::New(REPRESENTATION(type->BitsetLub()), region), region); + type->AsRange()->Min(), type->AsRange()->Max(), region); } else if (type->IsContext()) { TypeHandle outer = Convert(type->AsContext()->Outer(), region); return ContextType::New(outer, region); @@ -1206,18 +985,16 @@ void TypeImpl::BitsetType::Print(std::ostream& os, // NOLINT return; } - // clang-format off static const bitset named_bitsets[] = { #define BITSET_CONSTANT(type, value) REPRESENTATION(k##type), - REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT) + REPRESENTATION_BITSET_TYPE_LIST(BITSET_CONSTANT) #undef BITSET_CONSTANT #define BITSET_CONSTANT(type, value) SEMANTIC(k##type), - INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT) - SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT) + INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT) + SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT) #undef BITSET_CONSTANT }; - // clang-format on bool is_first = true; os << "("; diff --git a/src/types.h b/src/types.h index 72a78ca..4b7d8ba 100644 --- a/src/types.h +++ b/src/types.h @@ -153,8 +153,6 @@ namespace internal { // ----------------------------------------------------------------------------- // Values for bitset types -// clang-format off - #define MASK_BITSET_TYPE_LIST(V) \ V(Representation, 0xfff00000u) \ V(Semantic, 0x000ffffeu) @@ -197,11 +195,11 @@ namespace internal { V(OtherNumber, 1u << 4 | REPRESENTATION(kTagged | kUntaggedNumber)) #define SEMANTIC_BITSET_TYPE_LIST(V) \ - V(Negative31, 1u << 5 | REPRESENTATION(kTagged | kUntaggedNumber)) \ + V(NegativeSignedSmall, 1u << 5 | REPRESENTATION(kTagged | kUntaggedNumber)) \ V(Null, 1u << 6 | REPRESENTATION(kTaggedPointer)) \ V(Undefined, 1u << 7 | REPRESENTATION(kTaggedPointer)) \ V(Boolean, 1u << 8 | REPRESENTATION(kTaggedPointer)) \ - V(Unsigned30, 1u << 9 | REPRESENTATION(kTagged | kUntaggedNumber)) \ + V(UnsignedSmall, 1u << 9 | REPRESENTATION(kTagged | kUntaggedNumber)) \ V(MinusZero, 1u << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \ V(NaN, 1u << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \ V(Symbol, 1u << 12 | REPRESENTATION(kTaggedPointer)) \ @@ -213,11 +211,11 @@ namespace internal { V(Proxy, 1u << 18 | REPRESENTATION(kTaggedPointer)) \ V(Internal, 1u << 19 | REPRESENTATION(kTagged | kUntagged)) \ \ - V(Signed31, kUnsigned30 | kNegative31) \ - V(Signed32, kSigned31 | kOtherUnsigned31 | kOtherSigned32) \ - V(Negative32, kNegative31 | kOtherSigned32) \ - V(Unsigned31, kUnsigned30 | kOtherUnsigned31) \ - V(Unsigned32, kUnsigned30 | kOtherUnsigned31 | kOtherUnsigned32) \ + V(SignedSmall, kUnsignedSmall | kNegativeSignedSmall) \ + V(Signed32, kSignedSmall | kOtherUnsigned31 | kOtherSigned32) \ + V(NegativeSigned32, kNegativeSignedSmall | kOtherSigned32) \ + V(NonNegativeSigned32, kUnsignedSmall | kOtherUnsigned31) \ + V(Unsigned32, kUnsignedSmall | kOtherUnsigned31 | kOtherUnsigned32) \ V(Integral32, kSigned32 | kUnsigned32) \ V(PlainNumber, kIntegral32 | kOtherNumber) \ V(OrderedNumber, kPlainNumber | kMinusZero) \ @@ -239,17 +237,29 @@ namespace internal { V(NonNumber, kUnique | kString | kInternal) \ V(Any, 0xfffffffeu) -// clang-format on /* * The following diagrams show how integers (in the mathematical sense) are * divided among the different atomic numerical types. * - * ON OS32 N31 U30 OU31 OU32 ON + * If SmiValuesAre31Bits(): + * + * ON OS32 OSS US OU31 OU32 ON * ______[_______[_______[_______[_______[_______[_______ * -2^31 -2^30 0 2^30 2^31 2^32 * + * Otherwise: + * + * ON OSS US OU32 ON + * ______[_______________[_______________[_______[_______ + * -2^31 0 2^31 2^32 + * + * * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1. + * + * NOTE: OtherSigned32 (OS32) and OU31 (OtherUnsigned31) are empty if Smis are + * 32-bit wide. They should thus never be used directly, only indirectly + * via e.g. Number. */ #define PROPER_BITSET_TYPE_LIST(V) \ @@ -295,7 +305,6 @@ namespace internal { // static i::Handle struct_get_value(Handle::type, int); // template // static void struct_set_value(Handle::type, int, i::Handle); -// static i::Isolate* isolate(Region* region); // } template class TypeImpl : public Config::Base { @@ -336,19 +345,6 @@ class TypeImpl : public Config::Base { PROPER_BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) #undef DEFINE_TYPE_CONSTRUCTOR - static TypeImpl* SignedSmall() { - return BitsetType::New(BitsetType::SignedSmall()); - } - static TypeHandle SignedSmall(Region* region) { - return BitsetType::New(BitsetType::SignedSmall(), region); - } - static TypeImpl* UnsignedSmall() { - return BitsetType::New(BitsetType::UnsignedSmall()); - } - static TypeHandle UnsignedSmall(Region* region) { - return BitsetType::New(BitsetType::UnsignedSmall(), region); - } - static TypeHandle Class(i::Handle map, Region* region) { return ClassType::New(map, region); } @@ -357,11 +353,7 @@ class TypeImpl : public Config::Base { } static TypeHandle Range( i::Handle min, i::Handle max, Region* region) { - return RangeType::New( - min, max, BitsetType::New(REPRESENTATION(BitsetType::kTagged | - BitsetType::kUntaggedNumber), - region), - region); + return RangeType::New(min, max, region); } static TypeHandle Context(TypeHandle outer, Region* region) { return ContextType::New(outer, region); @@ -568,48 +560,31 @@ class TypeImpl : public Config::Base { struct Limits { i::Handle min; i::Handle max; - bitset representation; - Limits(i::Handle min, i::Handle max, - bitset representation) - : min(min), max(max), representation(representation) {} - explicit Limits(RangeType* range) - : min(range->Min()), - max(range->Max()), - representation(REPRESENTATION(range->Bound()->AsBitset())) {} - static Limits Empty(Region* region) { - i::Factory* f = Config::isolate(region)->factory(); - i::Handle min = f->NewNumber(1); - i::Handle max = f->NewNumber(0); - return Limits(min, max, BitsetType::kNone); - } + Limits(i::Handle min, i::Handle max) : + min(min), max(max) {} + explicit Limits(RangeType* range) : + min(range->Min()), max(range->Max()) {} }; - static bool IsEmpty(Limits lim); static Limits Intersect(Limits lhs, Limits rhs); static Limits Union(Limits lhs, Limits rhs); static bool Overlap(RangeType* lhs, RangeType* rhs); static bool Contains(RangeType* lhs, RangeType* rhs); - static bool Contains(RangeType* range, ConstantType* constant); static bool Contains(RangeType* range, i::Object* val); static int UpdateRange( RangeHandle type, UnionHandle result, int size, Region* region); - static Limits IntersectRangeAndBitset(TypeHandle range, TypeHandle bits, - Region* region); - static Limits ToLimits(bitset bits, Region* region); - bool SimplyEquals(TypeImpl* that); template bool SimplyEquals(TypeHandle that) { return this->SimplyEquals(*that); } static int AddToUnion( TypeHandle type, UnionHandle result, int size, Region* region); - static int IntersectAux(TypeHandle type, TypeHandle other, UnionHandle result, - int size, Limits* limits, Region* region); + static int IntersectAux( + TypeHandle type, TypeHandle other, + UnionHandle result, int size, Region* region); static TypeHandle NormalizeUnion(UnionHandle unioned, int size); - static TypeHandle NormalizeRangeAndBitset(RangeHandle range, bitset* bits, - Region* region); }; @@ -628,17 +603,28 @@ class TypeImpl::BitsetType : public TypeImpl { kUnusedEOL = 0 }; - static bitset SignedSmall(); - static bitset UnsignedSmall(); - bitset Bitset() { return Config::as_bitset(this); } static TypeImpl* New(bitset bits) { - if (FLAG_enable_slow_asserts) CheckNumberBits(bits); + DCHECK(bits == kNone || IsInhabited(bits)); + + if (FLAG_enable_slow_asserts) { + // Check that the bitset does not contain any holes in number ranges. + bitset mask = kSemantic; + if (!i::SmiValuesAre31Bits()) { + mask &= ~(kOtherUnsigned31 | kOtherSigned32); + } + bitset number_bits = bits & kPlainNumber & mask; + if (number_bits != 0) { + bitset lub = Lub(Min(number_bits), Max(number_bits)) & mask; + CHECK(lub == number_bits); + } + } + return Config::from_bitset(bits); } static TypeHandle New(bitset bits, Region* region) { - if (FLAG_enable_slow_asserts) CheckNumberBits(bits); + DCHECK(bits == kNone || IsInhabited(bits)); return Config::from_bitset(bits, region); } // TODO(neis): Eventually allow again for types with empty semantics @@ -656,7 +642,6 @@ class TypeImpl::BitsetType : public TypeImpl { static double Max(bitset); static bitset Glb(TypeImpl* type); // greatest lower bound that's a bitset - static bitset Glb(double min, double max); static bitset Lub(TypeImpl* type); // least upper bound that's a bitset static bitset Lub(i::Map* map); static bitset Lub(i::Object* value); @@ -669,18 +654,21 @@ class TypeImpl::BitsetType : public TypeImpl { static void Print(bitset); #endif - static bitset NumberBits(bitset bits); - private: - struct Boundary { + struct BitsetMin{ bitset bits; double min; }; - static const Boundary BoundariesArray[]; - static inline const Boundary* Boundaries(); - static inline size_t BoundariesSize(); - - static void CheckNumberBits(bitset bits); + static const BitsetMin BitsetMins31[]; + static const BitsetMin BitsetMins32[]; + static const BitsetMin* BitsetMins() { + return i::SmiValuesAre31Bits() ? BitsetMins31 : BitsetMins32; + } + static size_t BitsetMinsSize() { + return i::SmiValuesAre31Bits() ? 7 : 5; + /* arraysize(BitsetMins31) : arraysize(BitsetMins32); */ + // Using arraysize here doesn't compile on Windows. + } }; @@ -827,31 +815,25 @@ class TypeImpl::ConstantType : public StructuralType { template class TypeImpl::RangeType : public StructuralType { public: - TypeHandle Bound() { return this->Get(0); } + int BitsetLub() { return this->Get(0)->AsBitset(); } i::Handle Min() { return this->template GetValue(1); } i::Handle Max() { return this->template GetValue(2); } - static RangeHandle New(i::Handle min, i::Handle max, - TypeHandle representation, Region* region) { + static RangeHandle New( + i::Handle min, i::Handle max, Region* region) { DCHECK(IsInteger(min->Number()) && IsInteger(max->Number())); DCHECK(min->Number() <= max->Number()); - bitset representation_bits = representation->AsBitset(); - DCHECK(REPRESENTATION(representation_bits) == representation_bits); - RangeHandle type = Config::template cast( StructuralType::New(StructuralType::kRangeTag, 3, region)); - - bitset bits = SEMANTIC(BitsetType::Lub(min->Number(), max->Number())) | - representation_bits; - type->Set(0, BitsetType::New(bits, region)); + type->Set(0, BitsetType::New( + BitsetType::Lub(min->Number(), max->Number()), region)); type->SetValue(1, min); type->SetValue(2, max); return type; } static RangeHandle New(Limits lim, Region* region) { - return New(lim.min, lim.max, BitsetType::New(lim.representation, region), - region); + return New(lim.min, lim.max, region); } static RangeType* cast(TypeImpl* type) { @@ -1000,7 +982,6 @@ struct ZoneTypeConfig { static inline i::Handle struct_get_value(Struct* structure, int i); template static inline void struct_set_value( Struct* structure, int i, i::Handle x); - static inline i::Isolate* isolate(Zone* zone); }; typedef TypeImpl Type; @@ -1049,7 +1030,6 @@ struct HeapTypeConfig { template static inline void struct_set_value( i::Handle structure, int i, i::Handle x); - static inline i::Isolate* isolate(Isolate* isolate); }; typedef TypeImpl HeapType; diff --git a/test/cctest/compiler/test-js-typed-lowering.cc b/test/cctest/compiler/test-js-typed-lowering.cc index aee8e0c..3886786 100644 --- a/test/cctest/compiler/test-js-typed-lowering.cc +++ b/test/cctest/compiler/test-js-typed-lowering.cc @@ -176,17 +176,20 @@ static Type* kStringTypes[] = {Type::InternalizedString(), Type::OtherString(), Type::String()}; -static Type* kInt32Types[] = {Type::UnsignedSmall(), Type::Negative32(), - Type::Unsigned31(), Type::SignedSmall(), - Type::Signed32(), Type::Unsigned32(), - Type::Integral32()}; +static Type* kInt32Types[] = { + Type::UnsignedSmall(), Type::NegativeSigned32(), + Type::NonNegativeSigned32(), Type::SignedSmall(), + Type::Signed32(), Type::Unsigned32(), + Type::Integral32()}; static Type* kNumberTypes[] = { - Type::UnsignedSmall(), Type::Negative32(), Type::Unsigned31(), - Type::SignedSmall(), Type::Signed32(), Type::Unsigned32(), - Type::Integral32(), Type::MinusZero(), Type::NaN(), - Type::OrderedNumber(), Type::PlainNumber(), Type::Number()}; + Type::UnsignedSmall(), Type::NegativeSigned32(), + Type::NonNegativeSigned32(), Type::SignedSmall(), + Type::Signed32(), Type::Unsigned32(), + Type::Integral32(), Type::MinusZero(), + Type::NaN(), Type::OrderedNumber(), + Type::PlainNumber(), Type::Number()}; static Type* kJSTypes[] = {Type::Undefined(), Type::Null(), Type::Boolean(), @@ -313,12 +316,13 @@ class JSBitwiseShiftTypedLoweringTester : public JSTypedLoweringTester { TEST(Int32BitwiseShifts) { JSBitwiseShiftTypedLoweringTester R; - Type* types[] = { - Type::SignedSmall(), Type::UnsignedSmall(), Type::Negative32(), - Type::Unsigned31(), Type::Unsigned32(), Type::Signed32(), - Type::MinusZero(), Type::NaN(), Type::Undefined(), - Type::Null(), Type::Boolean(), Type::Number(), - Type::PlainNumber(), Type::String()}; + Type* types[] = {Type::SignedSmall(), Type::UnsignedSmall(), + Type::NegativeSigned32(), Type::NonNegativeSigned32(), + Type::Unsigned32(), Type::Signed32(), + Type::MinusZero(), Type::NaN(), + Type::Undefined(), Type::Null(), + Type::Boolean(), Type::Number(), + Type::PlainNumber(), Type::String()}; for (size_t i = 0; i < arraysize(types); ++i) { Node* p0 = R.Parameter(types[i], 0); diff --git a/test/cctest/test-types.cc b/test/cctest/test-types.cc index ee7ebf5..b845201 100644 --- a/test/cctest/test-types.cc +++ b/test/cctest/test-types.cc @@ -136,14 +136,6 @@ struct Tests : Rep { } } - void CheckSubOrEqual(TypeHandle type1, TypeHandle type2) { - CHECK(type1->Is(type2)); - if (this->IsBitset(type1) && this->IsBitset(type2)) { - CHECK((this->AsBitset(type1) | this->AsBitset(type2)) - == this->AsBitset(type2)); - } - } - void CheckUnordered(TypeHandle type1, TypeHandle type2) { CHECK(!type1->Is(type2)); CHECK(!type2->Is(type1)); @@ -302,33 +294,39 @@ struct Tests : Rep { CHECK(T.Constant(fac->NewNumber(0))->Is(T.UnsignedSmall)); CHECK(T.Constant(fac->NewNumber(1))->Is(T.UnsignedSmall)); CHECK(T.Constant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall)); - CHECK(T.Constant(fac->NewNumber(-1))->Is(T.Negative31)); - CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.Negative31)); - CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.Negative31)); - CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.Unsigned31)); - CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.Unsigned30)); - CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.Unsigned31)); - CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.Unsigned30)); - CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.Negative32)); - CHECK(!T.Constant(fac->NewNumber(-0x40000001))->Is(T.Negative31)); - CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.Negative32)); - CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 1))->Is(T.Negative31)); + CHECK(T.Constant(fac->NewNumber(-1))->Is(T.NegativeSignedSmall)); + CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.NegativeSignedSmall)); + CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.NegativeSignedSmall)); if (SmiValuesAre31Bits()) { + CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.NonNegativeSigned32)); CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall)); + CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.NonNegativeSigned32)); CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall)); - CHECK(!T.Constant(fac->NewNumber(-0x40000001))->Is(T.SignedSmall)); - CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 1))->Is(T.SignedSmall)); + CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.NegativeSigned32)); + CHECK( + !T.Constant(fac->NewNumber(-0x40000001))->Is(T.NegativeSignedSmall)); + CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.NegativeSigned32)); + CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 1)) + ->Is(T.NegativeSignedSmall)); } else { CHECK(SmiValuesAre32Bits()); CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall)); CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall)); - CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.SignedSmall)); - CHECK(T.Constant(fac->NewNumber(-0x7fffffff - 1))->Is(T.SignedSmall)); + CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.NonNegativeSigned32)); + CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.NonNegativeSigned32)); + CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.NegativeSignedSmall)); + CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.NegativeSignedSmall)); + CHECK(T.Constant(fac->NewNumber(-0x7fffffff - 1)) + ->Is(T.NegativeSignedSmall)); + CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.NegativeSigned32)); + CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.NegativeSigned32)); + CHECK( + T.Constant(fac->NewNumber(-0x7fffffff - 1))->Is(T.NegativeSigned32)); } CHECK(T.Constant(fac->NewNumber(0x80000000u))->Is(T.Unsigned32)); - CHECK(!T.Constant(fac->NewNumber(0x80000000u))->Is(T.Unsigned31)); + CHECK(!T.Constant(fac->NewNumber(0x80000000u))->Is(T.NonNegativeSigned32)); CHECK(T.Constant(fac->NewNumber(0xffffffffu))->Is(T.Unsigned32)); - CHECK(!T.Constant(fac->NewNumber(0xffffffffu))->Is(T.Unsigned31)); + CHECK(!T.Constant(fac->NewNumber(0xffffffffu))->Is(T.NonNegativeSigned32)); CHECK(T.Constant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.PlainNumber)); CHECK(!T.Constant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.Integral32)); CHECK(T.Constant(fac->NewNumber(-0x7fffffff - 2.0))->Is(T.PlainNumber)); @@ -798,7 +796,6 @@ struct Tests : Rep { (type1->IsClass() && type2->IsClass()) || (type1->IsConstant() && type2->IsConstant()) || (type1->IsConstant() && type2->IsRange()) || - (this->IsBitset(type1) && type2->IsRange()) || (type1->IsRange() && type2->IsRange()) || (type1->IsContext() && type2->IsContext()) || (type1->IsArray() && type2->IsArray()) || @@ -937,7 +934,7 @@ struct Tests : Rep { CheckSub(T.SignedSmall, T.Number); CheckSub(T.Signed32, T.Number); - CheckSubOrEqual(T.SignedSmall, T.Signed32); + CheckSub(T.SignedSmall, T.Signed32); CheckUnordered(T.SignedSmall, T.MinusZero); CheckUnordered(T.Signed32, T.Unsigned32); @@ -1481,8 +1478,8 @@ struct Tests : Rep { CheckDisjoint(T.Union(T.NumberFunction1, T.String), T.Number); // Bitset-class - CheckSub(T.Union(T.ObjectClass, T.SignedSmall), - T.Union(T.Object, T.Number)); + CheckSub( + T.Union(T.ObjectClass, T.SignedSmall), T.Union(T.Object, T.Number)); CheckSub(T.Union(T.ObjectClass, T.Array), T.Object); CheckUnordered(T.Union(T.ObjectClass, T.String), T.Array); CheckOverlap(T.Union(T.ObjectClass, T.String), T.Object); @@ -1552,9 +1549,11 @@ struct Tests : Rep { T.Union(T.ObjectConstant2, T.ObjectConstant1), T.Union(T.ObjectConstant1, T.ObjectConstant2)), T.Union(T.ObjectConstant2, T.ObjectConstant1)); - CheckEqual(T.Union(T.Union(T.Number, T.ArrayClass), - T.Union(T.SignedSmall, T.Array)), - T.Union(T.Number, T.Array)); + CheckEqual( + T.Union( + T.Union(T.Number, T.ArrayClass), + T.Union(T.SignedSmall, T.Array)), + T.Union(T.Number, T.Array)); } void Intersect() { @@ -1768,9 +1767,11 @@ struct Tests : Rep { ->IsInhabited()); // !!! // Union-union - CheckEqual(T.Intersect(T.Union(T.Number, T.ArrayClass), - T.Union(T.SignedSmall, T.Array)), - T.Union(T.SignedSmall, T.ArrayClass)); + CheckEqual( + T.Intersect( + T.Union(T.Number, T.ArrayClass), + T.Union(T.SignedSmall, T.Array)), + T.Union(T.SignedSmall, T.ArrayClass)); CheckEqual( T.Intersect( T.Union(T.Number, T.ObjectClass), diff --git a/test/cctest/types-fuzz.h b/test/cctest/types-fuzz.h index 7bf7512..4eac64c 100644 --- a/test/cctest/types-fuzz.h +++ b/test/cctest/types-fuzz.h @@ -45,9 +45,6 @@ class Types { PROPER_BITSET_TYPE_LIST(DECLARE_TYPE) #undef DECLARE_TYPE - SignedSmall = Type::SignedSmall(region); - UnsignedSmall = Type::UnsignedSmall(region); - object_map = isolate->factory()->NewMap( JS_OBJECT_TYPE, JSObject::kHeaderSize); array_map = isolate->factory()->NewMap( @@ -133,8 +130,6 @@ class Types { #define DECLARE_TYPE(name, value) TypeHandle name; PROPER_BITSET_TYPE_LIST(DECLARE_TYPE) #undef DECLARE_TYPE - TypeHandle SignedSmall; - TypeHandle UnsignedSmall; TypeHandle ObjectClass; TypeHandle ArrayClass; diff --git a/test/unittests/compiler/change-lowering-unittest.cc b/test/unittests/compiler/change-lowering-unittest.cc index 841968f..060b1c1 100644 --- a/test/unittests/compiler/change-lowering-unittest.cc +++ b/test/unittests/compiler/change-lowering-unittest.cc @@ -211,7 +211,7 @@ TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTagged) { TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTaggedSmall) { Node* val = Parameter(0); Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val); - NodeProperties::SetBounds(val, Bounds(Type::None(), Type::Signed31())); + NodeProperties::SetBounds(val, Bounds(Type::None(), Type::SignedSmall())); Reduction reduction = Reduce(node); ASSERT_TRUE(reduction.Changed()); diff --git a/test/unittests/compiler/js-builtin-reducer-unittest.cc b/test/unittests/compiler/js-builtin-reducer-unittest.cc index 1ea7306..9c57282 100644 --- a/test/unittests/compiler/js-builtin-reducer-unittest.cc +++ b/test/unittests/compiler/js-builtin-reducer-unittest.cc @@ -53,10 +53,12 @@ namespace { // TODO(mstarzinger): Find a common place and unify with test-js-typed-lowering. Type* const kNumberTypes[] = { - Type::UnsignedSmall(), Type::Negative32(), Type::Unsigned31(), - Type::SignedSmall(), Type::Signed32(), Type::Unsigned32(), - Type::Integral32(), Type::MinusZero(), Type::NaN(), - Type::OrderedNumber(), Type::PlainNumber(), Type::Number()}; + Type::UnsignedSmall(), Type::NegativeSigned32(), + Type::NonNegativeSigned32(), Type::SignedSmall(), + Type::Signed32(), Type::Unsigned32(), + Type::Integral32(), Type::MinusZero(), + Type::NaN(), Type::OrderedNumber(), + Type::PlainNumber(), Type::Number()}; } // namespace -- 2.7.4