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
|