LCOV - code coverage report
Current view: top level - src/compiler - operation-typer.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 430 447 96.2 %
Date: 2017-04-26 Functions: 74 78 94.9 %

          Line data    Source code
       1             : // Copyright 2016 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/compiler/operation-typer.h"
       6             : 
       7             : #include "src/compiler/common-operator.h"
       8             : #include "src/compiler/type-cache.h"
       9             : #include "src/compiler/types.h"
      10             : #include "src/factory.h"
      11             : #include "src/isolate.h"
      12             : 
      13             : #include "src/objects-inl.h"
      14             : 
      15             : namespace v8 {
      16             : namespace internal {
      17             : namespace compiler {
      18             : 
      19      791544 : OperationTyper::OperationTyper(Isolate* isolate, Zone* zone)
      20      791544 :     : zone_(zone), cache_(TypeCache::Get()) {
      21             :   Factory* factory = isolate->factory();
      22      791541 :   infinity_ = Type::NewConstant(factory->infinity_value(), zone);
      23      791533 :   minus_infinity_ = Type::NewConstant(factory->minus_infinity_value(), zone);
      24             :   Type* truncating_to_zero = Type::MinusZeroOrNaN();
      25             :   DCHECK(!truncating_to_zero->Maybe(Type::Integral32()));
      26             : 
      27      791537 :   singleton_false_ = Type::HeapConstant(factory->false_value(), zone);
      28      791540 :   singleton_true_ = Type::HeapConstant(factory->true_value(), zone);
      29      791540 :   singleton_the_hole_ = Type::HeapConstant(factory->the_hole_value(), zone);
      30      791540 :   signed32ish_ = Type::Union(Type::Signed32(), truncating_to_zero, zone);
      31      791540 :   unsigned32ish_ = Type::Union(Type::Unsigned32(), truncating_to_zero, zone);
      32      791544 : }
      33             : 
      34     1605096 : Type* OperationTyper::Merge(Type* left, Type* right) {
      35     1605096 :   return Type::Union(left, right, zone());
      36             : }
      37             : 
      38      811557 : Type* OperationTyper::WeakenRange(Type* previous_range, Type* current_range) {
      39             :   static const double kWeakenMinLimits[] = {0.0,
      40             :                                             -1073741824.0,
      41             :                                             -2147483648.0,
      42             :                                             -4294967296.0,
      43             :                                             -8589934592.0,
      44             :                                             -17179869184.0,
      45             :                                             -34359738368.0,
      46             :                                             -68719476736.0,
      47             :                                             -137438953472.0,
      48             :                                             -274877906944.0,
      49             :                                             -549755813888.0,
      50             :                                             -1099511627776.0,
      51             :                                             -2199023255552.0,
      52             :                                             -4398046511104.0,
      53             :                                             -8796093022208.0,
      54             :                                             -17592186044416.0,
      55             :                                             -35184372088832.0,
      56             :                                             -70368744177664.0,
      57             :                                             -140737488355328.0,
      58             :                                             -281474976710656.0,
      59             :                                             -562949953421312.0};
      60             :   static const double kWeakenMaxLimits[] = {0.0,
      61             :                                             1073741823.0,
      62             :                                             2147483647.0,
      63             :                                             4294967295.0,
      64             :                                             8589934591.0,
      65             :                                             17179869183.0,
      66             :                                             34359738367.0,
      67             :                                             68719476735.0,
      68             :                                             137438953471.0,
      69             :                                             274877906943.0,
      70             :                                             549755813887.0,
      71             :                                             1099511627775.0,
      72             :                                             2199023255551.0,
      73             :                                             4398046511103.0,
      74             :                                             8796093022207.0,
      75             :                                             17592186044415.0,
      76             :                                             35184372088831.0,
      77             :                                             70368744177663.0,
      78             :                                             140737488355327.0,
      79             :                                             281474976710655.0,
      80             :                                             562949953421311.0};
      81             :   STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits));
      82             : 
      83      405780 :   double current_min = current_range->Min();
      84             :   double new_min = current_min;
      85             :   // Find the closest lower entry in the list of allowed
      86             :   // minima (or negative infinity if there is no such entry).
      87      405779 :   if (current_min != previous_range->Min()) {
      88             :     new_min = -V8_INFINITY;
      89      656822 :     for (double const min : kWeakenMinLimits) {
      90      339323 :       if (min <= current_min) {
      91             :         new_min = min;
      92             :         break;
      93             :       }
      94             :     }
      95             :   }
      96             : 
      97      405778 :   double current_max = current_range->Max();
      98             :   double new_max = current_max;
      99             :   // Find the closest greater entry in the list of allowed
     100             :   // maxima (or infinity if there is no such entry).
     101      405778 :   if (current_max != previous_range->Max()) {
     102             :     new_max = V8_INFINITY;
     103     5534623 :     for (double const max : kWeakenMaxLimits) {
     104     2889882 :       if (max >= current_max) {
     105             :         new_max = max;
     106             :         break;
     107             :       }
     108             :     }
     109             :   }
     110             : 
     111      405778 :   return Type::Range(new_min, new_max, zone());
     112             : }
     113             : 
     114      228693 : Type* OperationTyper::Rangify(Type* type) {
     115      218150 :   if (type->IsRange()) return type;  // Shortcut.
     116      199490 :   if (!type->Is(cache_.kInteger)) {
     117             :     return type;  // Give up on non-integer types.
     118             :   }
     119       10543 :   double min = type->Min();
     120       10543 :   double max = type->Max();
     121             :   // Handle the degenerate case of empty bitset types (such as
     122             :   // OtherUnsigned31 and OtherSigned32 on 64-bit architectures).
     123       10543 :   if (std::isnan(min)) {
     124             :     DCHECK(std::isnan(max));
     125             :     return type;
     126             :   }
     127       10543 :   return Type::Range(min, max, zone());
     128             : }
     129             : 
     130             : namespace {
     131             : 
     132             : // Returns the array's least element, ignoring NaN.
     133             : // There must be at least one non-NaN element.
     134             : // Any -0 is converted to 0.
     135      700421 : double array_min(double a[], size_t n) {
     136             :   DCHECK(n != 0);
     137      700421 :   double x = +V8_INFINITY;
     138     3502097 :   for (size_t i = 0; i < n; ++i) {
     139     2801676 :     if (!std::isnan(a[i])) {
     140     2801614 :       x = std::min(a[i], x);
     141             :     }
     142             :   }
     143             :   DCHECK(!std::isnan(x));
     144      700421 :   return x == 0 ? 0 : x;  // -0 -> 0
     145             : }
     146             : 
     147             : // Returns the array's greatest element, ignoring NaN.
     148             : // There must be at least one non-NaN element.
     149             : // Any -0 is converted to 0.
     150      700418 : double array_max(double a[], size_t n) {
     151             :   DCHECK(n != 0);
     152      700418 :   double x = -V8_INFINITY;
     153     3502050 :   for (size_t i = 0; i < n; ++i) {
     154     2801632 :     if (!std::isnan(a[i])) {
     155     2801590 :       x = std::max(a[i], x);
     156             :     }
     157             :   }
     158             :   DCHECK(!std::isnan(x));
     159      700418 :   return x == 0 ? 0 : x;  // -0 -> 0
     160             : }
     161             : 
     162             : }  // namespace
     163             : 
     164      337745 : Type* OperationTyper::AddRanger(double lhs_min, double lhs_max, double rhs_min,
     165      337754 :                                 double rhs_max) {
     166             :   double results[4];
     167      337745 :   results[0] = lhs_min + rhs_min;
     168      337745 :   results[1] = lhs_min + rhs_max;
     169      337745 :   results[2] = lhs_max + rhs_min;
     170      337745 :   results[3] = lhs_max + rhs_max;
     171             :   // Since none of the inputs can be -0, the result cannot be -0 either.
     172             :   // However, it can be nan (the sum of two infinities of opposite sign).
     173             :   // On the other hand, if none of the "results" above is nan, then the
     174             :   // actual result cannot be nan either.
     175             :   int nans = 0;
     176     1688721 :   for (int i = 0; i < 4; ++i) {
     177     1350976 :     if (std::isnan(results[i])) ++nans;
     178             :   }
     179      337745 :   if (nans == 4) return Type::NaN();
     180             :   Type* type =
     181      337741 :       Type::Range(array_min(results, 4), array_max(results, 4), zone());
     182      337751 :   if (nans > 0) type = Type::Union(type, Type::NaN(), zone());
     183             :   // Examples:
     184             :   //   [-inf, -inf] + [+inf, +inf] = NaN
     185             :   //   [-inf, -inf] + [n, +inf] = [-inf, -inf] \/ NaN
     186             :   //   [-inf, +inf] + [n, +inf] = [-inf, +inf] \/ NaN
     187             :   //   [-inf, m] + [n, +inf] = [-inf, +inf] \/ NaN
     188      337738 :   return type;
     189             : }
     190             : 
     191      332271 : Type* OperationTyper::SubtractRanger(double lhs_min, double lhs_max,
     192      332283 :                                      double rhs_min, double rhs_max) {
     193             :   double results[4];
     194      332271 :   results[0] = lhs_min - rhs_min;
     195      332271 :   results[1] = lhs_min - rhs_max;
     196      332271 :   results[2] = lhs_max - rhs_min;
     197      332271 :   results[3] = lhs_max - rhs_max;
     198             :   // Since none of the inputs can be -0, the result cannot be -0.
     199             :   // However, it can be nan (the subtraction of two infinities of same sign).
     200             :   // On the other hand, if none of the "results" above is nan, then the actual
     201             :   // result cannot be nan either.
     202             :   int nans = 0;
     203     1661355 :   for (int i = 0; i < 4; ++i) {
     204     1329084 :     if (std::isnan(results[i])) ++nans;
     205             :   }
     206      332271 :   if (nans == 4) return Type::NaN();  // [inf..inf] - [inf..inf] (all same sign)
     207             :   Type* type =
     208      332266 :       Type::Range(array_min(results, 4), array_max(results, 4), zone());
     209      332284 :   return nans == 0 ? type : Type::Union(type, Type::NaN(), zone());
     210             :   // Examples:
     211             :   //   [-inf, +inf] - [-inf, +inf] = [-inf, +inf] \/ NaN
     212             :   //   [-inf, -inf] - [-inf, -inf] = NaN
     213             :   //   [-inf, -inf] - [n, +inf] = [-inf, -inf] \/ NaN
     214             :   //   [m, +inf] - [-inf, n] = [-inf, +inf] \/ NaN
     215             : }
     216             : 
     217       68001 : Type* OperationTyper::MultiplyRanger(Type* lhs, Type* rhs) {
     218             :   double results[4];
     219       30498 :   double lmin = lhs->AsRange()->Min();
     220       30498 :   double lmax = lhs->AsRange()->Max();
     221       30498 :   double rmin = rhs->AsRange()->Min();
     222       30498 :   double rmax = rhs->AsRange()->Max();
     223       30498 :   results[0] = lmin * rmin;
     224       30498 :   results[1] = lmin * rmax;
     225       30498 :   results[2] = lmax * rmin;
     226       30498 :   results[3] = lmax * rmax;
     227             :   // If the result may be nan, we give up on calculating a precise type, because
     228             :   // the discontinuity makes it too complicated.  Note that even if none of the
     229             :   // "results" above is nan, the actual result may still be, so we have to do a
     230             :   // different check:
     231       53666 :   bool maybe_nan = (lhs->Maybe(cache_.kSingletonZero) &&
     232       84088 :                     (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) ||
     233       33190 :                    (rhs->Maybe(cache_.kSingletonZero) &&
     234        2755 :                     (lmin == -V8_INFINITY || lmax == +V8_INFINITY));
     235       30498 :   if (maybe_nan) return cache_.kIntegerOrMinusZeroOrNaN;  // Giving up.
     236       54042 :   bool maybe_minuszero = (lhs->Maybe(cache_.kSingletonZero) && rmin < 0) ||
     237       24467 :                          (rhs->Maybe(cache_.kSingletonZero) && lmin < 0);
     238             :   Type* range =
     239       30407 :       Type::Range(array_min(results, 4), array_max(results, 4), zone());
     240             :   return maybe_minuszero ? Type::Union(range, Type::MinusZero(), zone())
     241       37503 :                          : range;
     242             : }
     243             : 
     244     2918494 : Type* OperationTyper::ToNumber(Type* type) {
     245     2264705 :   if (type->Is(Type::Number())) return type;
     246      469731 :   if (type->Is(Type::NullOrUndefined())) {
     247        3312 :     if (type->Is(Type::Null())) return cache_.kSingletonZero;
     248        1988 :     if (type->Is(Type::Undefined())) return Type::NaN();
     249           0 :     return Type::Union(Type::NaN(), cache_.kSingletonZero, zone());
     250             :   }
     251      466421 :   if (type->Is(Type::Boolean())) {
     252       15698 :     if (type->Is(singleton_false_)) return cache_.kSingletonZero;
     253       14464 :     if (type->Is(singleton_true_)) return cache_.kSingletonOne;
     254        4507 :     return cache_.kZeroOrOne;
     255             :   }
     256      458567 :   if (type->Is(Type::NumberOrOddball())) {
     257      326912 :     if (type->Is(Type::NumberOrUndefined())) {
     258       13902 :       type = Type::Union(type, Type::NaN(), zone());
     259      312998 :     } else if (type->Is(Type::NullOrNumber())) {
     260         144 :       type = Type::Union(type, cache_.kSingletonZero, zone());
     261      312858 :     } else if (type->Is(Type::BooleanOrNullOrNumber())) {
     262         696 :       type = Type::Union(type, cache_.kZeroOrOne, zone());
     263             :     } else {
     264      312162 :       type = Type::Union(type, cache_.kZeroOrOneOrNaN, zone());
     265             :     }
     266      326930 :     return Type::Intersect(type, Type::Number(), zone());
     267             :   }
     268             :   return Type::Number();
     269             : }
     270             : 
     271        1315 : Type* OperationTyper::NumberAbs(Type* type) {
     272             :   DCHECK(type->Is(Type::Number()));
     273             : 
     274         496 :   if (!type->IsInhabited()) {
     275             :     return Type::None();
     276             :   }
     277             : 
     278         454 :   bool const maybe_nan = type->Maybe(Type::NaN());
     279         454 :   bool const maybe_minuszero = type->Maybe(Type::MinusZero());
     280         454 :   type = Type::Intersect(type, Type::PlainNumber(), zone());
     281         454 :   double const max = type->Max();
     282         454 :   double const min = type->Min();
     283         454 :   if (min < 0) {
     284         554 :     if (type->Is(cache_.kInteger)) {
     285         372 :       type = Type::Range(0.0, std::max(std::fabs(min), std::fabs(max)), zone());
     286             :     } else {
     287             :       type = Type::PlainNumber();
     288             :     }
     289             :   }
     290         454 :   if (maybe_minuszero) {
     291          72 :     type = Type::Union(type, cache_.kSingletonZero, zone());
     292             :   }
     293         454 :   if (maybe_nan) {
     294         169 :     type = Type::Union(type, Type::NaN(), zone());
     295             :   }
     296         454 :   return type;
     297             : }
     298             : 
     299         115 : Type* OperationTyper::NumberAcos(Type* type) {
     300             :   DCHECK(type->Is(Type::Number()));
     301         115 :   return Type::Number();
     302             : }
     303             : 
     304         113 : Type* OperationTyper::NumberAcosh(Type* type) {
     305             :   DCHECK(type->Is(Type::Number()));
     306         113 :   return Type::Number();
     307             : }
     308             : 
     309         115 : Type* OperationTyper::NumberAsin(Type* type) {
     310             :   DCHECK(type->Is(Type::Number()));
     311         115 :   return Type::Number();
     312             : }
     313             : 
     314         113 : Type* OperationTyper::NumberAsinh(Type* type) {
     315             :   DCHECK(type->Is(Type::Number()));
     316         113 :   return Type::Number();
     317             : }
     318             : 
     319         115 : Type* OperationTyper::NumberAtan(Type* type) {
     320             :   DCHECK(type->Is(Type::Number()));
     321         115 :   return Type::Number();
     322             : }
     323             : 
     324         113 : Type* OperationTyper::NumberAtanh(Type* type) {
     325             :   DCHECK(type->Is(Type::Number()));
     326         113 :   return Type::Number();
     327             : }
     328             : 
     329         100 : Type* OperationTyper::NumberCbrt(Type* type) {
     330             :   DCHECK(type->Is(Type::Number()));
     331         100 :   return Type::Number();
     332             : }
     333             : 
     334       11546 : Type* OperationTyper::NumberCeil(Type* type) {
     335             :   DCHECK(type->Is(Type::Number()));
     336       23092 :   if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type;
     337             :   // TODO(bmeurer): We could infer a more precise type here.
     338       10876 :   return cache_.kIntegerOrMinusZeroOrNaN;
     339             : }
     340             : 
     341         157 : Type* OperationTyper::NumberClz32(Type* type) {
     342             :   DCHECK(type->Is(Type::Number()));
     343         157 :   return cache_.kZeroToThirtyTwo;
     344             : }
     345             : 
     346         205 : Type* OperationTyper::NumberCos(Type* type) {
     347             :   DCHECK(type->Is(Type::Number()));
     348         205 :   return Type::Number();
     349             : }
     350             : 
     351         131 : Type* OperationTyper::NumberCosh(Type* type) {
     352             :   DCHECK(type->Is(Type::Number()));
     353         131 :   return Type::Number();
     354             : }
     355             : 
     356         167 : Type* OperationTyper::NumberExp(Type* type) {
     357             :   DCHECK(type->Is(Type::Number()));
     358         167 :   return Type::Union(Type::PlainNumber(), Type::NaN(), zone());
     359             : }
     360             : 
     361         100 : Type* OperationTyper::NumberExpm1(Type* type) {
     362             :   DCHECK(type->Is(Type::Number()));
     363         100 :   return Type::Union(Type::PlainNumber(), Type::NaN(), zone());
     364             : }
     365             : 
     366       54078 : Type* OperationTyper::NumberFloor(Type* type) {
     367             :   DCHECK(type->Is(Type::Number()));
     368       36916 :   if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type;
     369       17810 :   type = Type::Intersect(type, Type::MinusZeroOrNaN(), zone());
     370       17810 :   type = Type::Union(type, cache_.kInteger, zone());
     371       17810 :   return type;
     372             : }
     373             : 
     374        1434 : Type* OperationTyper::NumberFround(Type* type) {
     375             :   DCHECK(type->Is(Type::Number()));
     376        1434 :   return Type::Number();
     377             : }
     378             : 
     379         363 : Type* OperationTyper::NumberLog(Type* type) {
     380             :   DCHECK(type->Is(Type::Number()));
     381         363 :   return Type::Number();
     382             : }
     383             : 
     384         113 : Type* OperationTyper::NumberLog1p(Type* type) {
     385             :   DCHECK(type->Is(Type::Number()));
     386         113 :   return Type::Number();
     387             : }
     388             : 
     389         100 : Type* OperationTyper::NumberLog2(Type* type) {
     390             :   DCHECK(type->Is(Type::Number()));
     391         100 :   return Type::Number();
     392             : }
     393             : 
     394         100 : Type* OperationTyper::NumberLog10(Type* type) {
     395             :   DCHECK(type->Is(Type::Number()));
     396         100 :   return Type::Number();
     397             : }
     398             : 
     399         268 : Type* OperationTyper::NumberRound(Type* type) {
     400             :   DCHECK(type->Is(Type::Number()));
     401         536 :   if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type;
     402             :   // TODO(bmeurer): We could infer a more precise type here.
     403         169 :   return cache_.kIntegerOrMinusZeroOrNaN;
     404             : }
     405             : 
     406         477 : Type* OperationTyper::NumberSign(Type* type) {
     407             :   DCHECK(type->Is(Type::Number()));
     408         310 :   if (type->Is(cache_.kZeroish)) return type;
     409         108 :   bool maybe_minuszero = type->Maybe(Type::MinusZero());
     410         108 :   bool maybe_nan = type->Maybe(Type::NaN());
     411         108 :   type = Type::Intersect(type, Type::PlainNumber(), zone());
     412         108 :   if (type->Max() < 0.0) {
     413           7 :     type = cache_.kSingletonMinusOne;
     414         101 :   } else if (type->Max() <= 0.0) {
     415           0 :     type = cache_.kMinusOneOrZero;
     416         101 :   } else if (type->Min() > 0.0) {
     417          12 :     type = cache_.kSingletonOne;
     418          89 :   } else if (type->Min() >= 0.0) {
     419           3 :     type = cache_.kZeroOrOne;
     420             :   } else {
     421             :     type = Type::Range(-1.0, 1.0, zone());
     422             :   }
     423         173 :   if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone());
     424         171 :   if (maybe_nan) type = Type::Union(type, Type::NaN(), zone());
     425         108 :   return type;
     426             : }
     427             : 
     428         265 : Type* OperationTyper::NumberSin(Type* type) {
     429             :   DCHECK(type->Is(Type::Number()));
     430         265 :   return Type::Number();
     431             : }
     432             : 
     433         131 : Type* OperationTyper::NumberSinh(Type* type) {
     434             :   DCHECK(type->Is(Type::Number()));
     435         131 :   return Type::Number();
     436             : }
     437             : 
     438         234 : Type* OperationTyper::NumberSqrt(Type* type) {
     439             :   DCHECK(type->Is(Type::Number()));
     440         234 :   return Type::Number();
     441             : }
     442             : 
     443         122 : Type* OperationTyper::NumberTan(Type* type) {
     444             :   DCHECK(type->Is(Type::Number()));
     445         122 :   return Type::Number();
     446             : }
     447             : 
     448         131 : Type* OperationTyper::NumberTanh(Type* type) {
     449             :   DCHECK(type->Is(Type::Number()));
     450         131 :   return Type::Number();
     451             : }
     452             : 
     453        2903 : Type* OperationTyper::NumberTrunc(Type* type) {
     454             :   DCHECK(type->Is(Type::Number()));
     455        5806 :   if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type;
     456             :   // TODO(bmeurer): We could infer a more precise type here.
     457        2677 :   return cache_.kIntegerOrMinusZeroOrNaN;
     458             : }
     459             : 
     460        3531 : Type* OperationTyper::NumberToBoolean(Type* type) {
     461             :   DCHECK(type->Is(Type::Number()));
     462        3531 :   if (!type->IsInhabited()) return Type::None();
     463        6978 :   if (type->Is(cache_.kZeroish)) return singleton_false_;
     464        3483 :   if (type->Is(Type::PlainNumber()) && (type->Max() < 0 || 0 < type->Min())) {
     465         219 :     return singleton_true_;  // Ruled out nan, -0 and +0.
     466             :   }
     467             :   return Type::Boolean();
     468             : }
     469             : 
     470      454597 : Type* OperationTyper::NumberToInt32(Type* type) {
     471             :   DCHECK(type->Is(Type::Number()));
     472             : 
     473      439426 :   if (type->Is(Type::Signed32())) return type;
     474      329378 :   if (type->Is(cache_.kZeroish)) return cache_.kSingletonZero;
     475      319949 :   if (type->Is(signed32ish_)) {
     476             :     return Type::Intersect(Type::Union(type, cache_.kSingletonZero, zone()),
     477       15177 :                            Type::Signed32(), zone());
     478             :   }
     479             :   return Type::Signed32();
     480             : }
     481             : 
     482      143001 : Type* OperationTyper::NumberToUint32(Type* type) {
     483             :   DCHECK(type->Is(Type::Number()));
     484             : 
     485      142851 :   if (type->Is(Type::Unsigned32())) return type;
     486       84537 :   if (type->Is(cache_.kZeroish)) return cache_.kSingletonZero;
     487       79792 :   if (type->Is(unsigned32ish_)) {
     488             :     return Type::Intersect(Type::Union(type, cache_.kSingletonZero, zone()),
     489         151 :                            Type::Unsigned32(), zone());
     490             :   }
     491             :   return Type::Unsigned32();
     492             : }
     493             : 
     494        1038 : Type* OperationTyper::NumberToUint8Clamped(Type* type) {
     495             :   DCHECK(type->Is(Type::Number()));
     496             : 
     497        2076 :   if (type->Is(cache_.kUint8)) return type;
     498         954 :   return cache_.kUint8;
     499             : }
     500             : 
     501        1804 : Type* OperationTyper::NumberSilenceNaN(Type* type) {
     502             :   DCHECK(type->Is(Type::Number()));
     503             :   // TODO(jarin): This is a terrible hack; we definitely need a dedicated type
     504             :   // for the hole (tagged and/or double). Otherwise if the input is the hole
     505             :   // NaN constant, we'd just eliminate this node in JSTypedLowering.
     506        1804 :   if (type->Maybe(Type::NaN())) return Type::Number();
     507         497 :   return type;
     508             : }
     509             : 
     510     2614249 : Type* OperationTyper::NumberAdd(Type* lhs, Type* rhs) {
     511             :   DCHECK(lhs->Is(Type::Number()));
     512             :   DCHECK(rhs->Is(Type::Number()));
     513             : 
     514     1299352 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
     515             :     return Type::None();
     516             :   }
     517             : 
     518             :   // Addition can return NaN if either input can be NaN or we try to compute
     519             :   // the sum of two infinities of opposite sign.
     520      648385 :   bool maybe_nan = lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN());
     521             : 
     522             :   // Addition can yield minus zero only if both inputs can be minus zero.
     523             :   bool maybe_minuszero = true;
     524      648377 :   if (lhs->Maybe(Type::MinusZero())) {
     525      169156 :     lhs = Type::Union(lhs, cache_.kSingletonZero, zone());
     526             :   } else {
     527             :     maybe_minuszero = false;
     528             :   }
     529      648403 :   if (rhs->Maybe(Type::MinusZero())) {
     530      135349 :     rhs = Type::Union(rhs, cache_.kSingletonZero, zone());
     531             :   } else {
     532             :     maybe_minuszero = false;
     533             :   }
     534             : 
     535             :   // We can give more precise types for integers.
     536             :   Type* type = Type::None();
     537      648403 :   lhs = Type::Intersect(lhs, Type::PlainNumber(), zone());
     538      648385 :   rhs = Type::Intersect(rhs, Type::PlainNumber(), zone());
     539     1296636 :   if (lhs->IsInhabited() && rhs->IsInhabited()) {
     540     1674104 :     if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) {
     541      337753 :       type = AddRanger(lhs->Min(), lhs->Max(), rhs->Min(), rhs->Max());
     542             :     } else {
     543      791256 :       if ((lhs->Maybe(minus_infinity_) && rhs->Maybe(infinity_)) ||
     544      183562 :           (rhs->Maybe(minus_infinity_) && lhs->Maybe(infinity_))) {
     545             :         maybe_nan = true;
     546             :       }
     547             :       type = Type::PlainNumber();
     548             :     }
     549             :   }
     550             : 
     551             :   // Take into account the -0 and NaN information computed earlier.
     552      774188 :   if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone());
     553      884848 :   if (maybe_nan) type = Type::Union(type, Type::NaN(), zone());
     554      648362 :   return type;
     555             : }
     556             : 
     557     1255073 : Type* OperationTyper::NumberSubtract(Type* lhs, Type* rhs) {
     558             :   DCHECK(lhs->Is(Type::Number()));
     559             :   DCHECK(rhs->Is(Type::Number()));
     560             : 
     561      766280 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
     562             :     return Type::None();
     563             :   }
     564             : 
     565             :   // Subtraction can return NaN if either input can be NaN or we try to
     566             :   // compute the sum of two infinities of opposite sign.
     567      381636 :   bool maybe_nan = lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN());
     568             : 
     569             :   // Subtraction can yield minus zero if {lhs} can be minus zero and {rhs}
     570             :   // can be zero.
     571             :   bool maybe_minuszero = false;
     572      381637 :   if (lhs->Maybe(Type::MinusZero())) {
     573       41437 :     lhs = Type::Union(lhs, cache_.kSingletonZero, zone());
     574       41437 :     maybe_minuszero = rhs->Maybe(cache_.kSingletonZero);
     575             :   }
     576      381637 :   if (rhs->Maybe(Type::MinusZero())) {
     577        9369 :     rhs = Type::Union(rhs, cache_.kSingletonZero, zone());
     578             :   }
     579             : 
     580             :   // We can give more precise types for integers.
     581             :   Type* type = Type::None();
     582      381637 :   lhs = Type::Intersect(lhs, Type::PlainNumber(), zone());
     583      381637 :   rhs = Type::Intersect(rhs, Type::PlainNumber(), zone());
     584      763114 :   if (lhs->IsInhabited() && rhs->IsInhabited()) {
     585     1096938 :     if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) {
     586      332271 :       type = SubtractRanger(lhs->Min(), lhs->Max(), rhs->Min(), rhs->Max());
     587             :     } else {
     588      138561 :       if ((lhs->Maybe(infinity_) && rhs->Maybe(infinity_)) ||
     589       41748 :           (rhs->Maybe(minus_infinity_) && lhs->Maybe(minus_infinity_))) {
     590             :         maybe_nan = true;
     591             :       }
     592             :       type = Type::PlainNumber();
     593             :     }
     594             :   }
     595             : 
     596             :   // Take into account the -0 and NaN information computed earlier.
     597      390210 :   if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone());
     598      429672 :   if (maybe_nan) type = Type::Union(type, Type::NaN(), zone());
     599      381636 :   return type;
     600             : }
     601             : 
     602      109607 : Type* OperationTyper::NumberMultiply(Type* lhs, Type* rhs) {
     603             :   DCHECK(lhs->Is(Type::Number()));
     604             :   DCHECK(rhs->Is(Type::Number()));
     605             : 
     606      218858 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
     607             :     return Type::None();
     608             :   }
     609             : 
     610      109075 :   lhs = Rangify(lhs);
     611      109075 :   rhs = Rangify(rhs);
     612      217966 :   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
     613      141723 :   if (lhs->IsRange() && rhs->IsRange()) {
     614       30498 :     return MultiplyRanger(lhs, rhs);
     615             :   }
     616             :   return Type::Number();
     617             : }
     618             : 
     619      296785 : Type* OperationTyper::NumberDivide(Type* lhs, Type* rhs) {
     620             :   DCHECK(lhs->Is(Type::Number()));
     621             :   DCHECK(rhs->Is(Type::Number()));
     622             : 
     623      139114 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
     624             :     return Type::None();
     625             :   }
     626             : 
     627      137816 :   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
     628             : 
     629             :   // Division is tricky, so all we do is try ruling out -0 and NaN.
     630             :   bool maybe_nan =
     631       91699 :       lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) ||
     632       47643 :       ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
     633        3205 :        (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
     634       68260 :   lhs = Type::Intersect(lhs, Type::OrderedNumber(), zone());
     635       68261 :   rhs = Type::Intersect(rhs, Type::OrderedNumber(), zone());
     636             : 
     637             :   // Try to rule out -0.
     638             :   bool maybe_minuszero =
     639      120466 :       !lhs->Is(cache_.kInteger) ||
     640      126674 :       (lhs->Maybe(cache_.kZeroish) && rhs->Min() < 0.0) ||
     641       69030 :       (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY);
     642             : 
     643             :   // Take into account the -0 and NaN information computed earlier.
     644             :   Type* type = Type::PlainNumber();
     645      114090 :   if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone());
     646      113097 :   if (maybe_nan) type = Type::Union(type, Type::NaN(), zone());
     647       68261 :   return type;
     648             : }
     649             : 
     650       90204 : Type* OperationTyper::NumberModulus(Type* lhs, Type* rhs) {
     651             :   DCHECK(lhs->Is(Type::Number()));
     652             :   DCHECK(rhs->Is(Type::Number()));
     653             : 
     654             :   // Modulus can yield NaN if either {lhs} or {rhs} are NaN, or
     655             :   // {lhs} is not finite, or the {rhs} is a zero value.
     656       42167 :   bool maybe_nan = lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) ||
     657       38837 :                    lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY;
     658             : 
     659             :   // Deal with -0 inputs, only the signbit of {lhs} matters for the result.
     660             :   bool maybe_minuszero = false;
     661       17407 :   if (lhs->Maybe(Type::MinusZero())) {
     662             :     maybe_minuszero = true;
     663        4080 :     lhs = Type::Union(lhs, cache_.kSingletonZero, zone());
     664             :   }
     665       17409 :   if (rhs->Maybe(Type::MinusZero())) {
     666        1415 :     rhs = Type::Union(rhs, cache_.kSingletonZero, zone());
     667             :   }
     668             : 
     669             :   // Rule out NaN and -0, and check what we can do with the remaining type info.
     670             :   Type* type = Type::None();
     671       17409 :   lhs = Type::Intersect(lhs, Type::PlainNumber(), zone());
     672       17410 :   rhs = Type::Intersect(rhs, Type::PlainNumber(), zone());
     673             : 
     674             :   // We can only derive a meaningful type if both {lhs} and {rhs} are inhabited,
     675             :   // and the {rhs} is not 0, otherwise the result is NaN independent of {lhs}.
     676       34620 :   if (lhs->IsInhabited() && !rhs->Is(cache_.kSingletonZero)) {
     677             :     // Determine the bounds of {lhs} and {rhs}.
     678       16952 :     double const lmin = lhs->Min();
     679       16952 :     double const lmax = lhs->Max();
     680       16950 :     double const rmin = rhs->Min();
     681       16948 :     double const rmax = rhs->Max();
     682             : 
     683             :     // The sign of the result is the sign of the {lhs}.
     684       16948 :     if (lmin < 0.0) maybe_minuszero = true;
     685             : 
     686             :     // For integer inputs {lhs} and {rhs} we can infer a precise type.
     687       46960 :     if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) {
     688       36228 :       double labs = std::max(std::abs(lmin), std::abs(lmax));
     689       36228 :       double rabs = std::max(std::abs(rmin), std::abs(rmax)) - 1;
     690       12076 :       double abs = std::min(labs, rabs);
     691             :       double min = 0.0, max = 0.0;
     692       12076 :       if (lmin >= 0.0) {
     693             :         // {lhs} positive.
     694             :         min = 0.0;
     695             :         max = abs;
     696        9130 :       } else if (lmax <= 0.0) {
     697             :         // {lhs} negative.
     698         633 :         min = 0.0 - abs;
     699             :         max = 0.0;
     700             :       } else {
     701             :         // {lhs} positive or negative.
     702        8497 :         min = 0.0 - abs;
     703             :         max = abs;
     704             :       }
     705             :       type = Type::Range(min, max, zone());
     706             :     } else {
     707             :       type = Type::PlainNumber();
     708             :     }
     709             :   }
     710             : 
     711             :   // Take into account the -0 and NaN information computed earlier.
     712       31025 :   if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone());
     713       24195 :   if (maybe_nan) type = Type::Union(type, Type::NaN(), zone());
     714       17409 :   return type;
     715             : }
     716             : 
     717      200785 : Type* OperationTyper::NumberBitwiseOr(Type* lhs, Type* rhs) {
     718             :   DCHECK(lhs->Is(Type::Number()));
     719             :   DCHECK(rhs->Is(Type::Number()));
     720             : 
     721      200832 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
     722             : 
     723      100013 :   lhs = NumberToInt32(lhs);
     724      100006 :   rhs = NumberToInt32(rhs);
     725             : 
     726      100009 :   double lmin = lhs->Min();
     727      100009 :   double rmin = rhs->Min();
     728      100008 :   double lmax = lhs->Max();
     729      100008 :   double rmax = rhs->Max();
     730             :   // Or-ing any two values results in a value no smaller than their minimum.
     731             :   // Even no smaller than their maximum if both values are non-negative.
     732             :   double min =
     733      200012 :       lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin);
     734      100006 :   double max = kMaxInt;
     735             : 
     736             :   // Or-ing with 0 is essentially a conversion to int32.
     737      100006 :   if (rmin == 0 && rmax == 0) {
     738             :     min = lmin;
     739       89588 :     max = lmax;
     740             :   }
     741      100006 :   if (lmin == 0 && lmax == 0) {
     742             :     min = rmin;
     743        1467 :     max = rmax;
     744             :   }
     745             : 
     746      100006 :   if (lmax < 0 || rmax < 0) {
     747             :     // Or-ing two values of which at least one is negative results in a negative
     748             :     // value.
     749         942 :     max = std::min(max, -1.0);
     750             :   }
     751      200014 :   return Type::Range(min, max, zone());
     752             : }
     753             : 
     754       52934 : Type* OperationTyper::NumberBitwiseAnd(Type* lhs, Type* rhs) {
     755             :   DCHECK(lhs->Is(Type::Number()));
     756             :   DCHECK(rhs->Is(Type::Number()));
     757             : 
     758       52986 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
     759             : 
     760       26346 :   lhs = NumberToInt32(lhs);
     761       26346 :   rhs = NumberToInt32(rhs);
     762             : 
     763       26346 :   double lmin = lhs->Min();
     764       26346 :   double rmin = rhs->Min();
     765       26346 :   double lmax = lhs->Max();
     766       26346 :   double rmax = rhs->Max();
     767             :   double min = kMinInt;
     768             :   // And-ing any two values results in a value no larger than their maximum.
     769             :   // Even no larger than their minimum if both values are non-negative.
     770             :   double max =
     771       52692 :       lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax);
     772             :   // And-ing with a non-negative value x causes the result to be between
     773             :   // zero and x.
     774       26346 :   if (lmin >= 0) {
     775             :     min = 0;
     776        6751 :     max = std::min(max, lmax);
     777             :   }
     778       26346 :   if (rmin >= 0) {
     779             :     min = 0;
     780       19430 :     max = std::min(max, rmax);
     781             :   }
     782       52692 :   return Type::Range(min, max, zone());
     783             : }
     784             : 
     785       15318 : Type* OperationTyper::NumberBitwiseXor(Type* lhs, Type* rhs) {
     786             :   DCHECK(lhs->Is(Type::Number()));
     787             :   DCHECK(rhs->Is(Type::Number()));
     788             : 
     789       30544 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
     790             : 
     791       15185 :   lhs = NumberToInt32(lhs);
     792       15185 :   rhs = NumberToInt32(rhs);
     793             : 
     794       15185 :   double lmin = lhs->Min();
     795       15185 :   double rmin = rhs->Min();
     796       15185 :   double lmax = lhs->Max();
     797       15185 :   double rmax = rhs->Max();
     798       15185 :   if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) {
     799             :     // Xor-ing negative or non-negative values results in a non-negative value.
     800             :     return Type::Unsigned31();
     801             :   }
     802       14772 :   if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) {
     803             :     // Xor-ing a negative and a non-negative value results in a negative value.
     804             :     // TODO(jarin) Use a range here.
     805             :     return Type::Negative32();
     806             :   }
     807       14589 :   return Type::Signed32();
     808             : }
     809             : 
     810       56167 : Type* OperationTyper::NumberShiftLeft(Type* lhs, Type* rhs) {
     811             :   DCHECK(lhs->Is(Type::Number()));
     812             :   DCHECK(rhs->Is(Type::Number()));
     813             : 
     814       72962 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
     815             : 
     816       36229 :   lhs = NumberToInt32(lhs);
     817       36229 :   rhs = NumberToUint32(rhs);
     818             : 
     819       36229 :   int32_t min_lhs = lhs->Min();
     820       36229 :   int32_t max_lhs = lhs->Max();
     821       36229 :   uint32_t min_rhs = rhs->Min();
     822       36228 :   uint32_t max_rhs = rhs->Max();
     823       36228 :   if (max_rhs > 31) {
     824             :     // rhs can be larger than the bitmask
     825             :     max_rhs = 31;
     826             :     min_rhs = 0;
     827             :   }
     828             : 
     829       36228 :   if (max_lhs > (kMaxInt >> max_rhs) || min_lhs < (kMinInt >> max_rhs)) {
     830             :     // overflow possible
     831             :     return Type::Signed32();
     832             :   }
     833             : 
     834             :   double min =
     835       19769 :       std::min(static_cast<int32_t>(static_cast<uint32_t>(min_lhs) << min_rhs),
     836       59307 :                static_cast<int32_t>(static_cast<uint32_t>(min_lhs) << max_rhs));
     837             :   double max =
     838       19769 :       std::max(static_cast<int32_t>(static_cast<uint32_t>(max_lhs) << min_rhs),
     839       59307 :                static_cast<int32_t>(static_cast<uint32_t>(max_lhs) << max_rhs));
     840             : 
     841       19769 :   if (max == kMaxInt && min == kMinInt) return Type::Signed32();
     842       19516 :   return Type::Range(min, max, zone());
     843             : }
     844             : 
     845       79023 : Type* OperationTyper::NumberShiftRight(Type* lhs, Type* rhs) {
     846             :   DCHECK(lhs->Is(Type::Number()));
     847             :   DCHECK(rhs->Is(Type::Number()));
     848             : 
     849       82611 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
     850             : 
     851       41109 :   lhs = NumberToInt32(lhs);
     852       41110 :   rhs = NumberToUint32(rhs);
     853             : 
     854       41110 :   int32_t min_lhs = lhs->Min();
     855       41110 :   int32_t max_lhs = lhs->Max();
     856       41110 :   uint32_t min_rhs = rhs->Min();
     857       41110 :   uint32_t max_rhs = rhs->Max();
     858       41110 :   if (max_rhs > 31) {
     859             :     // rhs can be larger than the bitmask
     860             :     max_rhs = 31;
     861             :     min_rhs = 0;
     862             :   }
     863       82220 :   double min = std::min(min_lhs >> min_rhs, min_lhs >> max_rhs);
     864       82220 :   double max = std::max(max_lhs >> min_rhs, max_lhs >> max_rhs);
     865             : 
     866       41110 :   if (max == kMaxInt && min == kMinInt) return Type::Signed32();
     867       37561 :   return Type::Range(min, max, zone());
     868             : }
     869             : 
     870       30097 : Type* OperationTyper::NumberShiftRightLogical(Type* lhs, Type* rhs) {
     871             :   DCHECK(lhs->Is(Type::Number()));
     872             :   DCHECK(rhs->Is(Type::Number()));
     873             : 
     874       39829 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
     875             : 
     876       19748 :   lhs = NumberToUint32(lhs);
     877       19747 :   rhs = NumberToUint32(rhs);
     878             : 
     879       19747 :   uint32_t min_lhs = lhs->Min();
     880       19747 :   uint32_t max_lhs = lhs->Max();
     881       19747 :   uint32_t min_rhs = rhs->Min();
     882       19747 :   uint32_t max_rhs = rhs->Max();
     883       19747 :   if (max_rhs > 31) {
     884             :     // rhs can be larger than the bitmask
     885             :     max_rhs = 31;
     886             :     min_rhs = 0;
     887             :   }
     888             : 
     889       19747 :   double min = min_lhs >> max_rhs;
     890       19747 :   double max = max_lhs >> min_rhs;
     891             :   DCHECK_LE(0, min);
     892             :   DCHECK_LE(max, kMaxUInt32);
     893             : 
     894       19747 :   if (min == 0 && max == kMaxInt) return Type::Unsigned31();
     895       18811 :   if (min == 0 && max == kMaxUInt32) return Type::Unsigned32();
     896       10065 :   return Type::Range(min, max, zone());
     897             : }
     898             : 
     899         318 : Type* OperationTyper::NumberAtan2(Type* lhs, Type* rhs) {
     900             :   DCHECK(lhs->Is(Type::Number()));
     901             :   DCHECK(rhs->Is(Type::Number()));
     902         318 :   return Type::Number();
     903             : }
     904             : 
     905         271 : Type* OperationTyper::NumberImul(Type* lhs, Type* rhs) {
     906             :   DCHECK(lhs->Is(Type::Number()));
     907             :   DCHECK(rhs->Is(Type::Number()));
     908             :   // TODO(turbofan): We should be able to do better here.
     909         271 :   return Type::Signed32();
     910             : }
     911             : 
     912        1938 : Type* OperationTyper::NumberMax(Type* lhs, Type* rhs) {
     913             :   DCHECK(lhs->Is(Type::Number()));
     914             :   DCHECK(rhs->Is(Type::Number()));
     915        1001 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
     916             :     return Type::None();
     917             :   }
     918         915 :   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) {
     919             :     return Type::NaN();
     920             :   }
     921             :   Type* type = Type::None();
     922             :   // TODO(turbofan): Improve minus zero handling here.
     923         445 :   if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) {
     924          83 :     type = Type::Union(type, Type::NaN(), zone());
     925             :   }
     926         445 :   lhs = Type::Intersect(lhs, Type::OrderedNumber(), zone());
     927         445 :   rhs = Type::Intersect(rhs, Type::OrderedNumber(), zone());
     928        1180 :   if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) {
     929         496 :     double max = std::max(lhs->Max(), rhs->Max());
     930         496 :     double min = std::max(lhs->Min(), rhs->Min());
     931         248 :     type = Type::Union(type, Type::Range(min, max, zone()), zone());
     932             :   } else {
     933         197 :     type = Type::Union(type, Type::Union(lhs, rhs, zone()), zone());
     934             :   }
     935         445 :   return type;
     936             : }
     937             : 
     938        2246 : Type* OperationTyper::NumberMin(Type* lhs, Type* rhs) {
     939             :   DCHECK(lhs->Is(Type::Number()));
     940             :   DCHECK(rhs->Is(Type::Number()));
     941        1106 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
     942             :     return Type::None();
     943             :   }
     944        1013 :   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) {
     945             :     return Type::NaN();
     946             :   }
     947             :   Type* type = Type::None();
     948             :   // TODO(turbofan): Improve minus zero handling here.
     949         494 :   if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) {
     950         188 :     type = Type::Union(type, Type::NaN(), zone());
     951             :   }
     952         494 :   lhs = Type::Intersect(lhs, Type::OrderedNumber(), zone());
     953         494 :   rhs = Type::Intersect(rhs, Type::OrderedNumber(), zone());
     954        1267 :   if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) {
     955         402 :     double max = std::min(lhs->Max(), rhs->Max());
     956         402 :     double min = std::min(lhs->Min(), rhs->Min());
     957         201 :     type = Type::Union(type, Type::Range(min, max, zone()), zone());
     958             :   } else {
     959         293 :     type = Type::Union(type, Type::Union(lhs, rhs, zone()), zone());
     960             :   }
     961         494 :   return type;
     962             : }
     963             : 
     964        2202 : Type* OperationTyper::NumberPow(Type* lhs, Type* rhs) {
     965             :   DCHECK(lhs->Is(Type::Number()));
     966             :   DCHECK(rhs->Is(Type::Number()));
     967             :   // TODO(turbofan): We should be able to do better here.
     968        2202 :   return Type::Number();
     969             : }
     970             : 
     971             : #define SPECULATIVE_NUMBER_BINOP(Name)                            \
     972             :   Type* OperationTyper::Speculative##Name(Type* lhs, Type* rhs) { \
     973             :     lhs = SpeculativeToNumber(lhs);                               \
     974             :     rhs = SpeculativeToNumber(rhs);                               \
     975             :     return Name(lhs, rhs);                                        \
     976             :   }
     977      462314 : SPECULATIVE_NUMBER_BINOP(NumberAdd)
     978       87763 : SPECULATIVE_NUMBER_BINOP(NumberSubtract)
     979       52909 : SPECULATIVE_NUMBER_BINOP(NumberMultiply)
     980       24651 : SPECULATIVE_NUMBER_BINOP(NumberDivide)
     981        8364 : SPECULATIVE_NUMBER_BINOP(NumberModulus)
     982       36574 : SPECULATIVE_NUMBER_BINOP(NumberBitwiseOr)
     983       13678 : SPECULATIVE_NUMBER_BINOP(NumberBitwiseAnd)
     984        3239 : SPECULATIVE_NUMBER_BINOP(NumberBitwiseXor)
     985        5123 : SPECULATIVE_NUMBER_BINOP(NumberShiftLeft)
     986       14774 : SPECULATIVE_NUMBER_BINOP(NumberShiftRight)
     987        4197 : SPECULATIVE_NUMBER_BINOP(NumberShiftRightLogical)
     988             : #undef SPECULATIVE_NUMBER_BINOP
     989             : 
     990     1440753 : Type* OperationTyper::SpeculativeToNumber(Type* type) {
     991     1440753 :   return ToNumber(Type::Intersect(type, Type::NumberOrOddball(), zone()));
     992             : }
     993             : 
     994           0 : Type* OperationTyper::ToPrimitive(Type* type) {
     995           0 :   if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) {
     996           0 :     return type;
     997             :   }
     998             :   return Type::Primitive();
     999             : }
    1000             : 
    1001           0 : Type* OperationTyper::Invert(Type* type) {
    1002             :   DCHECK(type->Is(Type::Boolean()));
    1003             :   DCHECK(type->IsInhabited());
    1004           0 :   if (type->Is(singleton_false())) return singleton_true();
    1005           0 :   if (type->Is(singleton_true())) return singleton_false();
    1006             :   return type;
    1007             : }
    1008             : 
    1009           0 : OperationTyper::ComparisonOutcome OperationTyper::Invert(
    1010             :     ComparisonOutcome outcome) {
    1011             :   ComparisonOutcome result(0);
    1012           0 :   if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined;
    1013           0 :   if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse;
    1014           0 :   if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue;
    1015           0 :   return result;
    1016             : }
    1017             : 
    1018           0 : Type* OperationTyper::FalsifyUndefined(ComparisonOutcome outcome) {
    1019           0 :   if ((outcome & kComparisonFalse) != 0 ||
    1020             :       (outcome & kComparisonUndefined) != 0) {
    1021             :     return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
    1022           0 :                                             : singleton_false();
    1023             :   }
    1024             :   // Type should be non empty, so we know it should be true.
    1025             :   DCHECK((outcome & kComparisonTrue) != 0);
    1026           0 :   return singleton_true();
    1027             : }
    1028             : 
    1029        4560 : Type* OperationTyper::CheckFloat64Hole(Type* type) {
    1030        1552 :   if (type->Maybe(Type::Hole())) {
    1031             :     // Turn "the hole" into undefined.
    1032        1504 :     type = Type::Intersect(type, Type::Number(), zone());
    1033        1504 :     type = Type::Union(type, Type::Undefined(), zone());
    1034             :   }
    1035        1552 :   return type;
    1036             : }
    1037             : 
    1038        4978 : Type* OperationTyper::CheckNumber(Type* type) {
    1039        4978 :   return Type::Intersect(type, Type::Number(), zone());
    1040             : }
    1041             : 
    1042       31591 : Type* OperationTyper::TypeTypeGuard(const Operator* sigma_op, Type* input) {
    1043       31591 :   return Type::Intersect(input, TypeGuardTypeOf(sigma_op), zone());
    1044             : }
    1045             : 
    1046             : }  // namespace compiler
    1047             : }  // namespace internal
    1048             : }  // namespace v8

Generated by: LCOV version 1.10