LCOV - code coverage report
Current view: top level - src/compiler - operation-typer.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 441 457 96.5 %
Date: 2017-10-20 Functions: 77 81 95.1 %

          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      887467 : OperationTyper::OperationTyper(Isolate* isolate, Zone* zone)
      20      887467 :     : zone_(zone), cache_(TypeCache::Get()) {
      21             :   Factory* factory = isolate->factory();
      22      887471 :   infinity_ = Type::NewConstant(factory->infinity_value(), zone);
      23      887472 :   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      887472 :   singleton_false_ = Type::HeapConstant(factory->false_value(), zone);
      28      887473 :   singleton_true_ = Type::HeapConstant(factory->true_value(), zone);
      29      887473 :   singleton_the_hole_ = Type::HeapConstant(factory->the_hole_value(), zone);
      30      887473 :   signed32ish_ = Type::Union(Type::Signed32(), truncating_to_zero, zone);
      31      887470 :   unsigned32ish_ = Type::Union(Type::Unsigned32(), truncating_to_zero, zone);
      32      887471 : }
      33             : 
      34     1346970 : Type* OperationTyper::Merge(Type* left, Type* right) {
      35     1346970 :   return Type::Union(left, right, zone());
      36             : }
      37             : 
      38      826027 : 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      413014 :   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      413014 :   if (current_min != previous_range->Min()) {
      88             :     new_min = -V8_INFINITY;
      89      388034 :     for (double const min : kWeakenMinLimits) {
      90      200087 :       if (min <= current_min) {
      91             :         new_min = min;
      92             :         break;
      93             :       }
      94             :     }
      95             :   }
      96             : 
      97      413013 :   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      413014 :   if (current_max != previous_range->Max()) {
     102             :     new_max = V8_INFINITY;
     103     6046077 :     for (double const max : kWeakenMaxLimits) {
     104     3159027 :       if (max >= current_max) {
     105             :         new_max = max;
     106             :         break;
     107             :       }
     108             :     }
     109             :   }
     110             : 
     111      413013 :   return Type::Range(new_min, new_max, zone());
     112             : }
     113             : 
     114      147190 : Type* OperationTyper::Rangify(Type* type) {
     115      139014 :   if (type->IsRange()) return type;  // Shortcut.
     116      108430 :   if (!type->Is(cache_.kInteger)) {
     117             :     return type;  // Give up on non-integer types.
     118             :   }
     119        8176 :   double min = type->Min();
     120        8176 :   double max = type->Max();
     121             :   // Handle the degenerate case of empty bitset types (such as
     122             :   // OtherUnsigned31 and OtherSigned32 on 64-bit architectures).
     123        8176 :   if (std::isnan(min)) {
     124             :     DCHECK(std::isnan(max));
     125             :     return type;
     126             :   }
     127        8176 :   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      820408 : double array_min(double a[], size_t n) {
     136             :   DCHECK_NE(0, n);
     137      820408 :   double x = +V8_INFINITY;
     138     4102032 :   for (size_t i = 0; i < n; ++i) {
     139     3281624 :     if (!std::isnan(a[i])) {
     140     3281410 :       x = std::min(a[i], x);
     141             :     }
     142             :   }
     143             :   DCHECK(!std::isnan(x));
     144      820408 :   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      820402 : double array_max(double a[], size_t n) {
     151             :   DCHECK_NE(0, n);
     152      820402 :   double x = -V8_INFINITY;
     153     4101938 :   for (size_t i = 0; i < n; ++i) {
     154     3281536 :     if (!std::isnan(a[i])) {
     155     3281322 :       x = std::max(a[i], x);
     156             :     }
     157             :   }
     158             :   DCHECK(!std::isnan(x));
     159      820402 :   return x == 0 ? 0 : x;  // -0 -> 0
     160             : }
     161             : 
     162             : }  // namespace
     163             : 
     164      381459 : Type* OperationTyper::AddRanger(double lhs_min, double lhs_max, double rhs_min,
     165      381490 :                                 double rhs_max) {
     166             :   double results[4];
     167      381459 :   results[0] = lhs_min + rhs_min;
     168      381459 :   results[1] = lhs_min + rhs_max;
     169      381459 :   results[2] = lhs_max + rhs_min;
     170      381459 :   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     1907271 :   for (int i = 0; i < 4; ++i) {
     177     1525812 :     if (std::isnan(results[i])) ++nans;
     178             :   }
     179      381459 :   if (nans == 4) return Type::NaN();
     180             :   Type* type =
     181      381459 :       Type::Range(array_min(results, 4), array_max(results, 4), zone());
     182      381473 :   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      381441 :   return type;
     189             : }
     190             : 
     191      409041 : Type* OperationTyper::SubtractRanger(double lhs_min, double lhs_max,
     192      409124 :                                      double rhs_min, double rhs_max) {
     193             :   double results[4];
     194      409041 :   results[0] = lhs_min - rhs_min;
     195      409041 :   results[1] = lhs_min - rhs_max;
     196      409041 :   results[2] = lhs_max - rhs_min;
     197      409041 :   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     2045205 :   for (int i = 0; i < 4; ++i) {
     204     1636164 :     if (std::isnan(results[i])) ++nans;
     205             :   }
     206      409041 :   if (nans == 4) return Type::NaN();  // [inf..inf] - [inf..inf] (all same sign)
     207             :   Type* type =
     208      409035 :       Type::Range(array_min(results, 4), array_max(results, 4), zone());
     209      409125 :   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       73897 : Type* OperationTyper::MultiplyRanger(Type* lhs, Type* rhs) {
     218             :   double results[4];
     219       29978 :   double lmin = lhs->AsRange()->Min();
     220       29978 :   double lmax = lhs->AsRange()->Max();
     221       29978 :   double rmin = rhs->AsRange()->Min();
     222       29978 :   double rmax = rhs->AsRange()->Max();
     223       29978 :   results[0] = lmin * rmin;
     224       29978 :   results[1] = lmin * rmax;
     225       29978 :   results[2] = lmax * rmin;
     226       29978 :   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       53708 :   bool maybe_nan = (lhs->Maybe(cache_.kSingletonZero) &&
     232       83609 :                     (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) ||
     233       32643 :                    (rhs->Maybe(cache_.kSingletonZero) &&
     234        2725 :                     (lmin == -V8_INFINITY || lmax == +V8_INFINITY));
     235       29978 :   if (maybe_nan) return cache_.kIntegerOrMinusZeroOrNaN;  // Giving up.
     236       46150 :   bool maybe_minuszero = (lhs->Maybe(cache_.kSingletonZero) && rmin < 0) ||
     237       17115 :                          (rhs->Maybe(cache_.kSingletonZero) && lmin < 0);
     238             :   Type* range =
     239       29901 :       Type::Range(array_min(results, 4), array_max(results, 4), zone());
     240             :   return maybe_minuszero ? Type::Union(range, Type::MinusZero(), zone())
     241       43919 :                          : range;
     242             : }
     243             : 
     244     3007037 : Type* OperationTyper::ToNumber(Type* type) {
     245     2375877 :   if (type->Is(Type::Number())) return type;
     246      439955 :   if (type->Is(Type::NullOrUndefined())) {
     247        3176 :     if (type->Is(Type::Null())) return cache_.kSingletonZero;
     248        2011 :     if (type->Is(Type::Undefined())) return Type::NaN();
     249          65 :     return Type::Union(Type::NaN(), cache_.kSingletonZero, zone());
     250             :   }
     251      436749 :   if (type->Is(Type::Boolean())) {
     252        7970 :     if (type->Is(singleton_false_)) return cache_.kSingletonZero;
     253        7312 :     if (type->Is(singleton_true_)) return cache_.kSingletonOne;
     254        2739 :     return cache_.kZeroOrOne;
     255             :   }
     256      432742 :   if (type->Is(Type::NumberOrOddball())) {
     257      315462 :     if (type->Is(Type::NumberOrUndefined())) {
     258        4461 :       type = Type::Union(type, Type::NaN(), zone());
     259      311008 :     } else if (type->Is(Type::NullOrNumber())) {
     260         110 :       type = Type::Union(type, cache_.kSingletonZero, zone());
     261      310870 :     } else if (type->Is(Type::BooleanOrNullOrNumber())) {
     262          56 :       type = Type::Union(type, cache_.kZeroOrOne, zone());
     263             :     } else {
     264      310814 :       type = Type::Union(type, cache_.kZeroOrOneOrNaN, zone());
     265             :     }
     266      315617 :     return Type::Intersect(type, Type::Number(), zone());
     267             :   }
     268             :   return Type::Number();
     269             : }
     270             : 
     271        1632 : Type* OperationTyper::NumberAbs(Type* type) {
     272             :   DCHECK(type->Is(Type::Number()));
     273             : 
     274         601 :   if (!type->IsInhabited()) {
     275             :     return Type::None();
     276             :   }
     277             : 
     278         557 :   bool const maybe_nan = type->Maybe(Type::NaN());
     279         557 :   bool const maybe_minuszero = type->Maybe(Type::MinusZero());
     280         557 :   type = Type::Intersect(type, Type::PlainNumber(), zone());
     281         557 :   double const max = type->Max();
     282         557 :   double const min = type->Min();
     283         557 :   if (min < 0) {
     284         706 :     if (type->Is(cache_.kInteger)) {
     285         435 :       type = Type::Range(0.0, std::max(std::fabs(min), std::fabs(max)), zone());
     286             :     } else {
     287             :       type = Type::PlainNumber();
     288             :     }
     289             :   }
     290         557 :   if (maybe_minuszero) {
     291         111 :     type = Type::Union(type, cache_.kSingletonZero, zone());
     292             :   }
     293         557 :   if (maybe_nan) {
     294         218 :     type = Type::Union(type, Type::NaN(), zone());
     295             :   }
     296         557 :   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       10918 : Type* OperationTyper::NumberCeil(Type* type) {
     335             :   DCHECK(type->Is(Type::Number()));
     336       21836 :   if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type;
     337             :   // TODO(bmeurer): We could infer a more precise type here.
     338       10271 :   return cache_.kIntegerOrMinusZeroOrNaN;
     339             : }
     340             : 
     341         131 : Type* OperationTyper::NumberClz32(Type* type) {
     342             :   DCHECK(type->Is(Type::Number()));
     343         131 :   return cache_.kZeroToThirtyTwo;
     344             : }
     345             : 
     346         115 : Type* OperationTyper::NumberCos(Type* type) {
     347             :   DCHECK(type->Is(Type::Number()));
     348         115 :   return Type::Number();
     349             : }
     350             : 
     351         129 : Type* OperationTyper::NumberCosh(Type* type) {
     352             :   DCHECK(type->Is(Type::Number()));
     353         129 :   return Type::Number();
     354             : }
     355             : 
     356         180 : Type* OperationTyper::NumberExp(Type* type) {
     357             :   DCHECK(type->Is(Type::Number()));
     358         180 :   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       55754 : Type* OperationTyper::NumberFloor(Type* type) {
     367             :   DCHECK(type->Is(Type::Number()));
     368       38012 :   if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type;
     369       18374 :   type = Type::Intersect(type, Type::MinusZeroOrNaN(), zone());
     370       18374 :   type = Type::Union(type, cache_.kInteger, zone());
     371       18374 :   return type;
     372             : }
     373             : 
     374        1658 : Type* OperationTyper::NumberFround(Type* type) {
     375             :   DCHECK(type->Is(Type::Number()));
     376        1658 :   return Type::Number();
     377             : }
     378             : 
     379         470 : Type* OperationTyper::NumberLog(Type* type) {
     380             :   DCHECK(type->Is(Type::Number()));
     381         470 :   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         294 : Type* OperationTyper::NumberRound(Type* type) {
     400             :   DCHECK(type->Is(Type::Number()));
     401         588 :   if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type;
     402             :   // TODO(bmeurer): We could infer a more precise type here.
     403         191 :   return cache_.kIntegerOrMinusZeroOrNaN;
     404             : }
     405             : 
     406         484 : 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           4 :     type = cache_.kSingletonMinusOne;
     414         104 :   } else if (type->Max() <= 0.0) {
     415           0 :     type = cache_.kMinusOneOrZero;
     416         104 :   } else if (type->Min() > 0.0) {
     417           9 :     type = cache_.kSingletonOne;
     418          95 :   } else if (type->Min() >= 0.0) {
     419           6 :     type = cache_.kZeroOrOne;
     420             :   } else {
     421             :     type = Type::Range(-1.0, 1.0, zone());
     422             :   }
     423         175 :   if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone());
     424         173 :   if (maybe_nan) type = Type::Union(type, Type::NaN(), zone());
     425         108 :   return type;
     426             : }
     427             : 
     428         175 : Type* OperationTyper::NumberSin(Type* type) {
     429             :   DCHECK(type->Is(Type::Number()));
     430         175 :   return Type::Number();
     431             : }
     432             : 
     433         129 : Type* OperationTyper::NumberSinh(Type* type) {
     434             :   DCHECK(type->Is(Type::Number()));
     435         129 :   return Type::Number();
     436             : }
     437             : 
     438         203 : Type* OperationTyper::NumberSqrt(Type* type) {
     439             :   DCHECK(type->Is(Type::Number()));
     440         203 :   return Type::Number();
     441             : }
     442             : 
     443         123 : Type* OperationTyper::NumberTan(Type* type) {
     444             :   DCHECK(type->Is(Type::Number()));
     445         123 :   return Type::Number();
     446             : }
     447             : 
     448         129 : Type* OperationTyper::NumberTanh(Type* type) {
     449             :   DCHECK(type->Is(Type::Number()));
     450         129 :   return Type::Number();
     451             : }
     452             : 
     453        2799 : Type* OperationTyper::NumberTrunc(Type* type) {
     454             :   DCHECK(type->Is(Type::Number()));
     455        5598 :   if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type;
     456             :   // TODO(bmeurer): We could infer a more precise type here.
     457        2580 :   return cache_.kIntegerOrMinusZeroOrNaN;
     458             : }
     459             : 
     460       45967 : Type* OperationTyper::NumberToBoolean(Type* type) {
     461             :   DCHECK(type->Is(Type::Number()));
     462       45967 :   if (!type->IsInhabited()) return Type::None();
     463       91846 :   if (type->Is(cache_.kZeroish)) return singleton_false_;
     464       45921 :   if (type->Is(Type::PlainNumber()) && (type->Max() < 0 || 0 < type->Min())) {
     465        2021 :     return singleton_true_;  // Ruled out nan, -0 and +0.
     466             :   }
     467             :   return Type::Boolean();
     468             : }
     469             : 
     470      233778 : Type* OperationTyper::NumberToInt32(Type* type) {
     471             :   DCHECK(type->Is(Type::Number()));
     472             : 
     473      227234 :   if (type->Is(Type::Signed32())) return type;
     474      175109 :   if (type->Is(cache_.kZeroish)) return cache_.kSingletonZero;
     475      167208 :   if (type->Is(signed32ish_)) {
     476             :     return Type::Intersect(Type::Union(type, cache_.kSingletonZero, zone()),
     477        6545 :                            Type::Signed32(), zone());
     478             :   }
     479             :   return Type::Signed32();
     480             : }
     481             : 
     482       66671 : Type* OperationTyper::NumberToUint32(Type* type) {
     483             :   DCHECK(type->Is(Type::Number()));
     484             : 
     485       66512 :   if (type->Is(Type::Unsigned32())) return type;
     486       57448 :   if (type->Is(cache_.kZeroish)) return cache_.kSingletonZero;
     487       53384 :   if (type->Is(unsigned32ish_)) {
     488             :     return Type::Intersect(Type::Union(type, cache_.kSingletonZero, zone()),
     489         159 :                            Type::Unsigned32(), zone());
     490             :   }
     491             :   return Type::Unsigned32();
     492             : }
     493             : 
     494        1427 : Type* OperationTyper::NumberToUint8Clamped(Type* type) {
     495             :   DCHECK(type->Is(Type::Number()));
     496             : 
     497        2854 :   if (type->Is(cache_.kUint8)) return type;
     498        1321 :   return cache_.kUint8;
     499             : }
     500             : 
     501        2194 : 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        2194 :   if (type->Maybe(Type::NaN())) return Type::Number();
     507         745 :   return type;
     508             : }
     509             : 
     510     2605972 : Type* OperationTyper::NumberAdd(Type* lhs, Type* rhs) {
     511             :   DCHECK(lhs->Is(Type::Number()));
     512             :   DCHECK(rhs->Is(Type::Number()));
     513             : 
     514     1342782 :   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      670663 :   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      670650 :   if (lhs->Maybe(Type::MinusZero())) {
     525      138668 :     lhs = Type::Union(lhs, cache_.kSingletonZero, zone());
     526             :   } else {
     527             :     maybe_minuszero = false;
     528             :   }
     529      670667 :   if (rhs->Maybe(Type::MinusZero())) {
     530      127669 :     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      670640 :   lhs = Type::Intersect(lhs, Type::PlainNumber(), zone());
     538      670532 :   rhs = Type::Intersect(rhs, Type::PlainNumber(), zone());
     539     1341000 :   if (lhs->IsInhabited() && rhs->IsInhabited()) {
     540     1764546 :     if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) {
     541      381473 :       type = AddRanger(lhs->Min(), lhs->Max(), rhs->Min(), rhs->Max());
     542             :     } else {
     543      721564 :       if ((lhs->Maybe(minus_infinity_) && rhs->Maybe(infinity_)) ||
     544      154000 :           (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      794062 :   if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone());
     553      873205 :   if (maybe_nan) type = Type::Union(type, Type::NaN(), zone());
     554      670404 :   return type;
     555             : }
     556             : 
     557     1437883 : Type* OperationTyper::NumberSubtract(Type* lhs, Type* rhs) {
     558             :   DCHECK(lhs->Is(Type::Number()));
     559             :   DCHECK(rhs->Is(Type::Number()));
     560             : 
     561      900386 :   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      449029 :   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      449029 :   if (lhs->Maybe(Type::MinusZero())) {
     573       34681 :     lhs = Type::Union(lhs, cache_.kSingletonZero, zone());
     574       34681 :     maybe_minuszero = rhs->Maybe(cache_.kSingletonZero);
     575             :   }
     576      449029 :   if (rhs->Maybe(Type::MinusZero())) {
     577        7291 :     rhs = Type::Union(rhs, cache_.kSingletonZero, zone());
     578             :   }
     579             : 
     580             :   // We can give more precise types for integers.
     581             :   Type* type = Type::None();
     582      449029 :   lhs = Type::Intersect(lhs, Type::PlainNumber(), zone());
     583      449030 :   rhs = Type::Intersect(rhs, Type::PlainNumber(), zone());
     584      897930 :   if (lhs->IsInhabited() && rhs->IsInhabited()) {
     585     1308850 :     if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) {
     586      409041 :       type = SubtractRanger(lhs->Min(), lhs->Max(), rhs->Min(), rhs->Max());
     587             :     } else {
     588      112988 :       if ((lhs->Maybe(infinity_) && rhs->Maybe(infinity_)) ||
     589       35116 :           (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      455535 :   if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone());
     598      489233 :   if (maybe_nan) type = Type::Union(type, Type::NaN(), zone());
     599      449030 :   return type;
     600             : }
     601             : 
     602      722058 : Type* OperationTyper::SpeculativeSafeIntegerAdd(Type* lhs, Type* rhs) {
     603      361046 :   Type* result = SpeculativeNumberAdd(lhs, rhs);
     604             :   // If we have a Smi or Int32 feedback, the representation selection will
     605             :   // either truncate or it will check the inputs (i.e., deopt if not int32).
     606             :   // In either case the result will be in the safe integer range, so we
     607             :   // can bake in the type here. This needs to be in sync with
     608             :   // SimplifiedLowering::VisitSpeculativeAdditiveOp.
     609      361012 :   return Type::Intersect(result, cache_.kSafeInteger, zone());
     610             : }
     611             : 
     612      272450 : Type* OperationTyper::SpeculativeSafeIntegerSubtract(Type* lhs, Type* rhs) {
     613      136225 :   Type* result = SpeculativeNumberSubtract(lhs, rhs);
     614             :   // If we have a Smi or Int32 feedback, the representation selection will
     615             :   // either truncate or it will check the inputs (i.e., deopt if not int32).
     616             :   // In either case the result will be in the safe integer range, so we
     617             :   // can bake in the type here. This needs to be in sync with
     618             :   // SimplifiedLowering::VisitSpeculativeAdditiveOp.
     619      136225 :   return result = Type::Intersect(result, cache_.kSafeInteger, zone());
     620             : }
     621             : 
     622       69751 : Type* OperationTyper::NumberMultiply(Type* lhs, Type* rhs) {
     623             :   DCHECK(lhs->Is(Type::Number()));
     624             :   DCHECK(rhs->Is(Type::Number()));
     625             : 
     626      139309 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
     627             :     return Type::None();
     628             :   }
     629             : 
     630       69507 :   lhs = Rangify(lhs);
     631       69507 :   rhs = Rangify(rhs);
     632      138891 :   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
     633      101760 :   if (lhs->IsRange() && rhs->IsRange()) {
     634       29978 :     return MultiplyRanger(lhs, rhs);
     635             :   }
     636             :   return Type::Number();
     637             : }
     638             : 
     639      297442 : Type* OperationTyper::NumberDivide(Type* lhs, Type* rhs) {
     640             :   DCHECK(lhs->Is(Type::Number()));
     641             :   DCHECK(rhs->Is(Type::Number()));
     642             : 
     643      141258 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
     644             :     return Type::None();
     645             :   }
     646             : 
     647      139471 :   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
     648             : 
     649             :   // Division is tricky, so all we do is try ruling out -0 and NaN.
     650             :   bool maybe_nan =
     651       99592 :       lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) ||
     652       61687 :       ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
     653        3854 :        (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
     654       69218 :   lhs = Type::Intersect(lhs, Type::OrderedNumber(), zone());
     655       69218 :   rhs = Type::Intersect(rhs, Type::OrderedNumber(), zone());
     656             : 
     657             :   // Try to rule out -0.
     658             :   bool maybe_minuszero =
     659      120575 :       !lhs->Is(cache_.kInteger) ||
     660      129178 :       (lhs->Maybe(cache_.kZeroish) && rhs->Min() < 0.0) ||
     661       62621 :       (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY);
     662             : 
     663             :   // Take into account the -0 and NaN information computed earlier.
     664             :   Type* type = Type::PlainNumber();
     665      118701 :   if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone());
     666      108078 :   if (maybe_nan) type = Type::Union(type, Type::NaN(), zone());
     667       69218 :   return type;
     668             : }
     669             : 
     670       79719 : Type* OperationTyper::NumberModulus(Type* lhs, Type* rhs) {
     671             :   DCHECK(lhs->Is(Type::Number()));
     672             :   DCHECK(rhs->Is(Type::Number()));
     673             : 
     674             :   // Modulus can yield NaN if either {lhs} or {rhs} are NaN, or
     675             :   // {lhs} is not finite, or the {rhs} is a zero value.
     676       36866 :   bool maybe_nan = lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) ||
     677       33718 :                    lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY;
     678             : 
     679             :   // Deal with -0 inputs, only the signbit of {lhs} matters for the result.
     680             :   bool maybe_minuszero = false;
     681       15286 :   if (lhs->Maybe(Type::MinusZero())) {
     682             :     maybe_minuszero = true;
     683        3609 :     lhs = Type::Union(lhs, cache_.kSingletonZero, zone());
     684             :   }
     685       15286 :   if (rhs->Maybe(Type::MinusZero())) {
     686        1505 :     rhs = Type::Union(rhs, cache_.kSingletonZero, zone());
     687             :   }
     688             : 
     689             :   // Rule out NaN and -0, and check what we can do with the remaining type info.
     690             :   Type* type = Type::None();
     691       15286 :   lhs = Type::Intersect(lhs, Type::PlainNumber(), zone());
     692       15286 :   rhs = Type::Intersect(rhs, Type::PlainNumber(), zone());
     693             : 
     694             :   // We can only derive a meaningful type if both {lhs} and {rhs} are inhabited,
     695             :   // and the {rhs} is not 0, otherwise the result is NaN independent of {lhs}.
     696       30397 :   if (lhs->IsInhabited() && !rhs->Is(cache_.kSingletonZero)) {
     697             :     // Determine the bounds of {lhs} and {rhs}.
     698       14896 :     double const lmin = lhs->Min();
     699       14896 :     double const lmax = lhs->Max();
     700       14896 :     double const rmin = rhs->Min();
     701       14896 :     double const rmax = rhs->Max();
     702             : 
     703             :     // The sign of the result is the sign of the {lhs}.
     704       14896 :     if (lmin < 0.0) maybe_minuszero = true;
     705             : 
     706             :     // For integer inputs {lhs} and {rhs} we can infer a precise type.
     707       41289 :     if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) {
     708       31296 :       double labs = std::max(std::abs(lmin), std::abs(lmax));
     709       31296 :       double rabs = std::max(std::abs(rmin), std::abs(rmax)) - 1;
     710       10432 :       double abs = std::min(labs, rabs);
     711             :       double min = 0.0, max = 0.0;
     712       10432 :       if (lmin >= 0.0) {
     713             :         // {lhs} positive.
     714             :         min = 0.0;
     715             :         max = abs;
     716        8105 :       } else if (lmax <= 0.0) {
     717             :         // {lhs} negative.
     718         622 :         min = 0.0 - abs;
     719             :         max = 0.0;
     720             :       } else {
     721             :         // {lhs} positive or negative.
     722        7483 :         min = 0.0 - abs;
     723             :         max = abs;
     724             :       }
     725             :       type = Type::Range(min, max, zone());
     726             :     } else {
     727             :       type = Type::PlainNumber();
     728             :     }
     729             :   }
     730             : 
     731             :   // Take into account the -0 and NaN information computed earlier.
     732       27426 :   if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone());
     733       21461 :   if (maybe_nan) type = Type::Union(type, Type::NaN(), zone());
     734       15286 :   return type;
     735             : }
     736             : 
     737      101177 : Type* OperationTyper::NumberBitwiseOr(Type* lhs, Type* rhs) {
     738             :   DCHECK(lhs->Is(Type::Number()));
     739             :   DCHECK(rhs->Is(Type::Number()));
     740             : 
     741      101228 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
     742             : 
     743       50471 :   lhs = NumberToInt32(lhs);
     744       50470 :   rhs = NumberToInt32(rhs);
     745             : 
     746       50471 :   double lmin = lhs->Min();
     747       50471 :   double rmin = rhs->Min();
     748       50471 :   double lmax = lhs->Max();
     749       50471 :   double rmax = rhs->Max();
     750             :   // Or-ing any two values results in a value no smaller than their minimum.
     751             :   // Even no smaller than their maximum if both values are non-negative.
     752             :   double min =
     753      100942 :       lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin);
     754       50471 :   double max = kMaxInt;
     755             : 
     756             :   // Or-ing with 0 is essentially a conversion to int32.
     757       50471 :   if (rmin == 0 && rmax == 0) {
     758             :     min = lmin;
     759       34312 :     max = lmax;
     760             :   }
     761       50471 :   if (lmin == 0 && lmax == 0) {
     762             :     min = rmin;
     763         564 :     max = rmax;
     764             :   }
     765             : 
     766       50471 :   if (lmax < 0 || rmax < 0) {
     767             :     // Or-ing two values of which at least one is negative results in a negative
     768             :     // value.
     769         994 :     max = std::min(max, -1.0);
     770             :   }
     771      100942 :   return Type::Range(min, max, zone());
     772             : }
     773             : 
     774       58546 : Type* OperationTyper::NumberBitwiseAnd(Type* lhs, Type* rhs) {
     775             :   DCHECK(lhs->Is(Type::Number()));
     776             :   DCHECK(rhs->Is(Type::Number()));
     777             : 
     778       58595 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
     779             : 
     780       29175 :   lhs = NumberToInt32(lhs);
     781       29175 :   rhs = NumberToInt32(rhs);
     782             : 
     783       29175 :   double lmin = lhs->Min();
     784       29175 :   double rmin = rhs->Min();
     785       29175 :   double lmax = lhs->Max();
     786       29175 :   double rmax = rhs->Max();
     787             :   double min = kMinInt;
     788             :   // And-ing any two values results in a value no larger than their maximum.
     789             :   // Even no larger than their minimum if both values are non-negative.
     790             :   double max =
     791       58352 :       lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax);
     792             :   // And-ing with a non-negative value x causes the result to be between
     793             :   // zero and x.
     794       29176 :   if (lmin >= 0) {
     795             :     min = 0;
     796        6839 :     max = std::min(max, lmax);
     797             :   }
     798       29176 :   if (rmin >= 0) {
     799             :     min = 0;
     800       18287 :     max = std::min(max, rmax);
     801             :   }
     802       58351 :   return Type::Range(min, max, zone());
     803             : }
     804             : 
     805        7291 : Type* OperationTyper::NumberBitwiseXor(Type* lhs, Type* rhs) {
     806             :   DCHECK(lhs->Is(Type::Number()));
     807             :   DCHECK(rhs->Is(Type::Number()));
     808             : 
     809       14505 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
     810             : 
     811        7163 :   lhs = NumberToInt32(lhs);
     812        7163 :   rhs = NumberToInt32(rhs);
     813             : 
     814        7163 :   double lmin = lhs->Min();
     815        7163 :   double rmin = rhs->Min();
     816        7163 :   double lmax = lhs->Max();
     817        7163 :   double rmax = rhs->Max();
     818        7163 :   if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) {
     819             :     // Xor-ing negative or non-negative values results in a non-negative value.
     820             :     return Type::Unsigned31();
     821             :   }
     822        6817 :   if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) {
     823             :     // Xor-ing a negative and a non-negative value results in a negative value.
     824             :     // TODO(jarin) Use a range here.
     825             :     return Type::Negative32();
     826             :   }
     827        6606 :   return Type::Signed32();
     828             : }
     829             : 
     830       11535 : Type* OperationTyper::NumberShiftLeft(Type* lhs, Type* rhs) {
     831             :   DCHECK(lhs->Is(Type::Number()));
     832             :   DCHECK(rhs->Is(Type::Number()));
     833             : 
     834       21274 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
     835             : 
     836       10552 :   lhs = NumberToInt32(lhs);
     837       10552 :   rhs = NumberToUint32(rhs);
     838             : 
     839       10552 :   int32_t min_lhs = lhs->Min();
     840       10552 :   int32_t max_lhs = lhs->Max();
     841       10552 :   uint32_t min_rhs = rhs->Min();
     842       10552 :   uint32_t max_rhs = rhs->Max();
     843       10552 :   if (max_rhs > 31) {
     844             :     // rhs can be larger than the bitmask
     845             :     max_rhs = 31;
     846             :     min_rhs = 0;
     847             :   }
     848             : 
     849       10552 :   if (max_lhs > (kMaxInt >> max_rhs) || min_lhs < (kMinInt >> max_rhs)) {
     850             :     // overflow possible
     851             :     return Type::Signed32();
     852             :   }
     853             : 
     854             :   double min =
     855        1093 :       std::min(static_cast<int32_t>(static_cast<uint32_t>(min_lhs) << min_rhs),
     856        3279 :                static_cast<int32_t>(static_cast<uint32_t>(min_lhs) << max_rhs));
     857             :   double max =
     858        1093 :       std::max(static_cast<int32_t>(static_cast<uint32_t>(max_lhs) << min_rhs),
     859        3279 :                static_cast<int32_t>(static_cast<uint32_t>(max_lhs) << max_rhs));
     860             : 
     861        1093 :   if (max == kMaxInt && min == kMinInt) return Type::Signed32();
     862         864 :   return Type::Range(min, max, zone());
     863             : }
     864             : 
     865       38325 : Type* OperationTyper::NumberShiftRight(Type* lhs, Type* rhs) {
     866             :   DCHECK(lhs->Is(Type::Number()));
     867             :   DCHECK(rhs->Is(Type::Number()));
     868             : 
     869       41833 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
     870             : 
     871       20801 :   lhs = NumberToInt32(lhs);
     872       20801 :   rhs = NumberToUint32(rhs);
     873             : 
     874       20801 :   int32_t min_lhs = lhs->Min();
     875       20801 :   int32_t max_lhs = lhs->Max();
     876       20801 :   uint32_t min_rhs = rhs->Min();
     877       20801 :   uint32_t max_rhs = rhs->Max();
     878       20801 :   if (max_rhs > 31) {
     879             :     // rhs can be larger than the bitmask
     880             :     max_rhs = 31;
     881             :     min_rhs = 0;
     882             :   }
     883       41602 :   double min = std::min(min_lhs >> min_rhs, min_lhs >> max_rhs);
     884       41602 :   double max = std::max(max_lhs >> min_rhs, max_lhs >> max_rhs);
     885             : 
     886       20801 :   if (max == kMaxInt && min == kMinInt) return Type::Signed32();
     887       17358 :   return Type::Range(min, max, zone());
     888             : }
     889             : 
     890       12831 : Type* OperationTyper::NumberShiftRightLogical(Type* lhs, Type* rhs) {
     891             :   DCHECK(lhs->Is(Type::Number()));
     892             :   DCHECK(rhs->Is(Type::Number()));
     893             : 
     894       20068 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
     895             : 
     896        9929 :   lhs = NumberToUint32(lhs);
     897        9929 :   rhs = NumberToUint32(rhs);
     898             : 
     899        9929 :   uint32_t min_lhs = lhs->Min();
     900        9929 :   uint32_t max_lhs = lhs->Max();
     901        9929 :   uint32_t min_rhs = rhs->Min();
     902        9929 :   uint32_t max_rhs = rhs->Max();
     903        9929 :   if (max_rhs > 31) {
     904             :     // rhs can be larger than the bitmask
     905             :     max_rhs = 31;
     906             :     min_rhs = 0;
     907             :   }
     908             : 
     909        9929 :   double min = min_lhs >> max_rhs;
     910        9929 :   double max = max_lhs >> min_rhs;
     911             :   DCHECK_LE(0, min);
     912             :   DCHECK_LE(max, kMaxUInt32);
     913             : 
     914        9929 :   if (min == 0 && max == kMaxInt) return Type::Unsigned31();
     915        9305 :   if (min == 0 && max == kMaxUInt32) return Type::Unsigned32();
     916        2743 :   return Type::Range(min, max, zone());
     917             : }
     918             : 
     919         320 : Type* OperationTyper::NumberAtan2(Type* lhs, Type* rhs) {
     920             :   DCHECK(lhs->Is(Type::Number()));
     921             :   DCHECK(rhs->Is(Type::Number()));
     922         320 :   return Type::Number();
     923             : }
     924             : 
     925         204 : Type* OperationTyper::NumberImul(Type* lhs, Type* rhs) {
     926             :   DCHECK(lhs->Is(Type::Number()));
     927             :   DCHECK(rhs->Is(Type::Number()));
     928             :   // TODO(turbofan): We should be able to do better here.
     929         204 :   return Type::Signed32();
     930             : }
     931             : 
     932        2843 : Type* OperationTyper::NumberMax(Type* lhs, Type* rhs) {
     933             :   DCHECK(lhs->Is(Type::Number()));
     934             :   DCHECK(rhs->Is(Type::Number()));
     935        1468 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
     936             :     return Type::None();
     937             :   }
     938        1372 :   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) {
     939             :     return Type::NaN();
     940             :   }
     941             :   Type* type = Type::None();
     942             :   // TODO(turbofan): Improve minus zero handling here.
     943         673 :   if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) {
     944          73 :     type = Type::Union(type, Type::NaN(), zone());
     945             :   }
     946         673 :   lhs = Type::Intersect(lhs, Type::OrderedNumber(), zone());
     947         673 :   rhs = Type::Intersect(rhs, Type::OrderedNumber(), zone());
     948        1863 :   if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) {
     949         974 :     double max = std::max(lhs->Max(), rhs->Max());
     950         974 :     double min = std::max(lhs->Min(), rhs->Min());
     951         487 :     type = Type::Union(type, Type::Range(min, max, zone()), zone());
     952             :   } else {
     953         186 :     type = Type::Union(type, Type::Union(lhs, rhs, zone()), zone());
     954             :   }
     955         673 :   return type;
     956             : }
     957             : 
     958        3301 : Type* OperationTyper::NumberMin(Type* lhs, Type* rhs) {
     959             :   DCHECK(lhs->Is(Type::Number()));
     960             :   DCHECK(rhs->Is(Type::Number()));
     961        1626 :   if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
     962             :     return Type::None();
     963             :   }
     964        1530 :   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) {
     965             :     return Type::NaN();
     966             :   }
     967             :   Type* type = Type::None();
     968             :   // TODO(turbofan): Improve minus zero handling here.
     969         752 :   if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) {
     970         215 :     type = Type::Union(type, Type::NaN(), zone());
     971             :   }
     972         752 :   lhs = Type::Intersect(lhs, Type::OrderedNumber(), zone());
     973         752 :   rhs = Type::Intersect(rhs, Type::OrderedNumber(), zone());
     974        1818 :   if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) {
     975         480 :     double max = std::min(lhs->Max(), rhs->Max());
     976         480 :     double min = std::min(lhs->Min(), rhs->Min());
     977         240 :     type = Type::Union(type, Type::Range(min, max, zone()), zone());
     978             :   } else {
     979         512 :     type = Type::Union(type, Type::Union(lhs, rhs, zone()), zone());
     980             :   }
     981         752 :   return type;
     982             : }
     983             : 
     984        2324 : Type* OperationTyper::NumberPow(Type* lhs, Type* rhs) {
     985             :   DCHECK(lhs->Is(Type::Number()));
     986             :   DCHECK(rhs->Is(Type::Number()));
     987             :   // TODO(turbofan): We should be able to do better here.
     988        2324 :   return Type::Number();
     989             : }
     990             : 
     991             : #define SPECULATIVE_NUMBER_BINOP(Name)                            \
     992             :   Type* OperationTyper::Speculative##Name(Type* lhs, Type* rhs) { \
     993             :     lhs = SpeculativeToNumber(lhs);                               \
     994             :     rhs = SpeculativeToNumber(rhs);                               \
     995             :     return Name(lhs, rhs);                                        \
     996             :   }
     997      460645 : SPECULATIVE_NUMBER_BINOP(NumberAdd)
     998      137987 : SPECULATIVE_NUMBER_BINOP(NumberSubtract)
     999       44740 : SPECULATIVE_NUMBER_BINOP(NumberMultiply)
    1000       47157 : SPECULATIVE_NUMBER_BINOP(NumberDivide)
    1001        7845 : SPECULATIVE_NUMBER_BINOP(NumberModulus)
    1002       34323 : SPECULATIVE_NUMBER_BINOP(NumberBitwiseOr)
    1003       14498 : SPECULATIVE_NUMBER_BINOP(NumberBitwiseAnd)
    1004        2317 : SPECULATIVE_NUMBER_BINOP(NumberBitwiseXor)
    1005        4569 : SPECULATIVE_NUMBER_BINOP(NumberShiftLeft)
    1006       14139 : SPECULATIVE_NUMBER_BINOP(NumberShiftRight)
    1007        4113 : SPECULATIVE_NUMBER_BINOP(NumberShiftRightLogical)
    1008             : #undef SPECULATIVE_NUMBER_BINOP
    1009             : 
    1010     1596498 : Type* OperationTyper::SpeculativeToNumber(Type* type) {
    1011     1596498 :   return ToNumber(Type::Intersect(type, Type::NumberOrOddball(), zone()));
    1012             : }
    1013             : 
    1014           0 : Type* OperationTyper::ToPrimitive(Type* type) {
    1015           0 :   if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) {
    1016           0 :     return type;
    1017             :   }
    1018             :   return Type::Primitive();
    1019             : }
    1020             : 
    1021           0 : Type* OperationTyper::Invert(Type* type) {
    1022             :   DCHECK(type->Is(Type::Boolean()));
    1023             :   DCHECK(type->IsInhabited());
    1024           0 :   if (type->Is(singleton_false())) return singleton_true();
    1025           0 :   if (type->Is(singleton_true())) return singleton_false();
    1026             :   return type;
    1027             : }
    1028             : 
    1029           0 : OperationTyper::ComparisonOutcome OperationTyper::Invert(
    1030             :     ComparisonOutcome outcome) {
    1031             :   ComparisonOutcome result(0);
    1032           0 :   if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined;
    1033           0 :   if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse;
    1034           0 :   if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue;
    1035           0 :   return result;
    1036             : }
    1037             : 
    1038           0 : Type* OperationTyper::FalsifyUndefined(ComparisonOutcome outcome) {
    1039           0 :   if ((outcome & kComparisonFalse) != 0 ||
    1040             :       (outcome & kComparisonUndefined) != 0) {
    1041             :     return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
    1042           0 :                                             : singleton_false();
    1043             :   }
    1044             :   // Type should be non empty, so we know it should be true.
    1045             :   DCHECK_NE(0, outcome & kComparisonTrue);
    1046           0 :   return singleton_true();
    1047             : }
    1048             : 
    1049        4515 : Type* OperationTyper::CheckFloat64Hole(Type* type) {
    1050        1553 :   if (type->Maybe(Type::Hole())) {
    1051             :     // Turn "the hole" into undefined.
    1052        1481 :     type = Type::Intersect(type, Type::Number(), zone());
    1053        1481 :     type = Type::Union(type, Type::Undefined(), zone());
    1054             :   }
    1055        1553 :   return type;
    1056             : }
    1057             : 
    1058        2212 : Type* OperationTyper::CheckNumber(Type* type) {
    1059        2212 :   return Type::Intersect(type, Type::Number(), zone());
    1060             : }
    1061             : 
    1062       45233 : Type* OperationTyper::TypeTypeGuard(const Operator* sigma_op, Type* input) {
    1063       45233 :   return Type::Intersect(input, TypeGuardTypeOf(sigma_op), zone());
    1064             : }
    1065             : 
    1066        8966 : Type* OperationTyper::ConvertTaggedHoleToUndefined(Type* input) {
    1067        3054 :   if (input->Maybe(Type::Hole())) {
    1068             :     // Turn "the hole" into undefined.
    1069        2956 :     Type* type = Type::Intersect(input, Type::NonInternal(), zone());
    1070        2956 :     return Type::Union(type, Type::Undefined(), zone());
    1071             :   }
    1072             :   return input;
    1073             : }
    1074             : 
    1075             : }  // namespace compiler
    1076             : }  // namespace internal
    1077             : }  // namespace v8

Generated by: LCOV version 1.10