1// Copyright 2015 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/representation-change.h" 6 7#include <sstream> 8 9#include "src/base/bits.h" 10#include "src/base/safe_conversions.h" 11#include "src/codegen/code-factory.h" 12#include "src/compiler/js-heap-broker.h" 13#include "src/compiler/machine-operator.h" 14#include "src/compiler/node-matchers.h" 15#include "src/compiler/simplified-lowering-verifier.h" 16#include "src/compiler/simplified-operator.h" 17#include "src/compiler/type-cache.h" 18#include "src/heap/factory-inl.h" 19 20namespace v8 { 21namespace internal { 22namespace compiler { 23 24const char* Truncation::description() const { 25 switch (kind()) { 26 case TruncationKind::kNone: 27 return "no-value-use"; 28 case TruncationKind::kBool: 29 return "truncate-to-bool"; 30 case TruncationKind::kWord32: 31 return "truncate-to-word32"; 32 case TruncationKind::kWord64: 33 return "truncate-to-word64"; 34 case TruncationKind::kOddballAndBigIntToNumber: 35 switch (identify_zeros()) { 36 case kIdentifyZeros: 37 return "truncate-oddball&bigint-to-number (identify zeros)"; 38 case kDistinguishZeros: 39 return "truncate-oddball&bigint-to-number (distinguish zeros)"; 40 } 41 case TruncationKind::kAny: 42 switch (identify_zeros()) { 43 case kIdentifyZeros: 44 return "no-truncation (but identify zeros)"; 45 case kDistinguishZeros: 46 return "no-truncation (but distinguish zeros)"; 47 } 48 } 49 UNREACHABLE(); 50} 51 52// Partial order for truncations: 53// 54// kAny <-------+ 55// ^ | 56// | | 57// kOddballAndBigIntToNumber | 58// ^ | 59// / | 60// kWord64 | 61// ^ | 62// | | 63// kWord32 kBool 64// ^ ^ 65// \ / 66// \ / 67// \ / 68// \ / 69// \ / 70// kNone 71// 72// TODO(jarin) We might consider making kBool < kOddballAndBigIntToNumber. 73 74// static 75Truncation::TruncationKind Truncation::Generalize(TruncationKind rep1, 76 TruncationKind rep2) { 77 if (LessGeneral(rep1, rep2)) return rep2; 78 if (LessGeneral(rep2, rep1)) return rep1; 79 // Handle the generalization of float64-representable values. 80 if (LessGeneral(rep1, TruncationKind::kOddballAndBigIntToNumber) && 81 LessGeneral(rep2, TruncationKind::kOddballAndBigIntToNumber)) { 82 return TruncationKind::kOddballAndBigIntToNumber; 83 } 84 // Handle the generalization of any-representable values. 85 if (LessGeneral(rep1, TruncationKind::kAny) && 86 LessGeneral(rep2, TruncationKind::kAny)) { 87 return TruncationKind::kAny; 88 } 89 // All other combinations are illegal. 90 FATAL("Tried to combine incompatible truncations"); 91} 92 93// static 94IdentifyZeros Truncation::GeneralizeIdentifyZeros(IdentifyZeros i1, 95 IdentifyZeros i2) { 96 if (i1 == i2) { 97 return i1; 98 } else { 99 return kDistinguishZeros; 100 } 101} 102 103// static 104bool Truncation::LessGeneral(TruncationKind rep1, TruncationKind rep2) { 105 switch (rep1) { 106 case TruncationKind::kNone: 107 return true; 108 case TruncationKind::kBool: 109 return rep2 == TruncationKind::kBool || rep2 == TruncationKind::kAny; 110 case TruncationKind::kWord32: 111 return rep2 == TruncationKind::kWord32 || 112 rep2 == TruncationKind::kWord64 || 113 rep2 == TruncationKind::kOddballAndBigIntToNumber || 114 rep2 == TruncationKind::kAny; 115 case TruncationKind::kWord64: 116 return rep2 == TruncationKind::kWord64 || 117 rep2 == TruncationKind::kOddballAndBigIntToNumber || 118 rep2 == TruncationKind::kAny; 119 case TruncationKind::kOddballAndBigIntToNumber: 120 return rep2 == TruncationKind::kOddballAndBigIntToNumber || 121 rep2 == TruncationKind::kAny; 122 case TruncationKind::kAny: 123 return rep2 == TruncationKind::kAny; 124 } 125 UNREACHABLE(); 126} 127 128// static 129bool Truncation::LessGeneralIdentifyZeros(IdentifyZeros i1, IdentifyZeros i2) { 130 return i1 == i2 || i1 == kIdentifyZeros; 131} 132 133namespace { 134 135bool IsWord(MachineRepresentation rep) { 136 return rep == MachineRepresentation::kWord8 || 137 rep == MachineRepresentation::kWord16 || 138 rep == MachineRepresentation::kWord32; 139} 140 141} // namespace 142 143RepresentationChanger::RepresentationChanger( 144 JSGraph* jsgraph, JSHeapBroker* broker, 145 SimplifiedLoweringVerifier* verifier) 146 : cache_(TypeCache::Get()), 147 jsgraph_(jsgraph), 148 broker_(broker), 149 verifier_(verifier), 150 testing_type_errors_(false), 151 type_error_(false) {} 152 153// Changes representation from {output_rep} to {use_rep}. The {truncation} 154// parameter is only used for checking - if the changer cannot figure 155// out signedness for the word32->float64 conversion, then we check that the 156// uses truncate to word32 (so they do not care about signedness). 157Node* RepresentationChanger::GetRepresentationFor( 158 Node* node, MachineRepresentation output_rep, Type output_type, 159 Node* use_node, UseInfo use_info) { 160 if (output_rep == MachineRepresentation::kNone && !output_type.IsNone()) { 161 // The output representation should be set if the type is inhabited (i.e., 162 // if the value is possible). 163 return TypeError(node, output_rep, output_type, use_info.representation()); 164 } 165 166 // Rematerialize any truncated BigInt if user is not expecting a BigInt. 167 if (output_type.Is(Type::BigInt()) && 168 output_rep == MachineRepresentation::kWord64 && 169 use_info.type_check() != TypeCheckKind::kBigInt) { 170 if (output_type.Is(Type::UnsignedBigInt64())) { 171 node = InsertConversion(node, simplified()->ChangeUint64ToBigInt(), 172 use_node); 173 } else { 174 node = 175 InsertConversion(node, simplified()->ChangeInt64ToBigInt(), use_node); 176 } 177 output_rep = MachineRepresentation::kTaggedPointer; 178 } 179 180 // Handle the no-op shortcuts when no checking is necessary. 181 if (use_info.type_check() == TypeCheckKind::kNone || 182 // TODO(nicohartmann@, chromium:1077804): Ignoring {use_info.type_check()} 183 // in case the representation already matches is not correct. For now, 184 // this behavior is disabled only for TypeCheckKind::kBigInt, but should 185 // be fixed for all other type checks. 186 (output_rep != MachineRepresentation::kWord32 && 187 use_info.type_check() != TypeCheckKind::kBigInt)) { 188 if (use_info.representation() == output_rep) { 189 // Representations are the same. That's a no-op. 190 return node; 191 } 192 if (IsWord(use_info.representation()) && IsWord(output_rep)) { 193 // Both are words less than or equal to 32-bits. 194 // Since loads of integers from memory implicitly sign or zero extend the 195 // value to the full machine word size and stores implicitly truncate, 196 // no representation change is necessary. 197 return node; 198 } 199 } 200 201 switch (use_info.representation()) { 202 case MachineRepresentation::kTaggedSigned: 203 DCHECK(use_info.type_check() == TypeCheckKind::kNone || 204 use_info.type_check() == TypeCheckKind::kSignedSmall); 205 return GetTaggedSignedRepresentationFor(node, output_rep, output_type, 206 use_node, use_info); 207 case MachineRepresentation::kTaggedPointer: 208 DCHECK(use_info.type_check() == TypeCheckKind::kNone || 209 use_info.type_check() == TypeCheckKind::kHeapObject || 210 use_info.type_check() == TypeCheckKind::kBigInt); 211 return GetTaggedPointerRepresentationFor(node, output_rep, output_type, 212 use_node, use_info); 213 case MachineRepresentation::kTagged: 214 DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check()); 215 return GetTaggedRepresentationFor(node, output_rep, output_type, 216 use_info.truncation()); 217 case MachineRepresentation::kFloat32: 218 DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check()); 219 return GetFloat32RepresentationFor(node, output_rep, output_type, 220 use_info.truncation()); 221 case MachineRepresentation::kFloat64: 222 DCHECK(use_info.type_check() == TypeCheckKind::kNone || 223 use_info.type_check() == TypeCheckKind::kNumber || 224 use_info.type_check() == TypeCheckKind::kNumberOrBoolean || 225 use_info.type_check() == TypeCheckKind::kNumberOrOddball); 226 return GetFloat64RepresentationFor(node, output_rep, output_type, 227 use_node, use_info); 228 case MachineRepresentation::kBit: 229 DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check()); 230 return GetBitRepresentationFor(node, output_rep, output_type); 231 case MachineRepresentation::kWord8: 232 case MachineRepresentation::kWord16: 233 case MachineRepresentation::kWord32: 234 return GetWord32RepresentationFor(node, output_rep, output_type, use_node, 235 use_info); 236 case MachineRepresentation::kWord64: 237 DCHECK(use_info.type_check() == TypeCheckKind::kNone || 238 use_info.type_check() == TypeCheckKind::kSigned64 || 239 use_info.type_check() == TypeCheckKind::kBigInt || 240 use_info.type_check() == TypeCheckKind::kArrayIndex); 241 return GetWord64RepresentationFor(node, output_rep, output_type, use_node, 242 use_info); 243 case MachineRepresentation::kSimd128: 244 case MachineRepresentation::kNone: 245 return node; 246 case MachineRepresentation::kCompressed: 247 case MachineRepresentation::kCompressedPointer: 248 case MachineRepresentation::kSandboxedPointer: 249 case MachineRepresentation::kMapWord: 250 UNREACHABLE(); 251 } 252 UNREACHABLE(); 253} 254 255Node* RepresentationChanger::GetTaggedSignedRepresentationFor( 256 Node* node, MachineRepresentation output_rep, Type output_type, 257 Node* use_node, UseInfo use_info) { 258 // Eagerly fold representation changes for constants. 259 switch (node->opcode()) { 260 case IrOpcode::kNumberConstant: 261 if (output_type.Is(Type::SignedSmall())) { 262 return node; 263 } 264 break; 265 default: 266 break; 267 } 268 // Select the correct X -> Tagged operator. 269 const Operator* op; 270 if (output_type.Is(Type::None())) { 271 // This is an impossible value; it should not be used at runtime. 272 return jsgraph()->graph()->NewNode( 273 jsgraph()->common()->DeadValue(MachineRepresentation::kTaggedSigned), 274 node); 275 } else if (IsWord(output_rep)) { 276 if (output_type.Is(Type::Signed31())) { 277 op = simplified()->ChangeInt31ToTaggedSigned(); 278 } else if (output_type.Is(Type::Signed32())) { 279 if (SmiValuesAre32Bits()) { 280 op = simplified()->ChangeInt32ToTagged(); 281 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) { 282 op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback()); 283 } else { 284 return TypeError(node, output_rep, output_type, 285 MachineRepresentation::kTaggedSigned); 286 } 287 } else if (output_type.Is(Type::Unsigned32()) && 288 use_info.type_check() == TypeCheckKind::kSignedSmall) { 289 op = simplified()->CheckedUint32ToTaggedSigned(use_info.feedback()); 290 } else { 291 return TypeError(node, output_rep, output_type, 292 MachineRepresentation::kTaggedSigned); 293 } 294 } else if (output_rep == MachineRepresentation::kWord64) { 295 if (output_type.Is(Type::Signed31())) { 296 // int64 -> int32 -> tagged signed 297 node = InsertTruncateInt64ToInt32(node); 298 op = simplified()->ChangeInt31ToTaggedSigned(); 299 } else if (output_type.Is(Type::Signed32()) && SmiValuesAre32Bits()) { 300 // int64 -> int32 -> tagged signed 301 node = InsertTruncateInt64ToInt32(node); 302 op = simplified()->ChangeInt32ToTagged(); 303 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) { 304 if (output_type.Is(cache_->kPositiveSafeInteger)) { 305 op = simplified()->CheckedUint64ToTaggedSigned(use_info.feedback()); 306 } else if (output_type.Is(cache_->kSafeInteger)) { 307 op = simplified()->CheckedInt64ToTaggedSigned(use_info.feedback()); 308 } else { 309 return TypeError(node, output_rep, output_type, 310 MachineRepresentation::kTaggedSigned); 311 } 312 } else { 313 return TypeError(node, output_rep, output_type, 314 MachineRepresentation::kTaggedSigned); 315 } 316 } else if (output_rep == MachineRepresentation::kFloat64) { 317 if (output_type.Is(Type::Signed31())) { 318 // float64 -> int32 -> tagged signed 319 node = InsertChangeFloat64ToInt32(node); 320 op = simplified()->ChangeInt31ToTaggedSigned(); 321 } else if (output_type.Is(Type::Signed32())) { 322 // float64 -> int32 -> tagged signed 323 node = InsertChangeFloat64ToInt32(node); 324 if (SmiValuesAre32Bits()) { 325 op = simplified()->ChangeInt32ToTagged(); 326 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) { 327 op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback()); 328 } else { 329 return TypeError(node, output_rep, output_type, 330 MachineRepresentation::kTaggedSigned); 331 } 332 } else if (output_type.Is(Type::Unsigned32()) && 333 use_info.type_check() == TypeCheckKind::kSignedSmall) { 334 // float64 -> uint32 -> tagged signed 335 node = InsertChangeFloat64ToUint32(node); 336 op = simplified()->CheckedUint32ToTaggedSigned(use_info.feedback()); 337 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) { 338 node = InsertCheckedFloat64ToInt32( 339 node, 340 output_type.Maybe(Type::MinusZero()) 341 ? CheckForMinusZeroMode::kCheckForMinusZero 342 : CheckForMinusZeroMode::kDontCheckForMinusZero, 343 use_info.feedback(), use_node); 344 if (SmiValuesAre32Bits()) { 345 op = simplified()->ChangeInt32ToTagged(); 346 } else { 347 op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback()); 348 } 349 } else { 350 return TypeError(node, output_rep, output_type, 351 MachineRepresentation::kTaggedSigned); 352 } 353 } else if (output_rep == MachineRepresentation::kFloat32) { 354 if (use_info.type_check() == TypeCheckKind::kSignedSmall) { 355 node = InsertChangeFloat32ToFloat64(node); 356 node = InsertCheckedFloat64ToInt32( 357 node, 358 output_type.Maybe(Type::MinusZero()) 359 ? CheckForMinusZeroMode::kCheckForMinusZero 360 : CheckForMinusZeroMode::kDontCheckForMinusZero, 361 use_info.feedback(), use_node); 362 if (SmiValuesAre32Bits()) { 363 op = simplified()->ChangeInt32ToTagged(); 364 } else { 365 op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback()); 366 } 367 } else { 368 return TypeError(node, output_rep, output_type, 369 MachineRepresentation::kTaggedSigned); 370 } 371 } else if (CanBeTaggedPointer(output_rep)) { 372 if (use_info.type_check() == TypeCheckKind::kSignedSmall) { 373 op = simplified()->CheckedTaggedToTaggedSigned(use_info.feedback()); 374 } else if (output_type.Is(Type::SignedSmall())) { 375 op = simplified()->ChangeTaggedToTaggedSigned(); 376 } else { 377 return TypeError(node, output_rep, output_type, 378 MachineRepresentation::kTaggedSigned); 379 } 380 } else if (output_rep == MachineRepresentation::kBit) { 381 if (use_info.type_check() == TypeCheckKind::kSignedSmall) { 382 // TODO(turbofan): Consider adding a Bailout operator that just deopts. 383 // Also use that for MachineRepresentation::kPointer case above. 384 node = InsertChangeBitToTagged(node); 385 op = simplified()->CheckedTaggedToTaggedSigned(use_info.feedback()); 386 } else { 387 return TypeError(node, output_rep, output_type, 388 MachineRepresentation::kTaggedSigned); 389 } 390 } else { 391 return TypeError(node, output_rep, output_type, 392 MachineRepresentation::kTaggedSigned); 393 } 394 return InsertConversion(node, op, use_node); 395} 396 397Node* RepresentationChanger::GetTaggedPointerRepresentationFor( 398 Node* node, MachineRepresentation output_rep, Type output_type, 399 Node* use_node, UseInfo use_info) { 400 // Eagerly fold representation changes for constants. 401 switch (node->opcode()) { 402 case IrOpcode::kHeapConstant: 403 case IrOpcode::kDelayedStringConstant: 404 if (use_info.type_check() == TypeCheckKind::kBigInt) break; 405 return node; // No change necessary. 406 case IrOpcode::kInt32Constant: 407 case IrOpcode::kFloat64Constant: 408 case IrOpcode::kFloat32Constant: 409 UNREACHABLE(); 410 default: 411 break; 412 } 413 // Select the correct X -> TaggedPointer operator. 414 Operator const* op; 415 if (output_type.Is(Type::None())) { 416 // This is an impossible value; it should not be used at runtime. 417 return jsgraph()->graph()->NewNode( 418 jsgraph()->common()->DeadValue(MachineRepresentation::kTaggedPointer), 419 node); 420 } 421 422 if (use_info.type_check() == TypeCheckKind::kBigInt && 423 !output_type.Is(Type::BigInt())) { 424 // BigInt checks can only be performed on tagged representations. Note that 425 // a corresponding check is inserted down below. 426 if (!CanBeTaggedPointer(output_rep)) { 427 Node* unreachable = 428 InsertUnconditionalDeopt(use_node, DeoptimizeReason::kNotABigInt); 429 return jsgraph()->graph()->NewNode( 430 jsgraph()->common()->DeadValue(MachineRepresentation::kTaggedPointer), 431 unreachable); 432 } 433 } 434 435 if (output_rep == MachineRepresentation::kBit) { 436 if (output_type.Is(Type::Boolean())) { 437 op = simplified()->ChangeBitToTagged(); 438 } else { 439 return TypeError(node, output_rep, output_type, 440 MachineRepresentation::kTagged); 441 } 442 } else if (IsWord(output_rep)) { 443 if (output_type.Is(Type::Unsigned32())) { 444 // uint32 -> float64 -> tagged 445 node = InsertChangeUint32ToFloat64(node); 446 } else if (output_type.Is(Type::Signed32())) { 447 // int32 -> float64 -> tagged 448 node = InsertChangeInt32ToFloat64(node); 449 } else { 450 return TypeError(node, output_rep, output_type, 451 MachineRepresentation::kTaggedPointer); 452 } 453 op = simplified()->ChangeFloat64ToTaggedPointer(); 454 } else if (output_rep == MachineRepresentation::kWord64) { 455 if (output_type.Is(cache_->kSafeInteger)) { 456 // int64 -> float64 -> tagged pointer 457 op = machine()->ChangeInt64ToFloat64(); 458 node = jsgraph()->graph()->NewNode(op, node); 459 op = simplified()->ChangeFloat64ToTaggedPointer(); 460 } else if (output_type.Is(Type::SignedBigInt64()) && 461 use_info.type_check() == TypeCheckKind::kBigInt) { 462 op = simplified()->ChangeInt64ToBigInt(); 463 } else if (output_type.Is(Type::UnsignedBigInt64()) && 464 use_info.type_check() == TypeCheckKind::kBigInt) { 465 op = simplified()->ChangeUint64ToBigInt(); 466 } else { 467 return TypeError(node, output_rep, output_type, 468 MachineRepresentation::kTaggedPointer); 469 } 470 } else if (output_rep == MachineRepresentation::kFloat32) { 471 if (output_type.Is(Type::Number())) { 472 // float32 -> float64 -> tagged 473 node = InsertChangeFloat32ToFloat64(node); 474 op = simplified()->ChangeFloat64ToTaggedPointer(); 475 } else { 476 return TypeError(node, output_rep, output_type, 477 MachineRepresentation::kTaggedPointer); 478 } 479 } else if (output_rep == MachineRepresentation::kFloat64) { 480 if (output_type.Is(Type::Number())) { 481 // float64 -> tagged 482 op = simplified()->ChangeFloat64ToTaggedPointer(); 483 } else { 484 return TypeError(node, output_rep, output_type, 485 MachineRepresentation::kTaggedPointer); 486 } 487 } else if (CanBeTaggedSigned(output_rep) && 488 use_info.type_check() == TypeCheckKind::kHeapObject) { 489 if (!output_type.Maybe(Type::SignedSmall())) { 490 return node; 491 } 492 // TODO(turbofan): Consider adding a Bailout operator that just deopts 493 // for TaggedSigned output representation. 494 op = simplified()->CheckedTaggedToTaggedPointer(use_info.feedback()); 495 } else if (IsAnyTagged(output_rep) && 496 (use_info.type_check() == TypeCheckKind::kBigInt || 497 output_type.Is(Type::BigInt()))) { 498 if (output_type.Is(Type::BigInt())) { 499 return node; 500 } 501 op = simplified()->CheckBigInt(use_info.feedback()); 502 } else { 503 return TypeError(node, output_rep, output_type, 504 MachineRepresentation::kTaggedPointer); 505 } 506 return InsertConversion(node, op, use_node); 507} 508 509Node* RepresentationChanger::GetTaggedRepresentationFor( 510 Node* node, MachineRepresentation output_rep, Type output_type, 511 Truncation truncation) { 512 // Eagerly fold representation changes for constants. 513 switch (node->opcode()) { 514 case IrOpcode::kNumberConstant: 515 case IrOpcode::kHeapConstant: 516 case IrOpcode::kDelayedStringConstant: 517 return node; // No change necessary. 518 case IrOpcode::kInt32Constant: 519 case IrOpcode::kFloat64Constant: 520 case IrOpcode::kFloat32Constant: 521 UNREACHABLE(); 522 default: 523 break; 524 } 525 if (output_rep == MachineRepresentation::kTaggedSigned || 526 output_rep == MachineRepresentation::kTaggedPointer || 527 output_rep == MachineRepresentation::kMapWord) { 528 // this is a no-op. 529 return node; 530 } 531 // Select the correct X -> Tagged operator. 532 const Operator* op; 533 if (output_type.Is(Type::None())) { 534 // This is an impossible value; it should not be used at runtime. 535 return jsgraph()->graph()->NewNode( 536 jsgraph()->common()->DeadValue(MachineRepresentation::kTagged), node); 537 } else if (output_rep == MachineRepresentation::kBit) { 538 if (output_type.Is(Type::Boolean())) { 539 op = simplified()->ChangeBitToTagged(); 540 } else { 541 return TypeError(node, output_rep, output_type, 542 MachineRepresentation::kTagged); 543 } 544 } else if (IsWord(output_rep)) { 545 if (output_type.Is(Type::Signed31())) { 546 op = simplified()->ChangeInt31ToTaggedSigned(); 547 } else if (output_type.Is(Type::Signed32()) || 548 (output_type.Is(Type::Signed32OrMinusZero()) && 549 truncation.IdentifiesZeroAndMinusZero())) { 550 op = simplified()->ChangeInt32ToTagged(); 551 } else if (output_type.Is(Type::Unsigned32()) || 552 (output_type.Is(Type::Unsigned32OrMinusZero()) && 553 truncation.IdentifiesZeroAndMinusZero()) || 554 truncation.IsUsedAsWord32()) { 555 // Either the output is uint32 or the uses only care about the 556 // low 32 bits (so we can pick uint32 safely). 557 op = simplified()->ChangeUint32ToTagged(); 558 } else { 559 return TypeError(node, output_rep, output_type, 560 MachineRepresentation::kTagged); 561 } 562 } else if (output_rep == MachineRepresentation::kWord64) { 563 if (output_type.Is(Type::Signed31())) { 564 // int64 -> int32 -> tagged signed 565 node = InsertTruncateInt64ToInt32(node); 566 op = simplified()->ChangeInt31ToTaggedSigned(); 567 } else if (output_type.Is(Type::Signed32())) { 568 // int64 -> int32 -> tagged 569 node = InsertTruncateInt64ToInt32(node); 570 op = simplified()->ChangeInt32ToTagged(); 571 } else if (output_type.Is(Type::Unsigned32())) { 572 // int64 -> uint32 -> tagged 573 node = InsertTruncateInt64ToInt32(node); 574 op = simplified()->ChangeUint32ToTagged(); 575 } else if (output_type.Is(cache_->kPositiveSafeInteger)) { 576 // uint64 -> tagged 577 op = simplified()->ChangeUint64ToTagged(); 578 } else if (output_type.Is(cache_->kSafeInteger)) { 579 // int64 -> tagged 580 op = simplified()->ChangeInt64ToTagged(); 581 } else if (output_type.Is(Type::SignedBigInt64())) { 582 // int64 -> BigInt 583 op = simplified()->ChangeInt64ToBigInt(); 584 } else if (output_type.Is(Type::UnsignedBigInt64())) { 585 // uint64 -> BigInt 586 op = simplified()->ChangeUint64ToBigInt(); 587 } else { 588 return TypeError(node, output_rep, output_type, 589 MachineRepresentation::kTagged); 590 } 591 } else if (output_rep == 592 MachineRepresentation::kFloat32) { // float32 -> float64 -> tagged 593 node = InsertChangeFloat32ToFloat64(node); 594 op = simplified()->ChangeFloat64ToTagged( 595 output_type.Maybe(Type::MinusZero()) 596 ? CheckForMinusZeroMode::kCheckForMinusZero 597 : CheckForMinusZeroMode::kDontCheckForMinusZero); 598 } else if (output_rep == MachineRepresentation::kFloat64) { 599 if (output_type.Is(Type::Signed31())) { // float64 -> int32 -> tagged 600 node = InsertChangeFloat64ToInt32(node); 601 op = simplified()->ChangeInt31ToTaggedSigned(); 602 } else if (output_type.Is( 603 Type::Signed32())) { // float64 -> int32 -> tagged 604 node = InsertChangeFloat64ToInt32(node); 605 op = simplified()->ChangeInt32ToTagged(); 606 } else if (output_type.Is( 607 Type::Unsigned32())) { // float64 -> uint32 -> tagged 608 node = InsertChangeFloat64ToUint32(node); 609 op = simplified()->ChangeUint32ToTagged(); 610 } else if (output_type.Is(Type::Number()) || 611 (output_type.Is(Type::NumberOrOddball()) && 612 truncation.TruncatesOddballAndBigIntToNumber())) { 613 op = simplified()->ChangeFloat64ToTagged( 614 output_type.Maybe(Type::MinusZero()) 615 ? CheckForMinusZeroMode::kCheckForMinusZero 616 : CheckForMinusZeroMode::kDontCheckForMinusZero); 617 } else { 618 return TypeError(node, output_rep, output_type, 619 MachineRepresentation::kTagged); 620 } 621 } else { 622 return TypeError(node, output_rep, output_type, 623 MachineRepresentation::kTagged); 624 } 625 return jsgraph()->graph()->NewNode(op, node); 626} 627 628Node* RepresentationChanger::GetFloat32RepresentationFor( 629 Node* node, MachineRepresentation output_rep, Type output_type, 630 Truncation truncation) { 631 // Eagerly fold representation changes for constants. 632 switch (node->opcode()) { 633 case IrOpcode::kNumberConstant: 634 return jsgraph()->Float32Constant( 635 DoubleToFloat32(OpParameter<double>(node->op()))); 636 case IrOpcode::kInt32Constant: 637 case IrOpcode::kFloat64Constant: 638 case IrOpcode::kFloat32Constant: 639 UNREACHABLE(); 640 default: 641 break; 642 } 643 // Select the correct X -> Float32 operator. 644 const Operator* op = nullptr; 645 if (output_type.Is(Type::None())) { 646 // This is an impossible value; it should not be used at runtime. 647 return jsgraph()->graph()->NewNode( 648 jsgraph()->common()->DeadValue(MachineRepresentation::kFloat32), node); 649 } else if (IsWord(output_rep)) { 650 if (output_type.Is(Type::Signed32())) { 651 // int32 -> float64 -> float32 652 op = machine()->ChangeInt32ToFloat64(); 653 node = jsgraph()->graph()->NewNode(op, node); 654 op = machine()->TruncateFloat64ToFloat32(); 655 } else if (output_type.Is(Type::Unsigned32()) || 656 truncation.IsUsedAsWord32()) { 657 // Either the output is uint32 or the uses only care about the 658 // low 32 bits (so we can pick uint32 safely). 659 660 // uint32 -> float64 -> float32 661 op = machine()->ChangeUint32ToFloat64(); 662 node = jsgraph()->graph()->NewNode(op, node); 663 op = machine()->TruncateFloat64ToFloat32(); 664 } 665 } else if (IsAnyTagged(output_rep)) { 666 if (output_type.Is(Type::NumberOrOddball())) { 667 // tagged -> float64 -> float32 668 if (output_type.Is(Type::Number())) { 669 op = simplified()->ChangeTaggedToFloat64(); 670 } else { 671 op = simplified()->TruncateTaggedToFloat64(); 672 } 673 node = jsgraph()->graph()->NewNode(op, node); 674 op = machine()->TruncateFloat64ToFloat32(); 675 } 676 } else if (output_rep == MachineRepresentation::kFloat64) { 677 op = machine()->TruncateFloat64ToFloat32(); 678 } else if (output_rep == MachineRepresentation::kWord64) { 679 if (output_type.Is(cache_->kSafeInteger)) { 680 // int64 -> float64 -> float32 681 op = machine()->ChangeInt64ToFloat64(); 682 node = jsgraph()->graph()->NewNode(op, node); 683 op = machine()->TruncateFloat64ToFloat32(); 684 } 685 } 686 if (op == nullptr) { 687 return TypeError(node, output_rep, output_type, 688 MachineRepresentation::kFloat32); 689 } 690 return jsgraph()->graph()->NewNode(op, node); 691} 692 693Node* RepresentationChanger::GetFloat64RepresentationFor( 694 Node* node, MachineRepresentation output_rep, Type output_type, 695 Node* use_node, UseInfo use_info) { 696 NumberMatcher m(node); 697 if (m.HasResolvedValue()) { 698 // BigInts are not used as number constants. 699 DCHECK(use_info.type_check() != TypeCheckKind::kBigInt); 700 switch (use_info.type_check()) { 701 case TypeCheckKind::kNone: 702 case TypeCheckKind::kNumber: 703 case TypeCheckKind::kNumberOrBoolean: 704 case TypeCheckKind::kNumberOrOddball: 705 return jsgraph()->Float64Constant(m.ResolvedValue()); 706 case TypeCheckKind::kBigInt: 707 case TypeCheckKind::kHeapObject: 708 case TypeCheckKind::kSigned32: 709 case TypeCheckKind::kSigned64: 710 case TypeCheckKind::kSignedSmall: 711 case TypeCheckKind::kArrayIndex: 712 break; 713 } 714 } 715 // Select the correct X -> Float64 operator. 716 const Operator* op = nullptr; 717 if (output_type.Is(Type::None())) { 718 // This is an impossible value; it should not be used at runtime. 719 return jsgraph()->graph()->NewNode( 720 jsgraph()->common()->DeadValue(MachineRepresentation::kFloat64), node); 721 } else if (IsWord(output_rep)) { 722 if (output_type.Is(Type::Signed32()) || 723 (output_type.Is(Type::Signed32OrMinusZero()) && 724 use_info.truncation().IdentifiesZeroAndMinusZero())) { 725 op = machine()->ChangeInt32ToFloat64(); 726 } else if (output_type.Is(Type::Unsigned32()) || 727 (output_type.Is(Type::Unsigned32OrMinusZero()) && 728 use_info.truncation().IdentifiesZeroAndMinusZero()) || 729 use_info.truncation().IsUsedAsWord32()) { 730 // Either the output is uint32 or the uses only care about the 731 // low 32 bits (so we can pick uint32 safely). 732 op = machine()->ChangeUint32ToFloat64(); 733 } 734 } else if (output_rep == MachineRepresentation::kBit) { 735 CHECK(output_type.Is(Type::Boolean())); 736 if (use_info.truncation().TruncatesOddballAndBigIntToNumber() || 737 use_info.type_check() == TypeCheckKind::kNumberOrBoolean || 738 use_info.type_check() == TypeCheckKind::kNumberOrOddball) { 739 op = machine()->ChangeUint32ToFloat64(); 740 } else { 741 CHECK_NE(use_info.type_check(), TypeCheckKind::kNone); 742 Node* unreachable = 743 InsertUnconditionalDeopt(use_node, DeoptimizeReason::kNotAHeapNumber); 744 return jsgraph()->graph()->NewNode( 745 jsgraph()->common()->DeadValue(MachineRepresentation::kFloat64), 746 unreachable); 747 } 748 } else if (IsAnyTagged(output_rep)) { 749 if (output_type.Is(Type::Undefined())) { 750 if (use_info.type_check() == TypeCheckKind::kNumberOrOddball || 751 (use_info.type_check() == TypeCheckKind::kNone && 752 use_info.truncation().TruncatesOddballAndBigIntToNumber())) { 753 return jsgraph()->Float64Constant( 754 std::numeric_limits<double>::quiet_NaN()); 755 } else { 756 DCHECK(use_info.type_check() == TypeCheckKind::kNone || 757 use_info.type_check() == TypeCheckKind::kNumber || 758 use_info.type_check() == TypeCheckKind::kNumberOrBoolean); 759 Node* unreachable = InsertUnconditionalDeopt( 760 use_node, use_info.type_check() == TypeCheckKind::kNumber 761 ? DeoptimizeReason::kNotANumber 762 : DeoptimizeReason::kNotANumberOrBoolean); 763 return jsgraph()->graph()->NewNode( 764 jsgraph()->common()->DeadValue(MachineRepresentation::kFloat64), 765 unreachable); 766 } 767 } else if (output_rep == MachineRepresentation::kTaggedSigned) { 768 node = InsertChangeTaggedSignedToInt32(node); 769 op = machine()->ChangeInt32ToFloat64(); 770 } else if (output_type.Is(Type::Number())) { 771 op = simplified()->ChangeTaggedToFloat64(); 772 } else if ((output_type.Is(Type::NumberOrOddball()) && 773 use_info.truncation().TruncatesOddballAndBigIntToNumber()) || 774 output_type.Is(Type::NumberOrHole())) { 775 // JavaScript 'null' is an Oddball that results in +0 when truncated to 776 // Number. In a context like -0 == null, which must evaluate to false, 777 // this truncation must not happen. For this reason we restrict this 778 // case to when either the user explicitly requested a float (and thus 779 // wants +0 if null is the input) or we know from the types that the 780 // input can only be Number | Hole. The latter is necessary to handle 781 // the operator CheckFloat64Hole. We did not put in the type (Number | 782 // Oddball \ Null) to discover more bugs related to this conversion via 783 // crashes. 784 op = simplified()->TruncateTaggedToFloat64(); 785 } else if (use_info.type_check() == TypeCheckKind::kNumber || 786 (use_info.type_check() == TypeCheckKind::kNumberOrOddball && 787 !output_type.Maybe(Type::BooleanOrNullOrNumber()))) { 788 op = simplified()->CheckedTaggedToFloat64(CheckTaggedInputMode::kNumber, 789 use_info.feedback()); 790 } else if (use_info.type_check() == TypeCheckKind::kNumberOrBoolean) { 791 op = simplified()->CheckedTaggedToFloat64( 792 CheckTaggedInputMode::kNumberOrBoolean, use_info.feedback()); 793 } else if (use_info.type_check() == TypeCheckKind::kNumberOrOddball) { 794 op = simplified()->CheckedTaggedToFloat64( 795 CheckTaggedInputMode::kNumberOrOddball, use_info.feedback()); 796 } 797 } else if (output_rep == MachineRepresentation::kFloat32) { 798 op = machine()->ChangeFloat32ToFloat64(); 799 } else if (output_rep == MachineRepresentation::kWord64) { 800 if (output_type.Is(cache_->kSafeInteger)) { 801 op = machine()->ChangeInt64ToFloat64(); 802 } 803 } 804 if (op == nullptr) { 805 return TypeError(node, output_rep, output_type, 806 MachineRepresentation::kFloat64); 807 } 808 return InsertConversion(node, op, use_node); 809} 810 811Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) { 812 return jsgraph()->Int32Constant(DoubleToInt32(value)); 813} 814 815Node* RepresentationChanger::InsertUnconditionalDeopt( 816 Node* node, DeoptimizeReason reason, const FeedbackSource& feedback) { 817 Node* effect = NodeProperties::GetEffectInput(node); 818 Node* control = NodeProperties::GetControlInput(node); 819 effect = 820 jsgraph()->graph()->NewNode(simplified()->CheckIf(reason, feedback), 821 jsgraph()->Int32Constant(0), effect, control); 822 Node* unreachable = effect = jsgraph()->graph()->NewNode( 823 jsgraph()->common()->Unreachable(), effect, control); 824 NodeProperties::ReplaceEffectInput(node, effect); 825 return unreachable; 826} 827 828Node* RepresentationChanger::GetWord32RepresentationFor( 829 Node* node, MachineRepresentation output_rep, Type output_type, 830 Node* use_node, UseInfo use_info) { 831 // Eagerly fold representation changes for constants. 832 switch (node->opcode()) { 833 case IrOpcode::kInt32Constant: 834 case IrOpcode::kInt64Constant: 835 case IrOpcode::kFloat32Constant: 836 case IrOpcode::kFloat64Constant: 837 UNREACHABLE(); 838 case IrOpcode::kNumberConstant: { 839 double const fv = OpParameter<double>(node->op()); 840 if (use_info.type_check() == TypeCheckKind::kNone || 841 ((use_info.type_check() == TypeCheckKind::kSignedSmall || 842 use_info.type_check() == TypeCheckKind::kSigned32 || 843 use_info.type_check() == TypeCheckKind::kNumber || 844 use_info.type_check() == TypeCheckKind::kNumberOrOddball || 845 use_info.type_check() == TypeCheckKind::kArrayIndex) && 846 IsInt32Double(fv))) { 847 return InsertTypeOverrideForVerifier(NodeProperties::GetType(node), 848 MakeTruncatedInt32Constant(fv)); 849 } 850 break; 851 } 852 default: 853 break; 854 } 855 856 // Select the correct X -> Word32 operator. 857 const Operator* op = nullptr; 858 if (output_type.Is(Type::None())) { 859 // This is an impossible value; it should not be used at runtime. 860 return jsgraph()->graph()->NewNode( 861 jsgraph()->common()->DeadValue(MachineRepresentation::kWord32), node); 862 } else if (output_rep == MachineRepresentation::kBit) { 863 CHECK(output_type.Is(Type::Boolean())); 864 if (use_info.truncation().IsUsedAsWord32()) { 865 return node; 866 } else { 867 CHECK(Truncation::Any(kIdentifyZeros) 868 .IsLessGeneralThan(use_info.truncation())); 869 CHECK_NE(use_info.type_check(), TypeCheckKind::kNone); 870 CHECK_NE(use_info.type_check(), TypeCheckKind::kNumberOrOddball); 871 Node* unreachable = 872 InsertUnconditionalDeopt(use_node, DeoptimizeReason::kNotASmi); 873 return jsgraph()->graph()->NewNode( 874 jsgraph()->common()->DeadValue(MachineRepresentation::kWord32), 875 unreachable); 876 } 877 } else if (output_rep == MachineRepresentation::kFloat64) { 878 if (output_type.Is(Type::Signed32())) { 879 op = machine()->ChangeFloat64ToInt32(); 880 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall || 881 use_info.type_check() == TypeCheckKind::kSigned32 || 882 use_info.type_check() == TypeCheckKind::kArrayIndex) { 883 op = simplified()->CheckedFloat64ToInt32( 884 output_type.Maybe(Type::MinusZero()) 885 ? use_info.minus_zero_check() 886 : CheckForMinusZeroMode::kDontCheckForMinusZero, 887 use_info.feedback()); 888 } else if (output_type.Is(Type::Unsigned32())) { 889 op = machine()->ChangeFloat64ToUint32(); 890 } else if (use_info.truncation().IsUsedAsWord32()) { 891 op = machine()->TruncateFloat64ToWord32(); 892 } else { 893 return TypeError(node, output_rep, output_type, 894 MachineRepresentation::kWord32); 895 } 896 } else if (output_rep == MachineRepresentation::kFloat32) { 897 node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32 898 if (output_type.Is(Type::Signed32())) { 899 op = machine()->ChangeFloat64ToInt32(); 900 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall || 901 use_info.type_check() == TypeCheckKind::kSigned32 || 902 use_info.type_check() == TypeCheckKind::kArrayIndex) { 903 op = simplified()->CheckedFloat64ToInt32( 904 output_type.Maybe(Type::MinusZero()) 905 ? use_info.minus_zero_check() 906 : CheckForMinusZeroMode::kDontCheckForMinusZero, 907 use_info.feedback()); 908 } else if (output_type.Is(Type::Unsigned32())) { 909 op = machine()->ChangeFloat64ToUint32(); 910 } else if (use_info.truncation().IsUsedAsWord32()) { 911 op = machine()->TruncateFloat64ToWord32(); 912 } else { 913 return TypeError(node, output_rep, output_type, 914 MachineRepresentation::kWord32); 915 } 916 } else if (IsAnyTagged(output_rep)) { 917 if (output_rep == MachineRepresentation::kTaggedSigned && 918 output_type.Is(Type::SignedSmall())) { 919 op = simplified()->ChangeTaggedSignedToInt32(); 920 } else if (output_type.Is(Type::Signed32())) { 921 op = simplified()->ChangeTaggedToInt32(); 922 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) { 923 op = simplified()->CheckedTaggedSignedToInt32(use_info.feedback()); 924 } else if (use_info.type_check() == TypeCheckKind::kSigned32) { 925 op = simplified()->CheckedTaggedToInt32( 926 output_type.Maybe(Type::MinusZero()) 927 ? use_info.minus_zero_check() 928 : CheckForMinusZeroMode::kDontCheckForMinusZero, 929 use_info.feedback()); 930 } else if (use_info.type_check() == TypeCheckKind::kArrayIndex) { 931 op = simplified()->CheckedTaggedToArrayIndex(use_info.feedback()); 932 } else if (output_type.Is(Type::Unsigned32())) { 933 op = simplified()->ChangeTaggedToUint32(); 934 } else if (use_info.truncation().IsUsedAsWord32()) { 935 if (output_type.Is(Type::NumberOrOddball())) { 936 op = simplified()->TruncateTaggedToWord32(); 937 } else if (use_info.type_check() == TypeCheckKind::kNumber) { 938 op = simplified()->CheckedTruncateTaggedToWord32( 939 CheckTaggedInputMode::kNumber, use_info.feedback()); 940 } else if (use_info.type_check() == TypeCheckKind::kNumberOrOddball) { 941 op = simplified()->CheckedTruncateTaggedToWord32( 942 CheckTaggedInputMode::kNumberOrOddball, use_info.feedback()); 943 } else { 944 return TypeError(node, output_rep, output_type, 945 MachineRepresentation::kWord32); 946 } 947 } else { 948 return TypeError(node, output_rep, output_type, 949 MachineRepresentation::kWord32); 950 } 951 } else if (output_rep == MachineRepresentation::kWord32) { 952 // Only the checked case should get here, the non-checked case is 953 // handled in GetRepresentationFor. 954 if (use_info.type_check() == TypeCheckKind::kSignedSmall || 955 use_info.type_check() == TypeCheckKind::kSigned32 || 956 use_info.type_check() == TypeCheckKind::kArrayIndex) { 957 bool identify_zeros = use_info.truncation().IdentifiesZeroAndMinusZero(); 958 if (output_type.Is(Type::Signed32()) || 959 (identify_zeros && output_type.Is(Type::Signed32OrMinusZero()))) { 960 return node; 961 } else if (output_type.Is(Type::Unsigned32()) || 962 (identify_zeros && 963 output_type.Is(Type::Unsigned32OrMinusZero()))) { 964 op = simplified()->CheckedUint32ToInt32(use_info.feedback()); 965 } else { 966 return TypeError(node, output_rep, output_type, 967 MachineRepresentation::kWord32); 968 } 969 } else if (use_info.type_check() == TypeCheckKind::kNumber || 970 use_info.type_check() == TypeCheckKind::kNumberOrOddball) { 971 return node; 972 } 973 } else if (output_rep == MachineRepresentation::kWord8 || 974 output_rep == MachineRepresentation::kWord16) { 975 DCHECK_EQ(MachineRepresentation::kWord32, use_info.representation()); 976 DCHECK(use_info.type_check() == TypeCheckKind::kSignedSmall || 977 use_info.type_check() == TypeCheckKind::kSigned32); 978 return node; 979 } else if (output_rep == MachineRepresentation::kWord64) { 980 if (output_type.Is(Type::Signed32()) || 981 (output_type.Is(Type::Unsigned32()) && 982 use_info.type_check() == TypeCheckKind::kNone) || 983 (output_type.Is(cache_->kSafeInteger) && 984 use_info.truncation().IsUsedAsWord32())) { 985 op = machine()->TruncateInt64ToInt32(); 986 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall || 987 use_info.type_check() == TypeCheckKind::kSigned32 || 988 use_info.type_check() == TypeCheckKind::kArrayIndex) { 989 if (output_type.Is(cache_->kPositiveSafeInteger)) { 990 op = simplified()->CheckedUint64ToInt32(use_info.feedback()); 991 } else if (output_type.Is(cache_->kSafeInteger)) { 992 op = simplified()->CheckedInt64ToInt32(use_info.feedback()); 993 } else { 994 return TypeError(node, output_rep, output_type, 995 MachineRepresentation::kWord32); 996 } 997 } else { 998 return TypeError(node, output_rep, output_type, 999 MachineRepresentation::kWord32); 1000 } 1001 } 1002 1003 if (op == nullptr) { 1004 return TypeError(node, output_rep, output_type, 1005 MachineRepresentation::kWord32); 1006 } 1007 return InsertConversion(node, op, use_node); 1008} 1009 1010Node* RepresentationChanger::InsertConversion(Node* node, const Operator* op, 1011 Node* use_node) { 1012 if (op->ControlInputCount() > 0) { 1013 // If the operator can deoptimize (which means it has control 1014 // input), we need to connect it to the effect and control chains. 1015 Node* effect = NodeProperties::GetEffectInput(use_node); 1016 Node* control = NodeProperties::GetControlInput(use_node); 1017 Node* conversion = jsgraph()->graph()->NewNode(op, node, effect, control); 1018 NodeProperties::ReplaceEffectInput(use_node, conversion); 1019 return conversion; 1020 } 1021 return jsgraph()->graph()->NewNode(op, node); 1022} 1023 1024Node* RepresentationChanger::GetBitRepresentationFor( 1025 Node* node, MachineRepresentation output_rep, Type output_type) { 1026 // Eagerly fold representation changes for constants. 1027 switch (node->opcode()) { 1028 case IrOpcode::kHeapConstant: { 1029 HeapObjectMatcher m(node); 1030 if (m.Is(factory()->false_value())) { 1031 return jsgraph()->Int32Constant(0); 1032 } else if (m.Is(factory()->true_value())) { 1033 return jsgraph()->Int32Constant(1); 1034 } 1035 break; 1036 } 1037 default: 1038 break; 1039 } 1040 // Select the correct X -> Bit operator. 1041 const Operator* op; 1042 if (output_type.Is(Type::None())) { 1043 // This is an impossible value; it should not be used at runtime. 1044 return jsgraph()->graph()->NewNode( 1045 jsgraph()->common()->DeadValue(MachineRepresentation::kBit), node); 1046 } else if (output_rep == MachineRepresentation::kTagged || 1047 output_rep == MachineRepresentation::kTaggedPointer) { 1048 if (output_type.Is(Type::BooleanOrNullOrUndefined())) { 1049 // true is the only trueish Oddball. 1050 op = simplified()->ChangeTaggedToBit(); 1051 } else { 1052 if (output_rep == MachineRepresentation::kTagged && 1053 output_type.Maybe(Type::SignedSmall())) { 1054 op = simplified()->TruncateTaggedToBit(); 1055 } else { 1056 // The {output_type} either doesn't include the Smi range, 1057 // or the {output_rep} is known to be TaggedPointer. 1058 op = simplified()->TruncateTaggedPointerToBit(); 1059 } 1060 } 1061 } else if (output_rep == MachineRepresentation::kTaggedSigned) { 1062 if (COMPRESS_POINTERS_BOOL) { 1063 node = jsgraph()->graph()->NewNode(machine()->Word32Equal(), node, 1064 jsgraph()->Int32Constant(0)); 1065 } else { 1066 node = jsgraph()->graph()->NewNode(machine()->WordEqual(), node, 1067 jsgraph()->IntPtrConstant(0)); 1068 } 1069 return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node, 1070 jsgraph()->Int32Constant(0)); 1071 } else if (IsWord(output_rep)) { 1072 node = jsgraph()->graph()->NewNode(machine()->Word32Equal(), node, 1073 jsgraph()->Int32Constant(0)); 1074 return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node, 1075 jsgraph()->Int32Constant(0)); 1076 } else if (output_rep == MachineRepresentation::kWord64) { 1077 node = jsgraph()->graph()->NewNode(machine()->Word64Equal(), node, 1078 jsgraph()->Int64Constant(0)); 1079 return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node, 1080 jsgraph()->Int32Constant(0)); 1081 } else if (output_rep == MachineRepresentation::kFloat32) { 1082 node = jsgraph()->graph()->NewNode(machine()->Float32Abs(), node); 1083 return jsgraph()->graph()->NewNode(machine()->Float32LessThan(), 1084 jsgraph()->Float32Constant(0.0), node); 1085 } else if (output_rep == MachineRepresentation::kFloat64) { 1086 node = jsgraph()->graph()->NewNode(machine()->Float64Abs(), node); 1087 return jsgraph()->graph()->NewNode(machine()->Float64LessThan(), 1088 jsgraph()->Float64Constant(0.0), node); 1089 } else { 1090 return TypeError(node, output_rep, output_type, 1091 MachineRepresentation::kBit); 1092 } 1093 return jsgraph()->graph()->NewNode(op, node); 1094} 1095 1096Node* RepresentationChanger::GetWord64RepresentationFor( 1097 Node* node, MachineRepresentation output_rep, Type output_type, 1098 Node* use_node, UseInfo use_info) { 1099 // Eagerly fold representation changes for constants. 1100 switch (node->opcode()) { 1101 case IrOpcode::kInt32Constant: 1102 case IrOpcode::kInt64Constant: 1103 case IrOpcode::kFloat32Constant: 1104 case IrOpcode::kFloat64Constant: 1105 UNREACHABLE(); 1106 case IrOpcode::kNumberConstant: { 1107 if (use_info.type_check() != TypeCheckKind::kBigInt) { 1108 double const fv = OpParameter<double>(node->op()); 1109 if (base::IsValueInRangeForNumericType<int64_t>(fv)) { 1110 int64_t const iv = static_cast<int64_t>(fv); 1111 if (static_cast<double>(iv) == fv) { 1112 return InsertTypeOverrideForVerifier(NodeProperties::GetType(node), 1113 jsgraph()->Int64Constant(iv)); 1114 } 1115 } 1116 } 1117 break; 1118 } 1119 case IrOpcode::kHeapConstant: { 1120 HeapObjectMatcher m(node); 1121 if (m.HasResolvedValue() && m.Ref(broker_).IsBigInt() && 1122 use_info.truncation().IsUsedAsWord64()) { 1123 BigIntRef bigint = m.Ref(broker_).AsBigInt(); 1124 return InsertTypeOverrideForVerifier( 1125 NodeProperties::GetType(node), 1126 jsgraph()->Int64Constant(static_cast<int64_t>(bigint.AsUint64()))); 1127 } 1128 break; 1129 } 1130 default: 1131 break; 1132 } 1133 1134 if (use_info.type_check() == TypeCheckKind::kBigInt) { 1135 // BigInts are only represented as tagged pointer and word64. 1136 if (!CanBeTaggedPointer(output_rep) && 1137 output_rep != MachineRepresentation::kWord64) { 1138 DCHECK(!output_type.Equals(Type::BigInt())); 1139 Node* unreachable = InsertUnconditionalDeopt( 1140 use_node, DeoptimizeReason::kNotABigInt, use_info.feedback()); 1141 return jsgraph()->graph()->NewNode( 1142 jsgraph()->common()->DeadValue(MachineRepresentation::kWord64), 1143 unreachable); 1144 } 1145 } 1146 1147 // Select the correct X -> Word64 operator. 1148 const Operator* op; 1149 if (output_type.Is(Type::None())) { 1150 // This is an impossible value; it should not be used at runtime. 1151 return jsgraph()->graph()->NewNode( 1152 jsgraph()->common()->DeadValue(MachineRepresentation::kWord64), node); 1153 } else if (output_rep == MachineRepresentation::kBit) { 1154 CHECK(output_type.Is(Type::Boolean())); 1155 CHECK_NE(use_info.type_check(), TypeCheckKind::kNone); 1156 CHECK_NE(use_info.type_check(), TypeCheckKind::kNumberOrOddball); 1157 CHECK_NE(use_info.type_check(), TypeCheckKind::kBigInt); 1158 Node* unreachable = 1159 InsertUnconditionalDeopt(use_node, DeoptimizeReason::kNotASmi); 1160 return jsgraph()->graph()->NewNode( 1161 jsgraph()->common()->DeadValue(MachineRepresentation::kWord64), 1162 unreachable); 1163 } else if (IsWord(output_rep)) { 1164 if (output_type.Is(Type::Unsigned32OrMinusZero())) { 1165 // uint32 -> uint64 1166 CHECK_IMPLIES(output_type.Maybe(Type::MinusZero()), 1167 use_info.truncation().IdentifiesZeroAndMinusZero()); 1168 op = machine()->ChangeUint32ToUint64(); 1169 } else if (output_type.Is(Type::Signed32OrMinusZero())) { 1170 // int32 -> int64 1171 CHECK_IMPLIES(output_type.Maybe(Type::MinusZero()), 1172 use_info.truncation().IdentifiesZeroAndMinusZero()); 1173 op = machine()->ChangeInt32ToInt64(); 1174 } else { 1175 return TypeError(node, output_rep, output_type, 1176 MachineRepresentation::kWord64); 1177 } 1178 } else if (output_rep == MachineRepresentation::kFloat32) { 1179 if (output_type.Is(cache_->kDoubleRepresentableInt64)) { 1180 // float32 -> float64 -> int64 1181 node = InsertChangeFloat32ToFloat64(node); 1182 op = machine()->ChangeFloat64ToInt64(); 1183 } else if (output_type.Is(cache_->kDoubleRepresentableUint64)) { 1184 // float32 -> float64 -> uint64 1185 node = InsertChangeFloat32ToFloat64(node); 1186 op = machine()->ChangeFloat64ToUint64(); 1187 } else if (use_info.type_check() == TypeCheckKind::kSigned64 || 1188 use_info.type_check() == TypeCheckKind::kArrayIndex) { 1189 // float32 -> float64 -> int64 1190 node = InsertChangeFloat32ToFloat64(node); 1191 op = simplified()->CheckedFloat64ToInt64( 1192 output_type.Maybe(Type::MinusZero()) 1193 ? use_info.minus_zero_check() 1194 : CheckForMinusZeroMode::kDontCheckForMinusZero, 1195 use_info.feedback()); 1196 } else { 1197 return TypeError(node, output_rep, output_type, 1198 MachineRepresentation::kWord64); 1199 } 1200 } else if (output_rep == MachineRepresentation::kFloat64) { 1201 if (output_type.Is(cache_->kDoubleRepresentableInt64)) { 1202 op = machine()->ChangeFloat64ToInt64(); 1203 } else if (output_type.Is(cache_->kDoubleRepresentableUint64)) { 1204 op = machine()->ChangeFloat64ToUint64(); 1205 } else if (use_info.type_check() == TypeCheckKind::kSigned64 || 1206 use_info.type_check() == TypeCheckKind::kArrayIndex) { 1207 op = simplified()->CheckedFloat64ToInt64( 1208 output_type.Maybe(Type::MinusZero()) 1209 ? use_info.minus_zero_check() 1210 : CheckForMinusZeroMode::kDontCheckForMinusZero, 1211 use_info.feedback()); 1212 } else { 1213 return TypeError(node, output_rep, output_type, 1214 MachineRepresentation::kWord64); 1215 } 1216 } else if (output_rep == MachineRepresentation::kTaggedSigned) { 1217 if (output_type.Is(Type::SignedSmall())) { 1218 op = simplified()->ChangeTaggedSignedToInt64(); 1219 } else { 1220 return TypeError(node, output_rep, output_type, 1221 MachineRepresentation::kWord64); 1222 } 1223 } else if (IsAnyTagged(output_rep) && 1224 use_info.truncation().IsUsedAsWord64() && 1225 (use_info.type_check() == TypeCheckKind::kBigInt || 1226 output_type.Is(Type::BigInt()))) { 1227 node = GetTaggedPointerRepresentationFor(node, output_rep, output_type, 1228 use_node, use_info); 1229 op = simplified()->TruncateBigIntToWord64(); 1230 } else if (CanBeTaggedPointer(output_rep)) { 1231 if (output_type.Is(cache_->kDoubleRepresentableInt64)) { 1232 op = simplified()->ChangeTaggedToInt64(); 1233 } else if (use_info.type_check() == TypeCheckKind::kSigned64) { 1234 op = simplified()->CheckedTaggedToInt64( 1235 output_type.Maybe(Type::MinusZero()) 1236 ? use_info.minus_zero_check() 1237 : CheckForMinusZeroMode::kDontCheckForMinusZero, 1238 use_info.feedback()); 1239 } else if (use_info.type_check() == TypeCheckKind::kArrayIndex) { 1240 op = simplified()->CheckedTaggedToArrayIndex(use_info.feedback()); 1241 } else { 1242 return TypeError(node, output_rep, output_type, 1243 MachineRepresentation::kWord64); 1244 } 1245 } else if (output_rep == MachineRepresentation::kWord64) { 1246 DCHECK_EQ(use_info.type_check(), TypeCheckKind::kBigInt); 1247 if (output_type.Is(Type::BigInt())) { 1248 return node; 1249 } else { 1250 Node* unreachable = InsertUnconditionalDeopt( 1251 use_node, DeoptimizeReason::kNotABigInt, use_info.feedback()); 1252 return jsgraph()->graph()->NewNode( 1253 jsgraph()->common()->DeadValue(MachineRepresentation::kWord64), 1254 unreachable); 1255 } 1256 } else if (output_rep == MachineRepresentation::kSandboxedPointer) { 1257 if (output_type.Is(Type::SandboxedPointer())) { 1258 return node; 1259 } else { 1260 return TypeError(node, output_rep, output_type, 1261 MachineRepresentation::kWord64); 1262 } 1263 } else { 1264 return TypeError(node, output_rep, output_type, 1265 MachineRepresentation::kWord64); 1266 } 1267 return InsertConversion(node, op, use_node); 1268} 1269 1270const Operator* RepresentationChanger::Int32OperatorFor( 1271 IrOpcode::Value opcode) { 1272 switch (opcode) { 1273 case IrOpcode::kSpeculativeNumberAdd: // Fall through. 1274 case IrOpcode::kSpeculativeSafeIntegerAdd: 1275 case IrOpcode::kNumberAdd: 1276 return machine()->Int32Add(); 1277 case IrOpcode::kSpeculativeNumberSubtract: // Fall through. 1278 case IrOpcode::kSpeculativeSafeIntegerSubtract: 1279 case IrOpcode::kNumberSubtract: 1280 return machine()->Int32Sub(); 1281 case IrOpcode::kSpeculativeNumberMultiply: 1282 case IrOpcode::kNumberMultiply: 1283 return machine()->Int32Mul(); 1284 case IrOpcode::kSpeculativeNumberDivide: 1285 case IrOpcode::kNumberDivide: 1286 return machine()->Int32Div(); 1287 case IrOpcode::kSpeculativeNumberModulus: 1288 case IrOpcode::kNumberModulus: 1289 return machine()->Int32Mod(); 1290 case IrOpcode::kSpeculativeNumberBitwiseOr: // Fall through. 1291 case IrOpcode::kNumberBitwiseOr: 1292 return machine()->Word32Or(); 1293 case IrOpcode::kSpeculativeNumberBitwiseXor: // Fall through. 1294 case IrOpcode::kNumberBitwiseXor: 1295 return machine()->Word32Xor(); 1296 case IrOpcode::kSpeculativeNumberBitwiseAnd: // Fall through. 1297 case IrOpcode::kNumberBitwiseAnd: 1298 return machine()->Word32And(); 1299 case IrOpcode::kNumberEqual: 1300 case IrOpcode::kSpeculativeNumberEqual: 1301 return machine()->Word32Equal(); 1302 case IrOpcode::kNumberLessThan: 1303 case IrOpcode::kSpeculativeNumberLessThan: 1304 return machine()->Int32LessThan(); 1305 case IrOpcode::kNumberLessThanOrEqual: 1306 case IrOpcode::kSpeculativeNumberLessThanOrEqual: 1307 return machine()->Int32LessThanOrEqual(); 1308 default: 1309 UNREACHABLE(); 1310 } 1311} 1312 1313const Operator* RepresentationChanger::Int32OverflowOperatorFor( 1314 IrOpcode::Value opcode) { 1315 switch (opcode) { 1316 case IrOpcode::kSpeculativeSafeIntegerAdd: 1317 return simplified()->CheckedInt32Add(); 1318 case IrOpcode::kSpeculativeSafeIntegerSubtract: 1319 return simplified()->CheckedInt32Sub(); 1320 case IrOpcode::kSpeculativeNumberDivide: 1321 return simplified()->CheckedInt32Div(); 1322 case IrOpcode::kSpeculativeNumberModulus: 1323 return simplified()->CheckedInt32Mod(); 1324 default: 1325 UNREACHABLE(); 1326 } 1327} 1328 1329const Operator* RepresentationChanger::Int64OperatorFor( 1330 IrOpcode::Value opcode) { 1331 switch (opcode) { 1332 case IrOpcode::kSpeculativeNumberAdd: // Fall through. 1333 case IrOpcode::kSpeculativeSafeIntegerAdd: 1334 case IrOpcode::kNumberAdd: 1335 return machine()->Int64Add(); 1336 case IrOpcode::kSpeculativeNumberSubtract: // Fall through. 1337 case IrOpcode::kSpeculativeSafeIntegerSubtract: 1338 case IrOpcode::kNumberSubtract: 1339 return machine()->Int64Sub(); 1340 default: 1341 UNREACHABLE(); 1342 } 1343} 1344 1345const Operator* RepresentationChanger::TaggedSignedOperatorFor( 1346 IrOpcode::Value opcode) { 1347 switch (opcode) { 1348 case IrOpcode::kSpeculativeNumberLessThan: 1349 return (COMPRESS_POINTERS_BOOL || machine()->Is32()) 1350 ? machine()->Int32LessThan() 1351 : machine()->Int64LessThan(); 1352 case IrOpcode::kSpeculativeNumberLessThanOrEqual: 1353 return (COMPRESS_POINTERS_BOOL || machine()->Is32()) 1354 ? machine()->Int32LessThanOrEqual() 1355 : machine()->Int64LessThanOrEqual(); 1356 case IrOpcode::kSpeculativeNumberEqual: 1357 return (COMPRESS_POINTERS_BOOL || machine()->Is32()) 1358 ? machine()->Word32Equal() 1359 : machine()->Word64Equal(); 1360 default: 1361 UNREACHABLE(); 1362 } 1363} 1364 1365const Operator* RepresentationChanger::Uint32OperatorFor( 1366 IrOpcode::Value opcode) { 1367 switch (opcode) { 1368 case IrOpcode::kNumberAdd: 1369 return machine()->Int32Add(); 1370 case IrOpcode::kNumberSubtract: 1371 return machine()->Int32Sub(); 1372 case IrOpcode::kSpeculativeNumberMultiply: 1373 case IrOpcode::kNumberMultiply: 1374 return machine()->Int32Mul(); 1375 case IrOpcode::kSpeculativeNumberDivide: 1376 case IrOpcode::kNumberDivide: 1377 return machine()->Uint32Div(); 1378 case IrOpcode::kSpeculativeNumberModulus: 1379 case IrOpcode::kNumberModulus: 1380 return machine()->Uint32Mod(); 1381 case IrOpcode::kNumberEqual: 1382 case IrOpcode::kSpeculativeNumberEqual: 1383 return machine()->Word32Equal(); 1384 case IrOpcode::kNumberLessThan: 1385 case IrOpcode::kSpeculativeNumberLessThan: 1386 return machine()->Uint32LessThan(); 1387 case IrOpcode::kNumberLessThanOrEqual: 1388 case IrOpcode::kSpeculativeNumberLessThanOrEqual: 1389 return machine()->Uint32LessThanOrEqual(); 1390 case IrOpcode::kNumberClz32: 1391 return machine()->Word32Clz(); 1392 case IrOpcode::kNumberImul: 1393 return machine()->Int32Mul(); 1394 default: 1395 UNREACHABLE(); 1396 } 1397} 1398 1399const Operator* RepresentationChanger::Uint32OverflowOperatorFor( 1400 IrOpcode::Value opcode) { 1401 switch (opcode) { 1402 case IrOpcode::kSpeculativeNumberDivide: 1403 return simplified()->CheckedUint32Div(); 1404 case IrOpcode::kSpeculativeNumberModulus: 1405 return simplified()->CheckedUint32Mod(); 1406 default: 1407 UNREACHABLE(); 1408 } 1409} 1410 1411const Operator* RepresentationChanger::Float64OperatorFor( 1412 IrOpcode::Value opcode) { 1413 switch (opcode) { 1414 case IrOpcode::kSpeculativeNumberAdd: 1415 case IrOpcode::kSpeculativeSafeIntegerAdd: 1416 case IrOpcode::kNumberAdd: 1417 return machine()->Float64Add(); 1418 case IrOpcode::kSpeculativeNumberSubtract: 1419 case IrOpcode::kSpeculativeSafeIntegerSubtract: 1420 case IrOpcode::kNumberSubtract: 1421 return machine()->Float64Sub(); 1422 case IrOpcode::kSpeculativeNumberMultiply: 1423 case IrOpcode::kNumberMultiply: 1424 return machine()->Float64Mul(); 1425 case IrOpcode::kSpeculativeNumberDivide: 1426 case IrOpcode::kNumberDivide: 1427 return machine()->Float64Div(); 1428 case IrOpcode::kSpeculativeNumberModulus: 1429 case IrOpcode::kNumberModulus: 1430 return machine()->Float64Mod(); 1431 case IrOpcode::kNumberEqual: 1432 case IrOpcode::kSpeculativeNumberEqual: 1433 return machine()->Float64Equal(); 1434 case IrOpcode::kNumberLessThan: 1435 case IrOpcode::kSpeculativeNumberLessThan: 1436 return machine()->Float64LessThan(); 1437 case IrOpcode::kNumberLessThanOrEqual: 1438 case IrOpcode::kSpeculativeNumberLessThanOrEqual: 1439 return machine()->Float64LessThanOrEqual(); 1440 case IrOpcode::kNumberAbs: 1441 return machine()->Float64Abs(); 1442 case IrOpcode::kNumberAcos: 1443 return machine()->Float64Acos(); 1444 case IrOpcode::kNumberAcosh: 1445 return machine()->Float64Acosh(); 1446 case IrOpcode::kNumberAsin: 1447 return machine()->Float64Asin(); 1448 case IrOpcode::kNumberAsinh: 1449 return machine()->Float64Asinh(); 1450 case IrOpcode::kNumberAtan: 1451 return machine()->Float64Atan(); 1452 case IrOpcode::kNumberAtanh: 1453 return machine()->Float64Atanh(); 1454 case IrOpcode::kNumberAtan2: 1455 return machine()->Float64Atan2(); 1456 case IrOpcode::kNumberCbrt: 1457 return machine()->Float64Cbrt(); 1458 case IrOpcode::kNumberCeil: 1459 return machine()->Float64RoundUp().placeholder(); 1460 case IrOpcode::kNumberCos: 1461 return machine()->Float64Cos(); 1462 case IrOpcode::kNumberCosh: 1463 return machine()->Float64Cosh(); 1464 case IrOpcode::kNumberExp: 1465 return machine()->Float64Exp(); 1466 case IrOpcode::kNumberExpm1: 1467 return machine()->Float64Expm1(); 1468 case IrOpcode::kNumberFloor: 1469 return machine()->Float64RoundDown().placeholder(); 1470 case IrOpcode::kNumberFround: 1471 return machine()->TruncateFloat64ToFloat32(); 1472 case IrOpcode::kNumberLog: 1473 return machine()->Float64Log(); 1474 case IrOpcode::kNumberLog1p: 1475 return machine()->Float64Log1p(); 1476 case IrOpcode::kNumberLog2: 1477 return machine()->Float64Log2(); 1478 case IrOpcode::kNumberLog10: 1479 return machine()->Float64Log10(); 1480 case IrOpcode::kNumberMax: 1481 return machine()->Float64Max(); 1482 case IrOpcode::kNumberMin: 1483 return machine()->Float64Min(); 1484 case IrOpcode::kSpeculativeNumberPow: 1485 case IrOpcode::kNumberPow: 1486 return machine()->Float64Pow(); 1487 case IrOpcode::kNumberSin: 1488 return machine()->Float64Sin(); 1489 case IrOpcode::kNumberSinh: 1490 return machine()->Float64Sinh(); 1491 case IrOpcode::kNumberSqrt: 1492 return machine()->Float64Sqrt(); 1493 case IrOpcode::kNumberTan: 1494 return machine()->Float64Tan(); 1495 case IrOpcode::kNumberTanh: 1496 return machine()->Float64Tanh(); 1497 case IrOpcode::kNumberTrunc: 1498 return machine()->Float64RoundTruncate().placeholder(); 1499 case IrOpcode::kNumberSilenceNaN: 1500 return machine()->Float64SilenceNaN(); 1501 default: 1502 UNREACHABLE(); 1503 } 1504} 1505 1506Node* RepresentationChanger::TypeError(Node* node, 1507 MachineRepresentation output_rep, 1508 Type output_type, 1509 MachineRepresentation use) { 1510 type_error_ = true; 1511 if (!testing_type_errors_) { 1512 std::ostringstream out_str; 1513 out_str << output_rep << " ("; 1514 output_type.PrintTo(out_str); 1515 out_str << ")"; 1516 1517 std::ostringstream use_str; 1518 use_str << use; 1519 1520 FATAL( 1521 "RepresentationChangerError: node #%d:%s of " 1522 "%s cannot be changed to %s", 1523 node->id(), node->op()->mnemonic(), out_str.str().c_str(), 1524 use_str.str().c_str()); 1525 } 1526 return node; 1527} 1528 1529Node* RepresentationChanger::InsertChangeBitToTagged(Node* node) { 1530 return jsgraph()->graph()->NewNode(simplified()->ChangeBitToTagged(), node); 1531} 1532 1533Node* RepresentationChanger::InsertChangeFloat32ToFloat64(Node* node) { 1534 return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node); 1535} 1536 1537Node* RepresentationChanger::InsertChangeFloat64ToUint32(Node* node) { 1538 return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToUint32(), node); 1539} 1540 1541Node* RepresentationChanger::InsertChangeFloat64ToInt32(Node* node) { 1542 return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToInt32(), node); 1543} 1544 1545Node* RepresentationChanger::InsertChangeInt32ToFloat64(Node* node) { 1546 return jsgraph()->graph()->NewNode(machine()->ChangeInt32ToFloat64(), node); 1547} 1548 1549Node* RepresentationChanger::InsertChangeTaggedSignedToInt32(Node* node) { 1550 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), 1551 node); 1552} 1553 1554Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { 1555 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), 1556 node); 1557} 1558 1559Node* RepresentationChanger::InsertChangeUint32ToFloat64(Node* node) { 1560 return jsgraph()->graph()->NewNode(machine()->ChangeUint32ToFloat64(), node); 1561} 1562 1563Node* RepresentationChanger::InsertTruncateInt64ToInt32(Node* node) { 1564 return jsgraph()->graph()->NewNode(machine()->TruncateInt64ToInt32(), node); 1565} 1566 1567Node* RepresentationChanger::InsertCheckedFloat64ToInt32( 1568 Node* node, CheckForMinusZeroMode check, const FeedbackSource& feedback, 1569 Node* use_node) { 1570 return InsertConversion( 1571 node, simplified()->CheckedFloat64ToInt32(check, feedback), use_node); 1572} 1573 1574Node* RepresentationChanger::InsertTypeOverrideForVerifier(const Type& type, 1575 Node* node) { 1576 if (verification_enabled()) { 1577 DCHECK(!type.IsInvalid()); 1578 node = jsgraph()->graph()->NewNode( 1579 jsgraph()->common()->SLVerifierHint(nullptr, type), node); 1580 verifier_->RecordHint(node); 1581 } 1582 return node; 1583} 1584 1585Isolate* RepresentationChanger::isolate() const { return broker_->isolate(); } 1586 1587} // namespace compiler 1588} // namespace internal 1589} // namespace v8 1590