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 15namespace v8 { 16namespace internal { 17namespace compiler { 18 19OperationTyper::OperationTyper(Isolate* isolate, Zone* zone) 20 : zone_(zone), cache_(TypeCache::Get()) { 21 Factory* factory = isolate->factory(); 22 infinity_ = Type::NewConstant(factory->infinity_value(), zone); 23 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 singleton_false_ = Type::HeapConstant(factory->false_value(), zone); 28 singleton_true_ = Type::HeapConstant(factory->true_value(), zone); 29 singleton_the_hole_ = Type::HeapConstant(factory->the_hole_value(), zone); 30 signed32ish_ = Type::Union(Type::Signed32(), truncating_to_zero, zone); 31 unsigned32ish_ = Type::Union(Type::Unsigned32(), truncating_to_zero, zone); 32} 33 34Type* OperationTyper::Merge(Type* left, Type* right) { 35 return Type::Union(left, right, zone()); 36} 37 38Type* 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 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 if (current_min != previous_range->Min()) { 88 new_min = -V8_INFINITY; 89 for (double const min : kWeakenMinLimits) { 90 if (min <= current_min) { 91 new_min = min; 92 break; 93 } 94 } 95 } 96 97 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 if (current_max != previous_range->Max()) { 102 new_max = V8_INFINITY; 103 for (double const max : kWeakenMaxLimits) { 104 if (max >= current_max) { 105 new_max = max; 106 break; 107 } 108 } 109 } 110 111 return Type::Range(new_min, new_max, zone()); 112} 113 114Type* OperationTyper::Rangify(Type* type) { 115 if (type->IsRange()) return type; // Shortcut. 116 if (!type->Is(cache_.kInteger)) { 117 return type; // Give up on non-integer types. 118 } 119 double min = type->Min(); 120 double max = type->Max(); 121 // Handle the degenerate case of empty bitset types (such as 122 // OtherUnsigned31 and OtherSigned32 on 64-bit architectures). 123 if (std::isnan(min)) { 124 DCHECK(std::isnan(max)); 125 return type; 126 } 127 return Type::Range(min, max, zone()); 128} 129 130namespace { 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. 135double array_min(double a[], size_t n) { 136 DCHECK(n != 0); 137 double x = +V8_INFINITY; 138 for (size_t i = 0; i < n; ++i) { 139 if (!std::isnan(a[i])) { 140 x = std::min(a[i], x); 141 } 142 } 143 DCHECK(!std::isnan(x)); 144 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. 150double array_max(double a[], size_t n) { 151 DCHECK(n != 0); 152 double x = -V8_INFINITY; 153 for (size_t i = 0; i < n; ++i) { 154 if (!std::isnan(a[i])) { 155 x = std::max(a[i], x); 156 } 157 } 158 DCHECK(!std::isnan(x)); 159 return x == 0 ? 0 : x; // -0 -> 0 160} 161 162} // namespace 163 164Type* OperationTyper::AddRanger(double lhs_min, double lhs_max, double rhs_min, 165 double rhs_max) { 166 double results[4]; 167 results[0] = lhs_min + rhs_min; 168 results[1] = lhs_min + rhs_max; 169 results[2] = lhs_max + rhs_min; 170 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 for (int i = 0; i < 4; ++i) { 177 if (std::isnan(results[i])) ++nans; 178 } 179 if (nans == 4) return Type::NaN(); 180 Type* type = 181 Type::Range(array_min(results, 4), array_max(results, 4), zone()); 182 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 return type; 189} 190 191Type* OperationTyper::SubtractRanger(double lhs_min, double lhs_max, 192 double rhs_min, double rhs_max) { 193 double results[4]; 194 results[0] = lhs_min - rhs_min; 195 results[1] = lhs_min - rhs_max; 196 results[2] = lhs_max - rhs_min; 197 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 for (int i = 0; i < 4; ++i) { 204 if (std::isnan(results[i])) ++nans; 205 } 206 if (nans == 4) return Type::NaN(); // [inf..inf] - [inf..inf] (all same sign) 207 Type* type = 208 Type::Range(array_min(results, 4), array_max(results, 4), zone()); 209 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 217Type* OperationTyper::MultiplyRanger(Type* lhs, Type* rhs) { 218 double results[4]; 219 double lmin = lhs->AsRange()->Min(); 220 double lmax = lhs->AsRange()->Max(); 221 double rmin = rhs->AsRange()->Min(); 222 double rmax = rhs->AsRange()->Max(); 223 results[0] = lmin * rmin; 224 results[1] = lmin * rmax; 225 results[2] = lmax * rmin; 226 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 bool maybe_nan = (lhs->Maybe(cache_.kSingletonZero) && 232 (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) || 233 (rhs->Maybe(cache_.kSingletonZero) && 234 (lmin == -V8_INFINITY || lmax == +V8_INFINITY)); 235 if (maybe_nan) return cache_.kIntegerOrMinusZeroOrNaN; // Giving up. 236 bool maybe_minuszero = (lhs->Maybe(cache_.kSingletonZero) && rmin < 0) || 237 (rhs->Maybe(cache_.kSingletonZero) && lmin < 0); 238 Type* range = 239 Type::Range(array_min(results, 4), array_max(results, 4), zone()); 240 return maybe_minuszero ? Type::Union(range, Type::MinusZero(), zone()) 241 : range; 242} 243 244Type* OperationTyper::ToNumber(Type* type) { 245 if (type->Is(Type::Number())) return type; 246 if (type->Is(Type::NullOrUndefined())) { 247 if (type->Is(Type::Null())) return cache_.kSingletonZero; 248 if (type->Is(Type::Undefined())) return Type::NaN(); 249 return Type::Union(Type::NaN(), cache_.kSingletonZero, zone()); 250 } 251 if (type->Is(Type::Boolean())) { 252 if (type->Is(singleton_false_)) return cache_.kSingletonZero; 253 if (type->Is(singleton_true_)) return cache_.kSingletonOne; 254 return cache_.kZeroOrOne; 255 } 256 if (type->Is(Type::NumberOrOddball())) { 257 if (type->Is(Type::NumberOrUndefined())) { 258 type = Type::Union(type, Type::NaN(), zone()); 259 } else if (type->Is(Type::NullOrNumber())) { 260 type = Type::Union(type, cache_.kSingletonZero, zone()); 261 } else if (type->Is(Type::BooleanOrNullOrNumber())) { 262 type = Type::Union(type, cache_.kZeroOrOne, zone()); 263 } else { 264 type = Type::Union(type, cache_.kZeroOrOneOrNaN, zone()); 265 } 266 return Type::Intersect(type, Type::Number(), zone()); 267 } 268 return Type::Number(); 269} 270 271Type* OperationTyper::NumberAbs(Type* type) { 272 DCHECK(type->Is(Type::Number())); 273 274 if (!type->IsInhabited()) { 275 return Type::None(); 276 } 277 278 bool const maybe_nan = type->Maybe(Type::NaN()); 279 bool const maybe_minuszero = type->Maybe(Type::MinusZero()); 280 type = Type::Intersect(type, Type::PlainNumber(), zone()); 281 double const max = type->Max(); 282 double const min = type->Min(); 283 if (min < 0) { 284 if (type->Is(cache_.kInteger)) { 285 type = Type::Range(0.0, std::max(std::fabs(min), std::fabs(max)), zone()); 286 } else { 287 type = Type::PlainNumber(); 288 } 289 } 290 if (maybe_minuszero) { 291 type = Type::Union(type, cache_.kSingletonZero, zone()); 292 } 293 if (maybe_nan) { 294 type = Type::Union(type, Type::NaN(), zone()); 295 } 296 return type; 297} 298 299Type* OperationTyper::NumberAcos(Type* type) { 300 DCHECK(type->Is(Type::Number())); 301 return Type::Number(); 302} 303 304Type* OperationTyper::NumberAcosh(Type* type) { 305 DCHECK(type->Is(Type::Number())); 306 return Type::Number(); 307} 308 309Type* OperationTyper::NumberAsin(Type* type) { 310 DCHECK(type->Is(Type::Number())); 311 return Type::Number(); 312} 313 314Type* OperationTyper::NumberAsinh(Type* type) { 315 DCHECK(type->Is(Type::Number())); 316 return Type::Number(); 317} 318 319Type* OperationTyper::NumberAtan(Type* type) { 320 DCHECK(type->Is(Type::Number())); 321 return Type::Number(); 322} 323 324Type* OperationTyper::NumberAtanh(Type* type) { 325 DCHECK(type->Is(Type::Number())); 326 return Type::Number(); 327} 328 329Type* OperationTyper::NumberCbrt(Type* type) { 330 DCHECK(type->Is(Type::Number())); 331 return Type::Number(); 332} 333 334Type* OperationTyper::NumberCeil(Type* type) { 335 DCHECK(type->Is(Type::Number())); 336 if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type; 337 // TODO(bmeurer): We could infer a more precise type here. 338 return cache_.kIntegerOrMinusZeroOrNaN; 339} 340 341Type* OperationTyper::NumberClz32(Type* type) { 342 DCHECK(type->Is(Type::Number())); 343 return cache_.kZeroToThirtyTwo; 344} 345 346Type* OperationTyper::NumberCos(Type* type) { 347 DCHECK(type->Is(Type::Number())); 348 return Type::Number(); 349} 350 351Type* OperationTyper::NumberCosh(Type* type) { 352 DCHECK(type->Is(Type::Number())); 353 return Type::Number(); 354} 355 356Type* OperationTyper::NumberExp(Type* type) { 357 DCHECK(type->Is(Type::Number())); 358 return Type::Union(Type::PlainNumber(), Type::NaN(), zone()); 359} 360 361Type* OperationTyper::NumberExpm1(Type* type) { 362 DCHECK(type->Is(Type::Number())); 363 return Type::Union(Type::PlainNumber(), Type::NaN(), zone()); 364} 365 366Type* OperationTyper::NumberFloor(Type* type) { 367 DCHECK(type->Is(Type::Number())); 368 if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type; 369 type = Type::Intersect(type, Type::MinusZeroOrNaN(), zone()); 370 type = Type::Union(type, cache_.kInteger, zone()); 371 return type; 372} 373 374Type* OperationTyper::NumberFround(Type* type) { 375 DCHECK(type->Is(Type::Number())); 376 return Type::Number(); 377} 378 379Type* OperationTyper::NumberLog(Type* type) { 380 DCHECK(type->Is(Type::Number())); 381 return Type::Number(); 382} 383 384Type* OperationTyper::NumberLog1p(Type* type) { 385 DCHECK(type->Is(Type::Number())); 386 return Type::Number(); 387} 388 389Type* OperationTyper::NumberLog2(Type* type) { 390 DCHECK(type->Is(Type::Number())); 391 return Type::Number(); 392} 393 394Type* OperationTyper::NumberLog10(Type* type) { 395 DCHECK(type->Is(Type::Number())); 396 return Type::Number(); 397} 398 399Type* OperationTyper::NumberRound(Type* type) { 400 DCHECK(type->Is(Type::Number())); 401 if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type; 402 // TODO(bmeurer): We could infer a more precise type here. 403 return cache_.kIntegerOrMinusZeroOrNaN; 404} 405 406Type* OperationTyper::NumberSign(Type* type) { 407 DCHECK(type->Is(Type::Number())); 408 if (type->Is(cache_.kZeroish)) return type; 409 bool maybe_minuszero = type->Maybe(Type::MinusZero()); 410 bool maybe_nan = type->Maybe(Type::NaN()); 411 type = Type::Intersect(type, Type::PlainNumber(), zone()); 412 if (type->Max() < 0.0) { 413 type = cache_.kSingletonMinusOne; 414 } else if (type->Max() <= 0.0) { 415 type = cache_.kMinusOneOrZero; 416 } else if (type->Min() > 0.0) { 417 type = cache_.kSingletonOne; 418 } else if (type->Min() >= 0.0) { 419 type = cache_.kZeroOrOne; 420 } else { 421 type = Type::Range(-1.0, 1.0, zone()); 422 } 423 if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone()); 424 if (maybe_nan) type = Type::Union(type, Type::NaN(), zone()); 425 return type; 426} 427 428Type* OperationTyper::NumberSin(Type* type) { 429 DCHECK(type->Is(Type::Number())); 430 return Type::Number(); 431} 432 433Type* OperationTyper::NumberSinh(Type* type) { 434 DCHECK(type->Is(Type::Number())); 435 return Type::Number(); 436} 437 438Type* OperationTyper::NumberSqrt(Type* type) { 439 DCHECK(type->Is(Type::Number())); 440 return Type::Number(); 441} 442 443Type* OperationTyper::NumberTan(Type* type) { 444 DCHECK(type->Is(Type::Number())); 445 return Type::Number(); 446} 447 448Type* OperationTyper::NumberTanh(Type* type) { 449 DCHECK(type->Is(Type::Number())); 450 return Type::Number(); 451} 452 453Type* OperationTyper::NumberTrunc(Type* type) { 454 DCHECK(type->Is(Type::Number())); 455 if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type; 456 // TODO(bmeurer): We could infer a more precise type here. 457 return cache_.kIntegerOrMinusZeroOrNaN; 458} 459 460Type* OperationTyper::NumberToBoolean(Type* type) { 461 DCHECK(type->Is(Type::Number())); 462 if (!type->IsInhabited()) return Type::None(); 463 if (type->Is(cache_.kZeroish)) return singleton_false_; 464 if (type->Is(Type::PlainNumber()) && (type->Max() < 0 || 0 < type->Min())) { 465 return singleton_true_; // Ruled out nan, -0 and +0. 466 } 467 return Type::Boolean(); 468} 469 470Type* OperationTyper::NumberToInt32(Type* type) { 471 DCHECK(type->Is(Type::Number())); 472 473 if (type->Is(Type::Signed32())) return type; 474 if (type->Is(cache_.kZeroish)) return cache_.kSingletonZero; 475 if (type->Is(signed32ish_)) { 476 return Type::Intersect(Type::Union(type, cache_.kSingletonZero, zone()), 477 Type::Signed32(), zone()); 478 } 479 return Type::Signed32(); 480} 481 482Type* OperationTyper::NumberToUint32(Type* type) { 483 DCHECK(type->Is(Type::Number())); 484 485 if (type->Is(Type::Unsigned32())) return type; 486 if (type->Is(cache_.kZeroish)) return cache_.kSingletonZero; 487 if (type->Is(unsigned32ish_)) { 488 return Type::Intersect(Type::Union(type, cache_.kSingletonZero, zone()), 489 Type::Unsigned32(), zone()); 490 } 491 return Type::Unsigned32(); 492} 493 494Type* OperationTyper::NumberToUint8Clamped(Type* type) { 495 DCHECK(type->Is(Type::Number())); 496 497 if (type->Is(cache_.kUint8)) return type; 498 return cache_.kUint8; 499} 500 501Type* 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 if (type->Maybe(Type::NaN())) return Type::Number(); 507 return type; 508} 509 510Type* OperationTyper::NumberAdd(Type* lhs, Type* rhs) { 511 DCHECK(lhs->Is(Type::Number())); 512 DCHECK(rhs->Is(Type::Number())); 513 514 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 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 if (lhs->Maybe(Type::MinusZero())) { 525 lhs = Type::Union(lhs, cache_.kSingletonZero, zone()); 526 } else { 527 maybe_minuszero = false; 528 } 529 if (rhs->Maybe(Type::MinusZero())) { 530 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 lhs = Type::Intersect(lhs, Type::PlainNumber(), zone()); 538 rhs = Type::Intersect(rhs, Type::PlainNumber(), zone()); 539 if (lhs->IsInhabited() && rhs->IsInhabited()) { 540 if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) { 541 type = AddRanger(lhs->Min(), lhs->Max(), rhs->Min(), rhs->Max()); 542 } else { 543 if ((lhs->Maybe(minus_infinity_) && rhs->Maybe(infinity_)) || 544 (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 if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone()); 553 if (maybe_nan) type = Type::Union(type, Type::NaN(), zone()); 554 return type; 555} 556 557Type* OperationTyper::NumberSubtract(Type* lhs, Type* rhs) { 558 DCHECK(lhs->Is(Type::Number())); 559 DCHECK(rhs->Is(Type::Number())); 560 561 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 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 if (lhs->Maybe(Type::MinusZero())) { 573 lhs = Type::Union(lhs, cache_.kSingletonZero, zone()); 574 maybe_minuszero = rhs->Maybe(cache_.kSingletonZero); 575 } 576 if (rhs->Maybe(Type::MinusZero())) { 577 rhs = Type::Union(rhs, cache_.kSingletonZero, zone()); 578 } 579 580 // We can give more precise types for integers. 581 Type* type = Type::None(); 582 lhs = Type::Intersect(lhs, Type::PlainNumber(), zone()); 583 rhs = Type::Intersect(rhs, Type::PlainNumber(), zone()); 584 if (lhs->IsInhabited() && rhs->IsInhabited()) { 585 if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) { 586 type = SubtractRanger(lhs->Min(), lhs->Max(), rhs->Min(), rhs->Max()); 587 } else { 588 if ((lhs->Maybe(infinity_) && rhs->Maybe(infinity_)) || 589 (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 if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone()); 598 if (maybe_nan) type = Type::Union(type, Type::NaN(), zone()); 599 return type; 600} 601 602Type* OperationTyper::NumberMultiply(Type* lhs, Type* rhs) { 603 DCHECK(lhs->Is(Type::Number())); 604 DCHECK(rhs->Is(Type::Number())); 605 606 if (!lhs->IsInhabited() || !rhs->IsInhabited()) { 607 return Type::None(); 608 } 609 610 lhs = Rangify(lhs); 611 rhs = Rangify(rhs); 612 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 613 if (lhs->IsRange() && rhs->IsRange()) { 614 return MultiplyRanger(lhs, rhs); 615 } 616 return Type::Number(); 617} 618 619Type* OperationTyper::NumberDivide(Type* lhs, Type* rhs) { 620 DCHECK(lhs->Is(Type::Number())); 621 DCHECK(rhs->Is(Type::Number())); 622 623 if (!lhs->IsInhabited() || !rhs->IsInhabited()) { 624 return Type::None(); 625 } 626 627 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 628 // Division is tricky, so all we do is try ruling out -0 and NaN. 629 bool maybe_minuszero = !lhs->Is(cache_.kPositiveIntegerOrNaN) || 630 !rhs->Is(cache_.kPositiveIntegerOrNaN); 631 bool maybe_nan = 632 lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) || 633 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && 634 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); 635 636 // Take into account the -0 and NaN information computed earlier. 637 Type* type = Type::PlainNumber(); 638 if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone()); 639 if (maybe_nan) type = Type::Union(type, Type::NaN(), zone()); 640 return type; 641} 642 643Type* OperationTyper::NumberModulus(Type* lhs, Type* rhs) { 644 DCHECK(lhs->Is(Type::Number())); 645 DCHECK(rhs->Is(Type::Number())); 646 647 // Modulus can yield NaN if either {lhs} or {rhs} are NaN, or 648 // {lhs} is not finite, or the {rhs} is a zero value. 649 bool maybe_nan = lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) || 650 lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY; 651 652 // Deal with -0 inputs, only the signbit of {lhs} matters for the result. 653 bool maybe_minuszero = false; 654 if (lhs->Maybe(Type::MinusZero())) { 655 maybe_minuszero = true; 656 lhs = Type::Union(lhs, cache_.kSingletonZero, zone()); 657 } 658 if (rhs->Maybe(Type::MinusZero())) { 659 rhs = Type::Union(rhs, cache_.kSingletonZero, zone()); 660 } 661 662 // Rule out NaN and -0, and check what we can do with the remaining type info. 663 Type* type = Type::None(); 664 lhs = Type::Intersect(lhs, Type::PlainNumber(), zone()); 665 rhs = Type::Intersect(rhs, Type::PlainNumber(), zone()); 666 667 // We can only derive a meaningful type if both {lhs} and {rhs} are inhabited, 668 // and the {rhs} is not 0, otherwise the result is NaN independent of {lhs}. 669 if (lhs->IsInhabited() && !rhs->Is(cache_.kSingletonZero)) { 670 // Determine the bounds of {lhs} and {rhs}. 671 double const lmin = lhs->Min(); 672 double const lmax = lhs->Max(); 673 double const rmin = rhs->Min(); 674 double const rmax = rhs->Max(); 675 676 // The sign of the result is the sign of the {lhs}. 677 if (lmin < 0.0) maybe_minuszero = true; 678 679 // For integer inputs {lhs} and {rhs} we can infer a precise type. 680 if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) { 681 double labs = std::max(std::abs(lmin), std::abs(lmax)); 682 double rabs = std::max(std::abs(rmin), std::abs(rmax)) - 1; 683 double abs = std::min(labs, rabs); 684 double min = 0.0, max = 0.0; 685 if (lmin >= 0.0) { 686 // {lhs} positive. 687 min = 0.0; 688 max = abs; 689 } else if (lmax <= 0.0) { 690 // {lhs} negative. 691 min = 0.0 - abs; 692 max = 0.0; 693 } else { 694 // {lhs} positive or negative. 695 min = 0.0 - abs; 696 max = abs; 697 } 698 type = Type::Range(min, max, zone()); 699 } else { 700 type = Type::PlainNumber(); 701 } 702 } 703 704 // Take into account the -0 and NaN information computed earlier. 705 if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone()); 706 if (maybe_nan) type = Type::Union(type, Type::NaN(), zone()); 707 return type; 708} 709 710Type* OperationTyper::NumberBitwiseOr(Type* lhs, Type* rhs) { 711 DCHECK(lhs->Is(Type::Number())); 712 DCHECK(rhs->Is(Type::Number())); 713 714 if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None(); 715 716 lhs = NumberToInt32(lhs); 717 rhs = NumberToInt32(rhs); 718 719 double lmin = lhs->Min(); 720 double rmin = rhs->Min(); 721 double lmax = lhs->Max(); 722 double rmax = rhs->Max(); 723 // Or-ing any two values results in a value no smaller than their minimum. 724 // Even no smaller than their maximum if both values are non-negative. 725 double min = 726 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin); 727 double max = kMaxInt; 728 729 // Or-ing with 0 is essentially a conversion to int32. 730 if (rmin == 0 && rmax == 0) { 731 min = lmin; 732 max = lmax; 733 } 734 if (lmin == 0 && lmax == 0) { 735 min = rmin; 736 max = rmax; 737 } 738 739 if (lmax < 0 || rmax < 0) { 740 // Or-ing two values of which at least one is negative results in a negative 741 // value. 742 max = std::min(max, -1.0); 743 } 744 return Type::Range(min, max, zone()); 745} 746 747Type* OperationTyper::NumberBitwiseAnd(Type* lhs, Type* rhs) { 748 DCHECK(lhs->Is(Type::Number())); 749 DCHECK(rhs->Is(Type::Number())); 750 751 if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None(); 752 753 lhs = NumberToInt32(lhs); 754 rhs = NumberToInt32(rhs); 755 756 double lmin = lhs->Min(); 757 double rmin = rhs->Min(); 758 double lmax = lhs->Max(); 759 double rmax = rhs->Max(); 760 double min = kMinInt; 761 // And-ing any two values results in a value no larger than their maximum. 762 // Even no larger than their minimum if both values are non-negative. 763 double max = 764 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax); 765 // And-ing with a non-negative value x causes the result to be between 766 // zero and x. 767 if (lmin >= 0) { 768 min = 0; 769 max = std::min(max, lmax); 770 } 771 if (rmin >= 0) { 772 min = 0; 773 max = std::min(max, rmax); 774 } 775 return Type::Range(min, max, zone()); 776} 777 778Type* OperationTyper::NumberBitwiseXor(Type* lhs, Type* rhs) { 779 DCHECK(lhs->Is(Type::Number())); 780 DCHECK(rhs->Is(Type::Number())); 781 782 if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None(); 783 784 lhs = NumberToInt32(lhs); 785 rhs = NumberToInt32(rhs); 786 787 double lmin = lhs->Min(); 788 double rmin = rhs->Min(); 789 double lmax = lhs->Max(); 790 double rmax = rhs->Max(); 791 if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) { 792 // Xor-ing negative or non-negative values results in a non-negative value. 793 return Type::Unsigned31(); 794 } 795 if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) { 796 // Xor-ing a negative and a non-negative value results in a negative value. 797 // TODO(jarin) Use a range here. 798 return Type::Negative32(); 799 } 800 return Type::Signed32(); 801} 802 803Type* OperationTyper::NumberShiftLeft(Type* lhs, Type* rhs) { 804 DCHECK(lhs->Is(Type::Number())); 805 DCHECK(rhs->Is(Type::Number())); 806 807 if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None(); 808 809 lhs = NumberToInt32(lhs); 810 rhs = NumberToUint32(rhs); 811 812 int32_t min_lhs = lhs->Min(); 813 int32_t max_lhs = lhs->Max(); 814 uint32_t min_rhs = rhs->Min(); 815 uint32_t max_rhs = rhs->Max(); 816 if (max_rhs > 31) { 817 // rhs can be larger than the bitmask 818 max_rhs = 31; 819 min_rhs = 0; 820 } 821 822 if (max_lhs > (kMaxInt >> max_rhs) || min_lhs < (kMinInt >> max_rhs)) { 823 // overflow possible 824 return Type::Signed32(); 825 } 826 827 double min = 828 std::min(static_cast<int32_t>(static_cast<uint32_t>(min_lhs) << min_rhs), 829 static_cast<int32_t>(static_cast<uint32_t>(min_lhs) << max_rhs)); 830 double max = 831 std::max(static_cast<int32_t>(static_cast<uint32_t>(max_lhs) << min_rhs), 832 static_cast<int32_t>(static_cast<uint32_t>(max_lhs) << max_rhs)); 833 834 if (max == kMaxInt && min == kMinInt) return Type::Signed32(); 835 return Type::Range(min, max, zone()); 836} 837 838Type* OperationTyper::NumberShiftRight(Type* lhs, Type* rhs) { 839 DCHECK(lhs->Is(Type::Number())); 840 DCHECK(rhs->Is(Type::Number())); 841 842 if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None(); 843 844 lhs = NumberToInt32(lhs); 845 rhs = NumberToUint32(rhs); 846 847 int32_t min_lhs = lhs->Min(); 848 int32_t max_lhs = lhs->Max(); 849 uint32_t min_rhs = rhs->Min(); 850 uint32_t max_rhs = rhs->Max(); 851 if (max_rhs > 31) { 852 // rhs can be larger than the bitmask 853 max_rhs = 31; 854 min_rhs = 0; 855 } 856 double min = std::min(min_lhs >> min_rhs, min_lhs >> max_rhs); 857 double max = std::max(max_lhs >> min_rhs, max_lhs >> max_rhs); 858 859 if (max == kMaxInt && min == kMinInt) return Type::Signed32(); 860 return Type::Range(min, max, zone()); 861} 862 863Type* OperationTyper::NumberShiftRightLogical(Type* lhs, Type* rhs) { 864 DCHECK(lhs->Is(Type::Number())); 865 DCHECK(rhs->Is(Type::Number())); 866 867 if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None(); 868 869 lhs = NumberToUint32(lhs); 870 rhs = NumberToUint32(rhs); 871 872 uint32_t min_lhs = lhs->Min(); 873 uint32_t max_lhs = lhs->Max(); 874 uint32_t min_rhs = rhs->Min(); 875 uint32_t max_rhs = rhs->Max(); 876 if (max_rhs > 31) { 877 // rhs can be larger than the bitmask 878 max_rhs = 31; 879 min_rhs = 0; 880 } 881 882 double min = min_lhs >> max_rhs; 883 double max = max_lhs >> min_rhs; 884 DCHECK_LE(0, min); 885 DCHECK_LE(max, kMaxUInt32); 886 887 if (min == 0 && max == kMaxInt) return Type::Unsigned31(); 888 if (min == 0 && max == kMaxUInt32) return Type::Unsigned32(); 889 return Type::Range(min, max, zone()); 890} 891 892Type* OperationTyper::NumberAtan2(Type* lhs, Type* rhs) { 893 DCHECK(lhs->Is(Type::Number())); 894 DCHECK(rhs->Is(Type::Number())); 895 return Type::Number(); 896} 897 898Type* OperationTyper::NumberImul(Type* lhs, Type* rhs) { 899 DCHECK(lhs->Is(Type::Number())); 900 DCHECK(rhs->Is(Type::Number())); 901 // TODO(turbofan): We should be able to do better here. 902 return Type::Signed32(); 903} 904 905Type* OperationTyper::NumberMax(Type* lhs, Type* rhs) { 906 DCHECK(lhs->Is(Type::Number())); 907 DCHECK(rhs->Is(Type::Number())); 908 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) { 909 return Type::NaN(); 910 } 911 Type* type = Type::None(); 912 // TODO(turbofan): Improve minus zero handling here. 913 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) { 914 type = Type::Union(type, Type::NaN(), zone()); 915 } 916 lhs = Type::Intersect(lhs, Type::OrderedNumber(), zone()); 917 rhs = Type::Intersect(rhs, Type::OrderedNumber(), zone()); 918 if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) { 919 double max = std::max(lhs->Max(), rhs->Max()); 920 double min = std::max(lhs->Min(), rhs->Min()); 921 type = Type::Union(type, Type::Range(min, max, zone()), zone()); 922 } else { 923 type = Type::Union(type, Type::Union(lhs, rhs, zone()), zone()); 924 } 925 return type; 926} 927 928Type* OperationTyper::NumberMin(Type* lhs, Type* rhs) { 929 DCHECK(lhs->Is(Type::Number())); 930 DCHECK(rhs->Is(Type::Number())); 931 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) { 932 return Type::NaN(); 933 } 934 Type* type = Type::None(); 935 // TODO(turbofan): Improve minus zero handling here. 936 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) { 937 type = Type::Union(type, Type::NaN(), zone()); 938 } 939 lhs = Type::Intersect(lhs, Type::OrderedNumber(), zone()); 940 rhs = Type::Intersect(rhs, Type::OrderedNumber(), zone()); 941 if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) { 942 double max = std::min(lhs->Max(), rhs->Max()); 943 double min = std::min(lhs->Min(), rhs->Min()); 944 type = Type::Union(type, Type::Range(min, max, zone()), zone()); 945 } else { 946 type = Type::Union(type, Type::Union(lhs, rhs, zone()), zone()); 947 } 948 return type; 949} 950 951Type* OperationTyper::NumberPow(Type* lhs, Type* rhs) { 952 DCHECK(lhs->Is(Type::Number())); 953 DCHECK(rhs->Is(Type::Number())); 954 // TODO(turbofan): We should be able to do better here. 955 return Type::Number(); 956} 957 958#define SPECULATIVE_NUMBER_BINOP(Name) \ 959 Type* OperationTyper::Speculative##Name(Type* lhs, Type* rhs) { \ 960 lhs = ToNumber(Type::Intersect(lhs, Type::NumberOrOddball(), zone())); \ 961 rhs = ToNumber(Type::Intersect(rhs, Type::NumberOrOddball(), zone())); \ 962 return Name(lhs, rhs); \ 963 } 964SPECULATIVE_NUMBER_BINOP(NumberAdd) 965SPECULATIVE_NUMBER_BINOP(NumberSubtract) 966SPECULATIVE_NUMBER_BINOP(NumberMultiply) 967SPECULATIVE_NUMBER_BINOP(NumberDivide) 968SPECULATIVE_NUMBER_BINOP(NumberModulus) 969SPECULATIVE_NUMBER_BINOP(NumberBitwiseOr) 970SPECULATIVE_NUMBER_BINOP(NumberBitwiseAnd) 971SPECULATIVE_NUMBER_BINOP(NumberBitwiseXor) 972SPECULATIVE_NUMBER_BINOP(NumberShiftLeft) 973SPECULATIVE_NUMBER_BINOP(NumberShiftRight) 974SPECULATIVE_NUMBER_BINOP(NumberShiftRightLogical) 975#undef SPECULATIVE_NUMBER_BINOP 976 977Type* OperationTyper::ToPrimitive(Type* type) { 978 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) { 979 return type; 980 } 981 return Type::Primitive(); 982} 983 984Type* OperationTyper::Invert(Type* type) { 985 DCHECK(type->Is(Type::Boolean())); 986 DCHECK(type->IsInhabited()); 987 if (type->Is(singleton_false())) return singleton_true(); 988 if (type->Is(singleton_true())) return singleton_false(); 989 return type; 990} 991 992OperationTyper::ComparisonOutcome OperationTyper::Invert( 993 ComparisonOutcome outcome) { 994 ComparisonOutcome result(0); 995 if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined; 996 if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse; 997 if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue; 998 return result; 999} 1000 1001Type* OperationTyper::FalsifyUndefined(ComparisonOutcome outcome) { 1002 if ((outcome & kComparisonFalse) != 0 || 1003 (outcome & kComparisonUndefined) != 0) { 1004 return (outcome & kComparisonTrue) != 0 ? Type::Boolean() 1005 : singleton_false(); 1006 } 1007 // Type should be non empty, so we know it should be true. 1008 DCHECK((outcome & kComparisonTrue) != 0); 1009 return singleton_true(); 1010} 1011 1012Type* OperationTyper::TypeTypeGuard(const Operator* sigma_op, Type* input) { 1013 return Type::Intersect(input, TypeGuardTypeOf(sigma_op), zone()); 1014} 1015 1016} // namespace compiler 1017} // namespace internal 1018} // namespace v8 1019