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

Unified Diff: src/compiler/typer.cc

Issue 1199903002: [turbofan] Some cleanup to the Typer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 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
« no previous file with comments | « src/compiler/typer.h ('k') | src/heap/heap.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/typer.cc
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
index 5417f66f27c94a7c89290149147b0df32f85d0fe..6e9a28ee3b0f7cb889e4606f7a759a7f8d110822 100644
--- a/src/compiler/typer.cc
+++ b/src/compiler/typer.cc
@@ -26,6 +26,10 @@ namespace compiler {
V(Float64)
enum LazyCachedType {
+ kInteger,
+ kWeakint,
+ kWeakintFunc1,
+ kRandomFunc0,
kAnyFunc0,
kAnyFunc1,
kAnyFunc2,
@@ -53,9 +57,9 @@ class LazyTypeCache final : public ZoneObject {
memset(cache_, 0, sizeof(cache_));
}
- inline Type* Get(LazyCachedType type) {
- int index = static_cast<int>(type);
- DCHECK(index < kNumLazyCachedTypes);
+ V8_INLINE Type* Get(LazyCachedType type) {
+ int const index = static_cast<int>(type);
+ DCHECK_LT(index, kNumLazyCachedTypes);
if (cache_[index] == NULL) cache_[index] = Create(type);
return cache_[index];
}
@@ -82,6 +86,14 @@ class LazyTypeCache final : public ZoneObject {
return CreateNative(Type::Number(), Type::UntaggedFloat64());
case kUint8Clamped:
return Get(kUint8);
+ case kInteger:
+ return CreateRange(-V8_INFINITY, V8_INFINITY);
+ case kWeakint:
+ return Type::Union(Get(kInteger), Type::MinusZeroOrNaN(), zone());
+ case kWeakintFunc1:
+ return Type::Function(Get(kWeakint), Type::Number(), zone());
+ case kRandomFunc0:
+ return Type::Function(Type::OrderedNumber(), zone());
case kAnyFunc0:
return Type::Function(Type::Any(), zone());
case kAnyFunc1:
@@ -171,47 +183,30 @@ Typer::Typer(Isolate* isolate, Graph* graph, MaybeHandle<Context> context)
decorator_(NULL),
cache_(new (graph->zone()) LazyTypeCache(isolate, graph->zone())) {
Zone* zone = this->zone();
- Factory* f = isolate->factory();
+ Factory* const factory = isolate->factory();
- Handle<Object> infinity = f->NewNumber(+V8_INFINITY);
- Handle<Object> minusinfinity = f->NewNumber(-V8_INFINITY);
-
- Type* number = Type::Number();
- Type* signed32 = Type::Signed32();
- Type* unsigned32 = Type::Unsigned32();
- Type* nan_or_minuszero = Type::Union(Type::NaN(), Type::MinusZero(), zone);
+ Type* infinity = Type::Constant(factory->infinity_value(), zone);
+ Type* minus_infinity = Type::Constant(factory->minus_infinity_value(), zone);
Type* truncating_to_zero =
- Type::Union(Type::Union(Type::Constant(infinity, zone),
- Type::Constant(minusinfinity, zone), zone),
- nan_or_minuszero, zone);
-
- boolean_or_number = Type::Union(Type::Boolean(), Type::Number(), zone);
- undefined_or_null = Type::Union(Type::Undefined(), Type::Null(), zone);
- undefined_or_number = Type::Union(Type::Undefined(), Type::Number(), zone);
- singleton_false = Type::Constant(f->false_value(), zone);
- singleton_true = Type::Constant(f->true_value(), zone);
- singleton_zero = Type::Range(0.0, 0.0, zone);
- singleton_one = Type::Range(1.0, 1.0, zone);
- zero_or_one = Type::Union(singleton_zero, singleton_one, zone);
- zeroish = Type::Union(singleton_zero, nan_or_minuszero, zone);
- signed32ish = Type::Union(signed32, truncating_to_zero, zone);
- unsigned32ish = Type::Union(unsigned32, truncating_to_zero, zone);
- falsish = Type::Union(Type::Undetectable(),
- Type::Union(Type::Union(singleton_false, zeroish, zone),
- undefined_or_null, zone),
- zone);
- truish = Type::Union(
- singleton_true,
+ Type::Union(Type::Union(infinity, minus_infinity, zone),
+ Type::MinusZeroOrNaN(), zone);
+
+ singleton_false_ = Type::Constant(factory->false_value(), zone);
+ singleton_true_ = Type::Constant(factory->true_value(), zone);
+ singleton_zero_ = Type::Range(0.0, 0.0, zone);
+ singleton_one_ = Type::Range(1.0, 1.0, zone);
+ zero_or_one_ = Type::Range(0.0, 1.0, zone);
+ zeroish_ = Type::Union(singleton_zero_, Type::MinusZeroOrNaN(), zone);
+ signed32ish_ = Type::Union(Type::Signed32(), truncating_to_zero, zone);
+ unsigned32ish_ = Type::Union(Type::Unsigned32(), truncating_to_zero, zone);
+ falsish_ =
+ Type::Union(Type::Undetectable(),
+ Type::Union(Type::Union(singleton_false_, zeroish_, zone),
+ Type::NullOrUndefined(), zone),
+ zone);
+ truish_ = Type::Union(
+ singleton_true_,
Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone);
- integer = Type::Range(-V8_INFINITY, V8_INFINITY, zone);
- weakint = Type::Union(integer, nan_or_minuszero, zone);
-
- number_fun0_ = Type::Function(number, zone);
- number_fun1_ = Type::Function(number, number, zone);
- number_fun2_ = Type::Function(number, number, number, zone);
-
- weakint_fun1_ = Type::Function(weakint, number, zone);
- random_fun_ = Type::Function(Type::OrderedNumber(), zone);
decorator_ = new (zone) Decorator(this);
graph_->AddDecorator(decorator_);
@@ -500,8 +495,8 @@ Bounds Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
Type* Typer::Visitor::Invert(Type* type, Typer* t) {
DCHECK(type->Is(Type::Boolean()));
DCHECK(type->IsInhabited());
- if (type->Is(t->singleton_false)) return t->singleton_true;
- if (type->Is(t->singleton_true)) return t->singleton_false;
+ if (type->Is(t->singleton_false_)) return t->singleton_true_;
+ if (type->Is(t->singleton_true_)) return t->singleton_false_;
return type;
}
@@ -520,17 +515,17 @@ Type* Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) {
if ((outcome & kComparisonFalse) != 0 ||
(outcome & kComparisonUndefined) != 0) {
return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
- : t->singleton_false;
+ : t->singleton_false_;
}
// Type should be non empty, so we know it should be true.
DCHECK((outcome & kComparisonTrue) != 0);
- return t->singleton_true;
+ return t->singleton_true_;
}
Type* Typer::Visitor::Rangify(Type* type, Typer* t) {
if (type->IsRange()) return type; // Shortcut.
- if (!type->Is(t->integer) && !type->Is(Type::Integral32())) {
+ if (!type->Is(t->cache_->Get(kInteger))) {
return type; // Give up on non-integer types.
}
double min = type->Min();
@@ -558,10 +553,10 @@ Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) {
Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) {
if (type->Is(Type::Boolean())) return type;
- if (type->Is(t->falsish)) return t->singleton_false;
- if (type->Is(t->truish)) return t->singleton_true;
+ if (type->Is(t->falsish_)) return t->singleton_false_;
+ if (type->Is(t->truish_)) return t->singleton_true_;
if (type->Is(Type::PlainNumber()) && (type->Max() < 0 || 0 < type->Min())) {
- return t->singleton_true; // Ruled out nan, -0 and +0.
+ return t->singleton_true_; // Ruled out nan, -0 and +0.
}
return Type::Boolean();
}
@@ -569,21 +564,21 @@ Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) {
Type* Typer::Visitor::ToNumber(Type* type, Typer* t) {
if (type->Is(Type::Number())) return type;
- if (type->Is(Type::Null())) return t->singleton_zero;
- if (type->Is(Type::Undefined())) return Type::NaN();
- if (type->Is(t->undefined_or_null)) {
- return Type::Union(Type::NaN(), t->singleton_zero, t->zone());
+ if (type->Is(Type::NullOrUndefined())) {
+ if (type->Is(Type::Null())) return t->singleton_zero_;
+ if (type->Is(Type::Undefined())) return Type::NaN();
+ return Type::Union(Type::NaN(), t->singleton_zero_, t->zone());
}
- if (type->Is(t->undefined_or_number)) {
+ if (type->Is(Type::NumberOrUndefined())) {
return Type::Union(Type::Intersect(type, Type::Number(), t->zone()),
Type::NaN(), t->zone());
}
- if (type->Is(t->singleton_false)) return t->singleton_zero;
- if (type->Is(t->singleton_true)) return t->singleton_one;
- if (type->Is(Type::Boolean())) return t->zero_or_one;
- if (type->Is(t->boolean_or_number)) {
+ if (type->Is(t->singleton_false_)) return t->singleton_zero_;
+ if (type->Is(t->singleton_true_)) return t->singleton_one_;
+ if (type->Is(Type::Boolean())) return t->zero_or_one_;
+ if (type->Is(Type::BooleanOrNumber())) {
return Type::Union(Type::Intersect(type, Type::Number(), t->zone()),
- t->zero_or_one, t->zone());
+ t->zero_or_one_, t->zone());
}
return Type::Number();
}
@@ -598,9 +593,9 @@ Type* Typer::Visitor::ToString(Type* type, Typer* t) {
Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) {
// TODO(neis): DCHECK(type->Is(Type::Number()));
if (type->Is(Type::Signed32())) return type;
- if (type->Is(t->zeroish)) return t->singleton_zero;
- if (type->Is(t->signed32ish)) {
- return Type::Intersect(Type::Union(type, t->singleton_zero, t->zone()),
+ if (type->Is(t->zeroish_)) return t->singleton_zero_;
+ if (type->Is(t->signed32ish_)) {
+ return Type::Intersect(Type::Union(type, t->singleton_zero_, t->zone()),
Type::Signed32(), t->zone());
}
return Type::Signed32();
@@ -610,9 +605,9 @@ Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) {
Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) {
// TODO(neis): DCHECK(type->Is(Type::Number()));
if (type->Is(Type::Unsigned32())) return type;
- if (type->Is(t->zeroish)) return t->singleton_zero;
- if (type->Is(t->unsigned32ish)) {
- return Type::Intersect(Type::Union(type, t->singleton_zero, t->zone()),
+ if (type->Is(t->zeroish_)) return t->singleton_zero_;
+ if (type->Is(t->unsigned32ish_)) {
+ return Type::Intersect(Type::Union(type, t->singleton_zero_, t->zone()),
Type::Unsigned32(), t->zone());
}
return Type::Unsigned32();
@@ -776,19 +771,19 @@ Bounds Typer::Visitor::TypeDead(Node* node) {
Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) {
- if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false;
- if (lhs->Is(t->undefined_or_null) && rhs->Is(t->undefined_or_null)) {
- return t->singleton_true;
+ if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_;
+ if (lhs->Is(Type::NullOrUndefined()) && rhs->Is(Type::NullOrUndefined())) {
+ return t->singleton_true_;
}
if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) &&
(lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) {
- return t->singleton_false;
+ return t->singleton_false_;
}
if (lhs->IsConstant() && rhs->Is(lhs)) {
// Types are equal and are inhabited only by a single semantic value,
// which is not nan due to the earlier check.
// TODO(neis): Extend this to Range(x,x), MinusZero, ...?
- return t->singleton_true;
+ return t->singleton_true_;
}
return Type::Boolean();
}
@@ -812,16 +807,16 @@ static Type* JSType(Type* type) {
Type* Typer::Visitor::JSStrictEqualTyper(Type* lhs, Type* rhs, Typer* t) {
- if (!JSType(lhs)->Maybe(JSType(rhs))) return t->singleton_false;
- if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false;
+ if (!JSType(lhs)->Maybe(JSType(rhs))) return t->singleton_false_;
+ if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_;
if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) &&
(lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) {
- return t->singleton_false;
+ return t->singleton_false_;
}
if (lhs->IsConstant() && rhs->Is(lhs)) {
// Types are equal and are inhabited only by a single semantic value,
// which is not nan due to the earlier check.
- return t->singleton_true;
+ return t->singleton_true_;
}
return Type::Boolean();
}
@@ -1162,13 +1157,13 @@ Type* Typer::Visitor::JSMultiplyRanger(Type::RangeType* lhs,
// the discontinuity makes it too complicated. Note that even if none of the
// "results" above is nan, the actual result may still be, so we have to do a
// different check:
- bool maybe_nan = (lhs->Maybe(t->singleton_zero) &&
+ bool maybe_nan = (lhs->Maybe(t->singleton_zero_) &&
(rmin == -V8_INFINITY || rmax == +V8_INFINITY)) ||
- (rhs->Maybe(t->singleton_zero) &&
+ (rhs->Maybe(t->singleton_zero_) &&
(lmin == -V8_INFINITY || lmax == +V8_INFINITY));
- if (maybe_nan) return t->weakint; // Giving up.
- bool maybe_minuszero = (lhs->Maybe(t->singleton_zero) && rmin < 0) ||
- (rhs->Maybe(t->singleton_zero) && lmin < 0);
+ if (maybe_nan) return t->cache_->Get(kWeakint); // Giving up.
+ bool maybe_minuszero = (lhs->Maybe(t->singleton_zero_) && rmin < 0) ||
+ (rhs->Maybe(t->singleton_zero_) && lmin < 0);
Type* range =
Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone())
@@ -1194,7 +1189,7 @@ Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) {
// Division is tricky, so all we do is try ruling out nan.
// TODO(neis): try ruling out -0 as well?
bool maybe_nan =
- lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) ||
+ lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish_) ||
((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
(rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
return maybe_nan ? Type::Number() : Type::OrderedNumber();
@@ -1239,7 +1234,7 @@ Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
rhs = ToNumber(rhs, t);
if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
- if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) ||
+ if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish_) ||
lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) {
// Result maybe NaN.
return Type::Number();
@@ -1367,15 +1362,14 @@ Type* Typer::Visitor::Weaken(Node* node, Type* current_type,
STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits));
// If the types have nothing to do with integers, return the types.
- if (!previous_type->Maybe(typer_->integer)) {
+ Type* const integer = typer_->cache_->Get(kInteger);
+ if (!previous_type->Maybe(integer)) {
return current_type;
}
- DCHECK(current_type->Maybe(typer_->integer));
+ DCHECK(current_type->Maybe(integer));
- Type* current_integer =
- Type::Intersect(current_type, typer_->integer, zone());
- Type* previous_integer =
- Type::Intersect(previous_type, typer_->integer, zone());
+ Type* current_integer = Type::Intersect(current_type, integer, zone());
+ Type* previous_integer = Type::Intersect(previous_type, integer, zone());
// Once we start weakening a node, we should always weaken.
if (!IsWeakened(node->id())) {
@@ -1396,7 +1390,7 @@ Type* Typer::Visitor::Weaken(Node* node, Type* current_type,
// Find the closest lower entry in the list of allowed
// minima (or negative infinity if there is no such entry).
if (current_min != previous_integer->Min()) {
- new_min = typer_->integer->AsRange()->Min();
+ new_min = -V8_INFINITY;
for (double const min : kWeakenMinLimits) {
if (min <= current_min) {
new_min = min;
@@ -1410,7 +1404,7 @@ Type* Typer::Visitor::Weaken(Node* node, Type* current_type,
// Find the closest greater entry in the list of allowed
// maxima (or infinity if there is no such entry).
if (current_max != previous_integer->Max()) {
- new_max = typer_->integer->AsRange()->Max();
+ new_max = V8_INFINITY;
for (double const max : kWeakenMaxLimits) {
if (max >= current_max) {
new_max = max;
@@ -2336,13 +2330,11 @@ Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) {
switch (JSFunction::cast(*value)->shared()->builtin_function_id()) {
case kMathRandom:
- return typer_->random_fun_;
+ return typer_->cache_->Get(kRandomFunc0);
case kMathFloor:
- return typer_->weakint_fun1_;
case kMathRound:
- return typer_->weakint_fun1_;
case kMathCeil:
- return typer_->weakint_fun1_;
+ return typer_->cache_->Get(kWeakintFunc1);
// Unary math functions.
case kMathAbs: // TODO(rossberg): can't express overloading
case kMathLog:
« no previous file with comments | « src/compiler/typer.h ('k') | src/heap/heap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698