Commit 08dc4394 authored by neis's avatar neis Committed by Commit bot

Construct Range rather than Constant when typing integers.

Also clarify some comments.

R=jarin@chromium.org
BUG=

Review URL: https://codereview.chromium.org/1328193003

Cr-Commit-Position: refs/heads/master@{#30708}
parent d90a4047
......@@ -48,6 +48,8 @@ Typer::Typer(Isolate* isolate, Graph* graph, Type::FunctionType* function_type)
Type* infinity = Type::Constant(factory->infinity_value(), zone);
Type* minus_infinity = Type::Constant(factory->minus_infinity_value(), zone);
// TODO(neis): Unfortunately, the infinities created in other places might
// be different ones (eg the result of NewNumber in TypeNumberConstant).
Type* truncating_to_zero =
Type::Union(Type::Union(infinity, minus_infinity, zone),
Type::MinusZeroOrNaN(), zone);
......@@ -535,8 +537,11 @@ Bounds Typer::Visitor::TypeFloat64Constant(Node* node) {
Bounds Typer::Visitor::TypeNumberConstant(Node* node) {
Factory* f = isolate()->factory();
return Bounds(Type::Constant(
f->NewNumber(OpParameter<double>(node)), zone()));
double number = OpParameter<double>(node);
if (Type::IsInteger(number)) {
return Bounds(Type::Range(number, number, zone()));
}
return Bounds(Type::Constant(f->NewNumber(number), zone()));
}
......@@ -2288,6 +2293,9 @@ Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
#undef TYPED_ARRAY_CASE
}
}
if (Type::IsInteger(*value)) {
return Type::Range(value->Number(), value->Number(), zone());
}
return Type::Constant(value, zone());
}
......
......@@ -930,7 +930,7 @@ int TypeImpl<Config>::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(),
// clear. Moreover, if we have a canonical range (such as Signed32),
// we want to produce a bitset rather than a range.
template <class Config>
typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeRangeAndBitset(
......@@ -942,8 +942,8 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeRangeAndBitset(
return range;
}
// If the range is contained within the bitset, return an empty range
// (but make sure we take the representation).
// If the range is semantically contained within the bitset, return None and
// leave the bitset untouched.
bitset range_lub = SEMANTIC(range->BitsetLub());
if (BitsetType::Is(BitsetType::NumberBits(range_lub), *bits)) {
return None(region);
......@@ -993,7 +993,7 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
// Figure out the representation of the result.
// The rest of the method should not change this representation and
// it should make any decisions based on representations (i.e.,
// it should not make any decisions based on representations (i.e.,
// it should only use the semantic part of types).
const bitset representation =
type1->Representation() | type2->Representation();
......
......@@ -95,10 +95,13 @@ namespace internal {
// RANGE TYPES
//
// A range type represents a continuous integer interval by its minimum and
// maximum value. Either value might be an infinity.
// maximum value. Either value may be an infinity, in which case that infinity
// itself is also included in the range. A range never contains NaN or -0.
//
// Constant(v) is considered a subtype of Range(x..y) if v happens to be an
// integer between x and y.
// If a value v happens to be an integer n, then Constant(v) is considered a
// subtype of Range(n, n) (and therefore also a subtype of any larger range).
// In order to avoid large unions, however, it is usually a good idea to use
// Range rather than Constant.
//
//
// PREDICATES
......@@ -513,11 +516,17 @@ class TypeImpl : public Config::Base {
double Min();
double Max();
// Extracts a range from the type. If the type is a range, it just
// returns it; if it is a union, it returns the range component.
// Note that it does not contain range for constants.
// Extracts a range from the type: if the type is a range or a union
// containing a range, that range is returned; otherwise, NULL is returned.
RangeType* GetRange();
static bool IsInteger(double x) {
return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
}
static bool IsInteger(i::Object* x) {
return x->IsNumber() && IsInteger(x->Number());
}
int NumClasses();
int NumConstants();
......@@ -589,13 +598,6 @@ class TypeImpl : public Config::Base {
bool SlowIs(TypeImpl* that);
bool SemanticIs(TypeImpl* that);
static bool IsInteger(double x) {
return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
}
static bool IsInteger(i::Object* x) {
return x->IsNumber() && IsInteger(x->Number());
}
struct Limits {
double min;
double max;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment