| Index: src/compiler/typer.cc | 
| diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc | 
| index 6ef16df97c46264ee39907b37fe91f6e3a859bca..432832e235f1d7f5bac41a1382abfd3cb700c1c8 100644 | 
| --- a/src/compiler/typer.cc | 
| +++ b/src/compiler/typer.cc | 
| @@ -29,10 +29,8 @@ class Typer::Decorator final : public GraphDecorator { | 
| Typer* const typer_; | 
| }; | 
|  | 
| - | 
| Typer::Typer(Isolate* isolate, Graph* graph, Flags flags, | 
| -             CompilationDependencies* dependencies, | 
| -             Type::FunctionType* function_type) | 
| +             CompilationDependencies* dependencies, FunctionType* function_type) | 
| : isolate_(isolate), | 
| graph_(graph), | 
| flags_(flags), | 
| @@ -243,11 +241,10 @@ class Typer::Visitor : public Reducer { | 
| static Type* NumberToInt32(Type*, Typer*); | 
| static Type* NumberToUint32(Type*, Typer*); | 
|  | 
| -  static Type* JSAddRanger(Type::RangeType*, Type::RangeType*, Typer*); | 
| -  static Type* JSSubtractRanger(Type::RangeType*, Type::RangeType*, Typer*); | 
| -  static Type* JSMultiplyRanger(Type::RangeType*, Type::RangeType*, Typer*); | 
| -  static Type* JSDivideRanger(Type::RangeType*, Type::RangeType*, Typer*); | 
| -  static Type* JSModulusRanger(Type::RangeType*, Type::RangeType*, Typer*); | 
| +  static Type* JSAddRanger(RangeType*, RangeType*, Typer*); | 
| +  static Type* JSSubtractRanger(RangeType*, RangeType*, Typer*); | 
| +  static Type* JSDivideRanger(RangeType*, RangeType*, Typer*); | 
| +  static Type* JSModulusRanger(RangeType*, RangeType*, Typer*); | 
|  | 
| static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*); | 
|  | 
| @@ -513,9 +510,7 @@ Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) { | 
|  | 
| // Control operators. | 
|  | 
| - | 
| -Type* Typer::Visitor::TypeStart(Node* node) { return Type::Internal(zone()); } | 
| - | 
| +Type* Typer::Visitor::TypeStart(Node* node) { return Type::Internal(); } | 
|  | 
| Type* Typer::Visitor::TypeIfException(Node* node) { return Type::Any(); } | 
|  | 
| @@ -524,7 +519,7 @@ Type* Typer::Visitor::TypeIfException(Node* node) { return Type::Any(); } | 
|  | 
|  | 
| Type* Typer::Visitor::TypeParameter(Node* node) { | 
| -  if (Type::FunctionType* function_type = typer_->function_type()) { | 
| +  if (FunctionType* function_type = typer_->function_type()) { | 
| int const index = ParameterIndexOf(node->op()); | 
| if (index >= 0 && index < function_type->Arity()) { | 
| return function_type->Parameter(index); | 
| @@ -578,7 +573,7 @@ Type* Typer::Visitor::TypeHeapConstant(Node* node) { | 
|  | 
|  | 
| Type* Typer::Visitor::TypeExternalConstant(Node* node) { | 
| -  return Type::Internal(zone()); | 
| +  return Type::Internal(); | 
| } | 
|  | 
|  | 
| @@ -627,22 +622,15 @@ Type* Typer::Visitor::TypeFinishRegion(Node* node) { return Operand(node, 0); } | 
|  | 
| Type* Typer::Visitor::TypeFrameState(Node* node) { | 
| // TODO(rossberg): Ideally FrameState wouldn't have a value output. | 
| -  return Type::Internal(zone()); | 
| -} | 
| - | 
| - | 
| -Type* Typer::Visitor::TypeStateValues(Node* node) { | 
| -  return Type::Internal(zone()); | 
| +  return Type::Internal(); | 
| } | 
|  | 
| +Type* Typer::Visitor::TypeStateValues(Node* node) { return Type::Internal(); } | 
|  | 
| -Type* Typer::Visitor::TypeObjectState(Node* node) { | 
| -  return Type::Internal(zone()); | 
| -} | 
| - | 
| +Type* Typer::Visitor::TypeObjectState(Node* node) { return Type::Internal(); } | 
|  | 
| Type* Typer::Visitor::TypeTypedStateValues(Node* node) { | 
| -  return Type::Internal(zone()); | 
| +  return Type::Internal(); | 
| } | 
|  | 
|  | 
| @@ -955,9 +943,7 @@ static double array_max(double a[], size_t n) { | 
| return x == 0 ? 0 : x;  // -0 -> 0 | 
| } | 
|  | 
| - | 
| -Type* Typer::Visitor::JSAddRanger(Type::RangeType* lhs, Type::RangeType* rhs, | 
| -                                  Typer* t) { | 
| +Type* Typer::Visitor::JSAddRanger(RangeType* lhs, RangeType* rhs, Typer* t) { | 
| double results[4]; | 
| results[0] = lhs->Min() + rhs->Min(); | 
| results[1] = lhs->Min() + rhs->Max(); | 
| @@ -1003,9 +989,8 @@ Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) { | 
| return Type::Number(); | 
| } | 
|  | 
| - | 
| -Type* Typer::Visitor::JSSubtractRanger(Type::RangeType* lhs, | 
| -                                       Type::RangeType* rhs, Typer* t) { | 
| +Type* Typer::Visitor::JSSubtractRanger(RangeType* lhs, RangeType* rhs, | 
| +                                       Typer* t) { | 
| double results[4]; | 
| results[0] = lhs->Min() - rhs->Min(); | 
| results[1] = lhs->Min() - rhs->Max(); | 
| @@ -1042,41 +1027,38 @@ Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) { | 
| } | 
|  | 
|  | 
| -Type* Typer::Visitor::JSMultiplyRanger(Type::RangeType* lhs, | 
| -                                       Type::RangeType* rhs, Typer* t) { | 
| -  double results[4]; | 
| -  double lmin = lhs->Min(); | 
| -  double lmax = lhs->Max(); | 
| -  double rmin = rhs->Min(); | 
| -  double rmax = rhs->Max(); | 
| -  results[0] = lmin * rmin; | 
| -  results[1] = lmin * rmax; | 
| -  results[2] = lmax * rmin; | 
| -  results[3] = lmax * rmax; | 
| -  // If the result may be nan, we give up on calculating a precise type, because | 
| -  // 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->cache_.kSingletonZero) && | 
| -                    (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) || | 
| -                   (rhs->Maybe(t->cache_.kSingletonZero) && | 
| -                    (lmin == -V8_INFINITY || lmax == +V8_INFINITY)); | 
| -  if (maybe_nan) return t->cache_.kIntegerOrMinusZeroOrNaN;  // Giving up. | 
| -  bool maybe_minuszero = (lhs->Maybe(t->cache_.kSingletonZero) && rmin < 0) || | 
| -                         (rhs->Maybe(t->cache_.kSingletonZero) && 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()) | 
| -                         : range; | 
| -} | 
| - | 
| - | 
| Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { | 
| lhs = Rangify(ToNumber(lhs, t), t); | 
| rhs = Rangify(ToNumber(rhs, t), t); | 
| if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 
| if (lhs->IsRange() && rhs->IsRange()) { | 
| -    return JSMultiplyRanger(lhs->AsRange(), rhs->AsRange(), t); | 
| +    double results[4]; | 
| +    double lmin = lhs->AsRange()->Min(); | 
| +    double lmax = lhs->AsRange()->Max(); | 
| +    double rmin = rhs->AsRange()->Min(); | 
| +    double rmax = rhs->AsRange()->Max(); | 
| +    results[0] = lmin * rmin; | 
| +    results[1] = lmin * rmax; | 
| +    results[2] = lmax * rmin; | 
| +    results[3] = lmax * rmax; | 
| +    // If the result may be nan, we give up on calculating a precise type, | 
| +    // because | 
| +    // 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->cache_.kSingletonZero) && | 
| +                      (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) || | 
| +                     (rhs->Maybe(t->cache_.kSingletonZero) && | 
| +                      (lmin == -V8_INFINITY || lmax == +V8_INFINITY)); | 
| +    if (maybe_nan) return t->cache_.kIntegerOrMinusZeroOrNaN;  // Giving up. | 
| +    bool maybe_minuszero = (lhs->Maybe(t->cache_.kSingletonZero) && rmin < 0) || | 
| +                           (rhs->Maybe(t->cache_.kSingletonZero) && 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()) | 
| +                           : range; | 
| } | 
| return Type::Number(); | 
| } | 
| @@ -1095,9 +1077,8 @@ Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { | 
| return maybe_nan ? Type::Number() : Type::OrderedNumber(); | 
| } | 
|  | 
| - | 
| -Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs, | 
| -                                      Type::RangeType* rhs, Typer* t) { | 
| +Type* Typer::Visitor::JSModulusRanger(RangeType* lhs, RangeType* rhs, | 
| +                                      Typer* t) { | 
| double lmin = lhs->Min(); | 
| double lmax = lhs->Max(); | 
| double rmin = rhs->Min(); | 
| @@ -1291,8 +1272,8 @@ Type* Typer::Visitor::TypeJSLoadNamed(Node* node) { | 
| } else if (receiver->IsClass() && | 
| receiver->AsClass()->Map()->IsJSFunctionMap()) { | 
| Handle<Map> map = receiver->AsClass()->Map(); | 
| -      return map->has_non_instance_prototype() ? Type::Primitive(zone()) | 
| -                                               : Type::Receiver(zone()); | 
| +      return map->has_non_instance_prototype() ? Type::Primitive() | 
| +                                               : Type::Receiver(); | 
| } | 
| } | 
| return Type::Any(); | 
| @@ -1340,8 +1321,8 @@ Type* Typer::Visitor::Weaken(Node* node, Type* current_type, | 
| // Only weaken if there is range involved; we should converge quickly | 
| // for all other types (the exception is a union of many constants, | 
| // but we currently do not increase the number of constants in unions). | 
| -    Type::RangeType* previous = previous_integer->GetRange(); | 
| -    Type::RangeType* current = current_integer->GetRange(); | 
| +    Type* previous = previous_integer->GetRange(); | 
| +    Type* current = current_integer->GetRange(); | 
| if (current == nullptr || previous == nullptr) { | 
| return current_type; | 
| } | 
| @@ -1402,19 +1383,12 @@ Type* Typer::Visitor::TypeJSStoreGlobal(Node* node) { | 
|  | 
|  | 
| Type* Typer::Visitor::TypeJSDeleteProperty(Node* node) { | 
| -  return Type::Boolean(zone()); | 
| -} | 
| - | 
| - | 
| -Type* Typer::Visitor::TypeJSHasProperty(Node* node) { | 
| -  return Type::Boolean(zone()); | 
| +  return Type::Boolean(); | 
| } | 
|  | 
| +Type* Typer::Visitor::TypeJSHasProperty(Node* node) { return Type::Boolean(); } | 
|  | 
| -Type* Typer::Visitor::TypeJSInstanceOf(Node* node) { | 
| -  return Type::Boolean(zone()); | 
| -} | 
| - | 
| +Type* Typer::Visitor::TypeJSInstanceOf(Node* node) { return Type::Boolean(); } | 
|  | 
| // JS context operators. | 
|  | 
| @@ -1563,7 +1537,7 @@ Type* Typer::Visitor::TypeJSCallRuntime(Node* node) { | 
| case Runtime::kInlineIsFunction: | 
| case Runtime::kInlineIsRegExp: | 
| case Runtime::kInlineIsJSReceiver: | 
| -      return Type::Boolean(zone()); | 
| +      return Type::Boolean(); | 
| case Runtime::kInlineDoubleLo: | 
| case Runtime::kInlineDoubleHi: | 
| return Type::Signed32(); | 
| @@ -1627,11 +1601,7 @@ Type* Typer::Visitor::TypeJSForInPrepare(Node* node) { | 
| return Type::Tuple(cache_type, cache_array, cache_length, zone()); | 
| } | 
|  | 
| - | 
| -Type* Typer::Visitor::TypeJSForInDone(Node* node) { | 
| -  return Type::Boolean(zone()); | 
| -} | 
| - | 
| +Type* Typer::Visitor::TypeJSForInDone(Node* node) { return Type::Boolean(); } | 
|  | 
| Type* Typer::Visitor::TypeJSForInStep(Node* node) { | 
| STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength); | 
| @@ -1653,82 +1623,57 @@ Type* Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); } | 
|  | 
| // Simplified operators. | 
|  | 
| - | 
| -Type* Typer::Visitor::TypeBooleanNot(Node* node) { | 
| -  return Type::Boolean(zone()); | 
| -} | 
| - | 
| +Type* Typer::Visitor::TypeBooleanNot(Node* node) { return Type::Boolean(); } | 
|  | 
| Type* Typer::Visitor::TypeBooleanToNumber(Node* node) { | 
| return TypeUnaryOp(node, ToNumber); | 
| } | 
|  | 
| +Type* Typer::Visitor::TypeNumberEqual(Node* node) { return Type::Boolean(); } | 
|  | 
| -Type* Typer::Visitor::TypeNumberEqual(Node* node) { | 
| -  return Type::Boolean(zone()); | 
| -} | 
| - | 
| - | 
| -Type* Typer::Visitor::TypeNumberLessThan(Node* node) { | 
| -  return Type::Boolean(zone()); | 
| -} | 
| - | 
| +Type* Typer::Visitor::TypeNumberLessThan(Node* node) { return Type::Boolean(); } | 
|  | 
| Type* Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) { | 
| -  return Type::Boolean(zone()); | 
| -} | 
| - | 
| - | 
| -Type* Typer::Visitor::TypeNumberAdd(Node* node) { return Type::Number(zone()); } | 
| - | 
| - | 
| -Type* Typer::Visitor::TypeNumberSubtract(Node* node) { | 
| -  return Type::Number(zone()); | 
| -} | 
| - | 
| - | 
| -Type* Typer::Visitor::TypeNumberMultiply(Node* node) { | 
| -  return Type::Number(zone()); | 
| +  return Type::Boolean(); | 
| } | 
|  | 
| +Type* Typer::Visitor::TypeNumberAdd(Node* node) { return Type::Number(); } | 
|  | 
| -Type* Typer::Visitor::TypeNumberDivide(Node* node) { | 
| -  return Type::Number(zone()); | 
| -} | 
| +Type* Typer::Visitor::TypeNumberSubtract(Node* node) { return Type::Number(); } | 
|  | 
| +Type* Typer::Visitor::TypeNumberMultiply(Node* node) { return Type::Number(); } | 
|  | 
| -Type* Typer::Visitor::TypeNumberModulus(Node* node) { | 
| -  return Type::Number(zone()); | 
| -} | 
| +Type* Typer::Visitor::TypeNumberDivide(Node* node) { return Type::Number(); } | 
|  | 
| +Type* Typer::Visitor::TypeNumberModulus(Node* node) { return Type::Number(); } | 
|  | 
| Type* Typer::Visitor::TypeNumberBitwiseOr(Node* node) { | 
| -  return Type::Signed32(zone()); | 
| +  return Type::Signed32(); | 
| } | 
|  | 
|  | 
| Type* Typer::Visitor::TypeNumberBitwiseXor(Node* node) { | 
| -  return Type::Signed32(zone()); | 
| +  return Type::Signed32(); | 
| } | 
|  | 
|  | 
| Type* Typer::Visitor::TypeNumberBitwiseAnd(Node* node) { | 
| -  return Type::Signed32(zone()); | 
| +  return Type::Signed32(); | 
| } | 
|  | 
|  | 
| Type* Typer::Visitor::TypeNumberShiftLeft(Node* node) { | 
| -  return Type::Signed32(zone()); | 
| +  return Type::Signed32(); | 
| } | 
|  | 
|  | 
| Type* Typer::Visitor::TypeNumberShiftRight(Node* node) { | 
| -  return Type::Signed32(zone()); | 
| +  return Type::Signed32(); | 
| } | 
|  | 
|  | 
| Type* Typer::Visitor::TypeNumberShiftRightLogical(Node* node) { | 
| -  return Type::Unsigned32(zone()); | 
| +  return Type::Unsigned32(); | 
| } | 
|  | 
|  | 
| @@ -1743,7 +1688,7 @@ Type* Typer::Visitor::TypeNumberToUint32(Node* node) { | 
|  | 
|  | 
| Type* Typer::Visitor::TypeNumberIsHoleNaN(Node* node) { | 
| -  return Type::Boolean(zone()); | 
| +  return Type::Boolean(); | 
| } | 
|  | 
|  | 
| @@ -1765,19 +1710,12 @@ Type* Typer::Visitor::TypeReferenceEqual(Node* node) { | 
| return TypeBinaryOp(node, ReferenceEqualTyper); | 
| } | 
|  | 
| +Type* Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); } | 
|  | 
| -Type* Typer::Visitor::TypeStringEqual(Node* node) { | 
| -  return Type::Boolean(zone()); | 
| -} | 
| - | 
| - | 
| -Type* Typer::Visitor::TypeStringLessThan(Node* node) { | 
| -  return Type::Boolean(zone()); | 
| -} | 
| - | 
| +Type* Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); } | 
|  | 
| Type* Typer::Visitor::TypeStringLessThanOrEqual(Node* node) { | 
| -  return Type::Boolean(zone()); | 
| +  return Type::Boolean(); | 
| } | 
|  | 
|  | 
|  |