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/code-factory.h" 11 #include "src/compiler/machine-operator.h" 12 #include "src/compiler/node-matchers.h" 13 #include "src/heap/factory-inl.h" 14 15 namespace v8 { 16 namespace internal { 17 namespace compiler { 18 19 const char* Truncation::description() const { 20 switch (kind()) { 21 case TruncationKind::kNone: 22 return "no-value-use"; 23 case TruncationKind::kBool: 24 return "truncate-to-bool"; 25 case TruncationKind::kWord32: 26 return "truncate-to-word32"; 27 case TruncationKind::kWord64: 28 return "truncate-to-word64"; 29 case TruncationKind::kFloat64: 30 switch (identify_zeros()) { 31 case kIdentifyZeros: 32 return "truncate-to-float64 (identify zeros)"; 33 case kDistinguishZeros: 34 return "truncate-to-float64 (distinguish zeros)"; 35 } 36 case TruncationKind::kAny: 37 switch (identify_zeros()) { 38 case kIdentifyZeros: 39 return "no-truncation (but identify zeros)"; 40 case kDistinguishZeros: 41 return "no-truncation (but distinguish zeros)"; 42 } 43 } 44 UNREACHABLE(); 45 } 46 47 48 // Partial order for truncations: 49 // 50 // kWord64 kAny <-------+ 51 // ^ ^ | 52 // \ | | 53 // \ kFloat64 | 54 // \ ^ | 55 // \ / | 56 // kWord32 kBool 57 // ^ ^ 58 // \ / 59 // \ / 60 // \ / 61 // \ / 62 // \ / 63 // kNone 64 // 65 // TODO(jarin) We might consider making kBool < kFloat64. 66 67 // static 68 Truncation::TruncationKind Truncation::Generalize(TruncationKind rep1, 69 TruncationKind rep2) { 70 if (LessGeneral(rep1, rep2)) return rep2; 71 if (LessGeneral(rep2, rep1)) return rep1; 72 // Handle the generalization of float64-representable values. 73 if (LessGeneral(rep1, TruncationKind::kFloat64) && 74 LessGeneral(rep2, TruncationKind::kFloat64)) { 75 return TruncationKind::kFloat64; 76 } 77 // Handle the generalization of any-representable values. 78 if (LessGeneral(rep1, TruncationKind::kAny) && 79 LessGeneral(rep2, TruncationKind::kAny)) { 80 return TruncationKind::kAny; 81 } 82 // All other combinations are illegal. 83 FATAL("Tried to combine incompatible truncations"); 84 return TruncationKind::kNone; 85 } 86 87 // static 88 IdentifyZeros Truncation::GeneralizeIdentifyZeros(IdentifyZeros i1, 89 IdentifyZeros i2) { 90 if (i1 == i2) { 91 return i1; 92 } else { 93 return kDistinguishZeros; 94 } 95 } 96 97 // static 98 bool Truncation::LessGeneral(TruncationKind rep1, TruncationKind rep2) { 99 switch (rep1) { 100 case TruncationKind::kNone: 101 return true; 102 case TruncationKind::kBool: 103 return rep2 == TruncationKind::kBool || rep2 == TruncationKind::kAny; 104 case TruncationKind::kWord32: 105 return rep2 == TruncationKind::kWord32 || 106 rep2 == TruncationKind::kWord64 || 107 rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny; 108 case TruncationKind::kWord64: 109 return rep2 == TruncationKind::kWord64; 110 case TruncationKind::kFloat64: 111 return rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny; 112 case TruncationKind::kAny: 113 return rep2 == TruncationKind::kAny; 114 } 115 UNREACHABLE(); 116 } 117 118 // static 119 bool Truncation::LessGeneralIdentifyZeros(IdentifyZeros i1, IdentifyZeros i2) { 120 return i1 == i2 || i1 == kIdentifyZeros; 121 } 122 123 namespace { 124 125 bool IsWord(MachineRepresentation rep) { 126 return rep == MachineRepresentation::kWord8 || 127 rep == MachineRepresentation::kWord16 || 128 rep == MachineRepresentation::kWord32; 129 } 130 131 } // namespace 132 133 // Changes representation from {output_rep} to {use_rep}. The {truncation} 134 // parameter is only used for sanity checking - if the changer cannot figure 135 // out signedness for the word32->float64 conversion, then we check that the 136 // uses truncate to word32 (so they do not care about signedness). 137 Node* RepresentationChanger::GetRepresentationFor( 138 Node* node, MachineRepresentation output_rep, Type output_type, 139 Node* use_node, UseInfo use_info) { 140 if (output_rep == MachineRepresentation::kNone && !output_type.IsNone()) { 141 // The output representation should be set if the type is inhabited (i.e., 142 // if the value is possible). 143 return TypeError(node, output_rep, output_type, use_info.representation()); 144 } 145 146 // Handle the no-op shortcuts when no checking is necessary. 147 if (use_info.type_check() == TypeCheckKind::kNone || 148 output_rep != MachineRepresentation::kWord32) { 149 if (use_info.representation() == output_rep) { 150 // Representations are the same. That's a no-op. 151 return node; 152 } 153 if (IsWord(use_info.representation()) && IsWord(output_rep)) { 154 // Both are words less than or equal to 32-bits. 155 // Since loads of integers from memory implicitly sign or zero extend the 156 // value to the full machine word size and stores implicitly truncate, 157 // no representation change is necessary. 158 return node; 159 } 160 } 161 162 switch (use_info.representation()) { 163 case MachineRepresentation::kTaggedSigned: 164 DCHECK(use_info.type_check() == TypeCheckKind::kNone || 165 use_info.type_check() == TypeCheckKind::kSignedSmall); 166 return GetTaggedSignedRepresentationFor(node, output_rep, output_type, 167 use_node, use_info); 168 case MachineRepresentation::kTaggedPointer: 169 DCHECK(use_info.type_check() == TypeCheckKind::kNone || 170 use_info.type_check() == TypeCheckKind::kHeapObject); 171 return GetTaggedPointerRepresentationFor(node, output_rep, output_type, 172 use_node, use_info); 173 case MachineRepresentation::kTagged: 174 DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check()); 175 return GetTaggedRepresentationFor(node, output_rep, output_type, 176 use_info.truncation()); 177 case MachineRepresentation::kFloat32: 178 DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check()); 179 return GetFloat32RepresentationFor(node, output_rep, output_type, 180 use_info.truncation()); 181 case MachineRepresentation::kFloat64: 182 return GetFloat64RepresentationFor(node, output_rep, output_type, 183 use_node, use_info); 184 case MachineRepresentation::kBit: 185 DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check()); 186 return GetBitRepresentationFor(node, output_rep, output_type); 187 case MachineRepresentation::kWord8: 188 case MachineRepresentation::kWord16: 189 case MachineRepresentation::kWord32: 190 return GetWord32RepresentationFor(node, output_rep, output_type, use_node, 191 use_info); 192 case MachineRepresentation::kWord64: 193 DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check()); 194 return GetWord64RepresentationFor(node, output_rep, output_type); 195 case MachineRepresentation::kSimd128: 196 case MachineRepresentation::kNone: 197 return node; 198 } 199 UNREACHABLE(); 200 } 201 202 Node* RepresentationChanger::GetTaggedSignedRepresentationFor( 203 Node* node, MachineRepresentation output_rep, Type output_type, 204 Node* use_node, UseInfo use_info) { 205 // Eagerly fold representation changes for constants. 206 switch (node->opcode()) { 207 case IrOpcode::kNumberConstant: 208 if (output_type.Is(Type::SignedSmall())) { 209 return node; 210 } 211 break; 212 default: 213 break; 214 } 215 // Select the correct X -> Tagged operator. 216 const Operator* op; 217 if (output_type.Is(Type::None())) { 218 // This is an impossible value; it should not be used at runtime. 219 return jsgraph()->graph()->NewNode( 220 jsgraph()->common()->DeadValue(MachineRepresentation::kTaggedSigned), 221 node); 222 } else if (IsWord(output_rep)) { 223 if (output_type.Is(Type::Signed31())) { 224 op = simplified()->ChangeInt31ToTaggedSigned(); 225 } else if (output_type.Is(Type::Signed32())) { 226 if (SmiValuesAre32Bits()) { 227 op = simplified()->ChangeInt32ToTagged(); 228 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) { 229 op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback()); 230 } else { 231 return TypeError(node, output_rep, output_type, 232 MachineRepresentation::kTaggedSigned); 233 } 234 } else if (output_type.Is(Type::Unsigned32()) && 235 use_info.type_check() == TypeCheckKind::kSignedSmall) { 236 op = simplified()->CheckedUint32ToTaggedSigned(use_info.feedback()); 237 } else { 238 return TypeError(node, output_rep, output_type, 239 MachineRepresentation::kTaggedSigned); 240 } 241 } else if (output_rep == MachineRepresentation::kFloat64) { 242 if (output_type.Is(Type::Signed31())) { 243 // float64 -> int32 -> tagged signed 244 node = InsertChangeFloat64ToInt32(node); 245 op = simplified()->ChangeInt31ToTaggedSigned(); 246 } else if (output_type.Is(Type::Signed32())) { 247 // float64 -> int32 -> tagged signed 248 node = InsertChangeFloat64ToInt32(node); 249 if (SmiValuesAre32Bits()) { 250 op = simplified()->ChangeInt32ToTagged(); 251 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) { 252 op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback()); 253 } else { 254 return TypeError(node, output_rep, output_type, 255 MachineRepresentation::kTaggedSigned); 256 } 257 } else if (output_type.Is(Type::Unsigned32()) && 258 use_info.type_check() == TypeCheckKind::kSignedSmall) { 259 // float64 -> uint32 -> tagged signed 260 node = InsertChangeFloat64ToUint32(node); 261 op = simplified()->CheckedUint32ToTaggedSigned(use_info.feedback()); 262 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) { 263 op = simplified()->CheckedFloat64ToInt32( 264 output_type.Maybe(Type::MinusZero()) 265 ? CheckForMinusZeroMode::kCheckForMinusZero 266 : CheckForMinusZeroMode::kDontCheckForMinusZero, 267 use_info.feedback()); 268 node = InsertConversion(node, op, use_node); 269 if (SmiValuesAre32Bits()) { 270 op = simplified()->ChangeInt32ToTagged(); 271 } else { 272 op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback()); 273 } 274 } else { 275 return TypeError(node, output_rep, output_type, 276 MachineRepresentation::kTaggedSigned); 277 } 278 } else if (output_rep == MachineRepresentation::kFloat32) { 279 if (use_info.type_check() == TypeCheckKind::kSignedSmall) { 280 op = machine()->ChangeFloat32ToFloat64(); 281 node = InsertConversion(node, op, use_node); 282 op = simplified()->CheckedFloat64ToInt32( 283 output_type.Maybe(Type::MinusZero()) 284 ? CheckForMinusZeroMode::kCheckForMinusZero 285 : CheckForMinusZeroMode::kDontCheckForMinusZero, 286 use_info.feedback()); 287 node = InsertConversion(node, op, use_node); 288 if (SmiValuesAre32Bits()) { 289 op = simplified()->ChangeInt32ToTagged(); 290 } else { 291 op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback()); 292 } 293 } else { 294 return TypeError(node, output_rep, output_type, 295 MachineRepresentation::kTaggedSigned); 296 } 297 } else if (CanBeTaggedPointer(output_rep)) { 298 if (use_info.type_check() == TypeCheckKind::kSignedSmall) { 299 op = simplified()->CheckedTaggedToTaggedSigned(use_info.feedback()); 300 } else if (output_type.Is(Type::SignedSmall())) { 301 op = simplified()->ChangeTaggedToTaggedSigned(); 302 } else { 303 return TypeError(node, output_rep, output_type, 304 MachineRepresentation::kTaggedSigned); 305 } 306 } else if (output_rep == MachineRepresentation::kBit) { 307 if (use_info.type_check() == TypeCheckKind::kSignedSmall) { 308 // TODO(turbofan): Consider adding a Bailout operator that just deopts. 309 // Also use that for MachineRepresentation::kPointer case above. 310 node = InsertChangeBitToTagged(node); 311 op = simplified()->CheckedTaggedToTaggedSigned(use_info.feedback()); 312 } else { 313 return TypeError(node, output_rep, output_type, 314 MachineRepresentation::kTaggedSigned); 315 } 316 } else { 317 return TypeError(node, output_rep, output_type, 318 MachineRepresentation::kTaggedSigned); 319 } 320 return InsertConversion(node, op, use_node); 321 } 322 323 Node* RepresentationChanger::GetTaggedPointerRepresentationFor( 324 Node* node, MachineRepresentation output_rep, Type output_type, 325 Node* use_node, UseInfo use_info) { 326 // Eagerly fold representation changes for constants. 327 switch (node->opcode()) { 328 case IrOpcode::kHeapConstant: 329 return node; // No change necessary. 330 case IrOpcode::kInt32Constant: 331 case IrOpcode::kFloat64Constant: 332 case IrOpcode::kFloat32Constant: 333 UNREACHABLE(); 334 default: 335 break; 336 } 337 // Select the correct X -> TaggedPointer operator. 338 Operator const* op; 339 if (output_type.Is(Type::None())) { 340 // This is an impossible value; it should not be used at runtime. 341 return jsgraph()->graph()->NewNode( 342 jsgraph()->common()->DeadValue(MachineRepresentation::kTaggedPointer), 343 node); 344 } else if (output_rep == MachineRepresentation::kBit) { 345 if (output_type.Is(Type::Boolean())) { 346 op = simplified()->ChangeBitToTagged(); 347 } else { 348 return TypeError(node, output_rep, output_type, 349 MachineRepresentation::kTagged); 350 } 351 } else if (IsWord(output_rep)) { 352 if (output_type.Is(Type::Unsigned32())) { 353 // uint32 -> float64 -> tagged 354 node = InsertChangeUint32ToFloat64(node); 355 } else if (output_type.Is(Type::Signed32())) { 356 // int32 -> float64 -> tagged 357 node = InsertChangeInt32ToFloat64(node); 358 } else { 359 return TypeError(node, output_rep, output_type, 360 MachineRepresentation::kTaggedPointer); 361 } 362 op = simplified()->ChangeFloat64ToTaggedPointer(); 363 } else if (output_rep == MachineRepresentation::kFloat32) { 364 if (output_type.Is(Type::Number())) { 365 // float32 -> float64 -> tagged 366 node = InsertChangeFloat32ToFloat64(node); 367 op = simplified()->ChangeFloat64ToTaggedPointer(); 368 } else { 369 return TypeError(node, output_rep, output_type, 370 MachineRepresentation::kTaggedPointer); 371 } 372 } else if (output_rep == MachineRepresentation::kFloat64) { 373 if (output_type.Is(Type::Number())) { 374 // float64 -> tagged 375 op = simplified()->ChangeFloat64ToTaggedPointer(); 376 } else { 377 return TypeError(node, output_rep, output_type, 378 MachineRepresentation::kTaggedPointer); 379 } 380 } else if (CanBeTaggedSigned(output_rep) && 381 use_info.type_check() == TypeCheckKind::kHeapObject) { 382 if (!output_type.Maybe(Type::SignedSmall())) { 383 return node; 384 } 385 // TODO(turbofan): Consider adding a Bailout operator that just deopts 386 // for TaggedSigned output representation. 387 op = simplified()->CheckedTaggedToTaggedPointer(use_info.feedback()); 388 } else { 389 return TypeError(node, output_rep, output_type, 390 MachineRepresentation::kTaggedPointer); 391 } 392 return InsertConversion(node, op, use_node); 393 } 394 395 Node* RepresentationChanger::GetTaggedRepresentationFor( 396 Node* node, MachineRepresentation output_rep, Type output_type, 397 Truncation truncation) { 398 // Eagerly fold representation changes for constants. 399 switch (node->opcode()) { 400 case IrOpcode::kNumberConstant: 401 case IrOpcode::kHeapConstant: 402 return node; // No change necessary. 403 case IrOpcode::kInt32Constant: 404 case IrOpcode::kFloat64Constant: 405 case IrOpcode::kFloat32Constant: 406 UNREACHABLE(); 407 break; 408 default: 409 break; 410 } 411 if (output_rep == MachineRepresentation::kTaggedSigned || 412 output_rep == MachineRepresentation::kTaggedPointer) { 413 // this is a no-op. 414 return node; 415 } 416 // Select the correct X -> Tagged operator. 417 const Operator* op; 418 if (output_type.Is(Type::None())) { 419 // This is an impossible value; it should not be used at runtime. 420 return jsgraph()->graph()->NewNode( 421 jsgraph()->common()->DeadValue(MachineRepresentation::kTagged), node); 422 } else if (output_rep == MachineRepresentation::kBit) { 423 if (output_type.Is(Type::Boolean())) { 424 op = simplified()->ChangeBitToTagged(); 425 } else { 426 return TypeError(node, output_rep, output_type, 427 MachineRepresentation::kTagged); 428 } 429 } else if (IsWord(output_rep)) { 430 if (output_type.Is(Type::Signed31())) { 431 op = simplified()->ChangeInt31ToTaggedSigned(); 432 } else if (output_type.Is(Type::Signed32())) { 433 op = simplified()->ChangeInt32ToTagged(); 434 } else if (output_type.Is(Type::Unsigned32()) || 435 truncation.IsUsedAsWord32()) { 436 // Either the output is uint32 or the uses only care about the 437 // low 32 bits (so we can pick uint32 safely). 438 op = simplified()->ChangeUint32ToTagged(); 439 } else { 440 return TypeError(node, output_rep, output_type, 441 MachineRepresentation::kTagged); 442 } 443 } else if (output_rep == 444 MachineRepresentation::kFloat32) { // float32 -> float64 -> tagged 445 node = InsertChangeFloat32ToFloat64(node); 446 op = simplified()->ChangeFloat64ToTagged( 447 output_type.Maybe(Type::MinusZero()) 448 ? CheckForMinusZeroMode::kCheckForMinusZero 449 : CheckForMinusZeroMode::kDontCheckForMinusZero); 450 } else if (output_rep == MachineRepresentation::kFloat64) { 451 if (output_type.Is(Type::Signed31())) { // float64 -> int32 -> tagged 452 node = InsertChangeFloat64ToInt32(node); 453 op = simplified()->ChangeInt31ToTaggedSigned(); 454 } else if (output_type.Is( 455 Type::Signed32())) { // float64 -> int32 -> tagged 456 node = InsertChangeFloat64ToInt32(node); 457 op = simplified()->ChangeInt32ToTagged(); 458 } else if (output_type.Is( 459 Type::Unsigned32())) { // float64 -> uint32 -> tagged 460 node = InsertChangeFloat64ToUint32(node); 461 op = simplified()->ChangeUint32ToTagged(); 462 } else if (output_type.Is(Type::Number())) { 463 op = simplified()->ChangeFloat64ToTagged( 464 output_type.Maybe(Type::MinusZero()) 465 ? CheckForMinusZeroMode::kCheckForMinusZero 466 : CheckForMinusZeroMode::kDontCheckForMinusZero); 467 } else { 468 return TypeError(node, output_rep, output_type, 469 MachineRepresentation::kTagged); 470 } 471 } else { 472 return TypeError(node, output_rep, output_type, 473 MachineRepresentation::kTagged); 474 } 475 return jsgraph()->graph()->NewNode(op, node); 476 } 477 478 Node* RepresentationChanger::GetFloat32RepresentationFor( 479 Node* node, MachineRepresentation output_rep, Type output_type, 480 Truncation truncation) { 481 // Eagerly fold representation changes for constants. 482 switch (node->opcode()) { 483 case IrOpcode::kNumberConstant: 484 return jsgraph()->Float32Constant( 485 DoubleToFloat32(OpParameter<double>(node->op()))); 486 case IrOpcode::kInt32Constant: 487 case IrOpcode::kFloat64Constant: 488 case IrOpcode::kFloat32Constant: 489 UNREACHABLE(); 490 break; 491 default: 492 break; 493 } 494 // Select the correct X -> Float32 operator. 495 const Operator* op = nullptr; 496 if (output_type.Is(Type::None())) { 497 // This is an impossible value; it should not be used at runtime. 498 return jsgraph()->graph()->NewNode( 499 jsgraph()->common()->DeadValue(MachineRepresentation::kFloat32), node); 500 } else if (IsWord(output_rep)) { 501 if (output_type.Is(Type::Signed32())) { 502 // int32 -> float64 -> float32 503 op = machine()->ChangeInt32ToFloat64(); 504 node = jsgraph()->graph()->NewNode(op, node); 505 op = machine()->TruncateFloat64ToFloat32(); 506 } else if (output_type.Is(Type::Unsigned32()) || 507 truncation.IsUsedAsWord32()) { 508 // Either the output is uint32 or the uses only care about the 509 // low 32 bits (so we can pick uint32 safely). 510 511 // uint32 -> float64 -> float32 512 op = machine()->ChangeUint32ToFloat64(); 513 node = jsgraph()->graph()->NewNode(op, node); 514 op = machine()->TruncateFloat64ToFloat32(); 515 } 516 } else if (IsAnyTagged(output_rep)) { 517 if (output_type.Is(Type::NumberOrOddball())) { 518 // tagged -> float64 -> float32 519 if (output_type.Is(Type::Number())) { 520 op = simplified()->ChangeTaggedToFloat64(); 521 } else { 522 op = simplified()->TruncateTaggedToFloat64(); 523 } 524 node = jsgraph()->graph()->NewNode(op, node); 525 op = machine()->TruncateFloat64ToFloat32(); 526 } 527 } else if (output_rep == MachineRepresentation::kFloat64) { 528 op = machine()->TruncateFloat64ToFloat32(); 529 } 530 if (op == nullptr) { 531 return TypeError(node, output_rep, output_type, 532 MachineRepresentation::kFloat32); 533 } 534 return jsgraph()->graph()->NewNode(op, node); 535 } 536 537 Node* RepresentationChanger::GetFloat64RepresentationFor( 538 Node* node, MachineRepresentation output_rep, Type output_type, 539 Node* use_node, UseInfo use_info) { 540 // Eagerly fold representation changes for constants. 541 if ((use_info.type_check() == TypeCheckKind::kNone)) { 542 // TODO(jarin) Handle checked constant conversions. 543 switch (node->opcode()) { 544 case IrOpcode::kNumberConstant: 545 return jsgraph()->Float64Constant(OpParameter<double>(node->op())); 546 case IrOpcode::kInt32Constant: 547 case IrOpcode::kFloat64Constant: 548 case IrOpcode::kFloat32Constant: 549 UNREACHABLE(); 550 break; 551 default: 552 break; 553 } 554 } 555 // Select the correct X -> Float64 operator. 556 const Operator* op = nullptr; 557 if (output_type.Is(Type::None())) { 558 // This is an impossible value; it should not be used at runtime. 559 return jsgraph()->graph()->NewNode( 560 jsgraph()->common()->DeadValue(MachineRepresentation::kFloat64), node); 561 } else if (IsWord(output_rep)) { 562 if (output_type.Is(Type::Signed32())) { 563 op = machine()->ChangeInt32ToFloat64(); 564 } else if (output_type.Is(Type::Unsigned32()) || 565 use_info.truncation().IsUsedAsWord32()) { 566 // Either the output is uint32 or the uses only care about the 567 // low 32 bits (so we can pick uint32 safely). 568 op = machine()->ChangeUint32ToFloat64(); 569 } 570 } else if (output_rep == MachineRepresentation::kBit) { 571 op = machine()->ChangeUint32ToFloat64(); 572 } else if (output_rep == MachineRepresentation::kTagged || 573 output_rep == MachineRepresentation::kTaggedSigned || 574 output_rep == MachineRepresentation::kTaggedPointer) { 575 if (output_type.Is(Type::Undefined())) { 576 return jsgraph()->Float64Constant( 577 std::numeric_limits<double>::quiet_NaN()); 578 579 } else if (output_rep == MachineRepresentation::kTaggedSigned) { 580 node = InsertChangeTaggedSignedToInt32(node); 581 op = machine()->ChangeInt32ToFloat64(); 582 } else if (output_type.Is(Type::Number())) { 583 op = simplified()->ChangeTaggedToFloat64(); 584 } else if (output_type.Is(Type::NumberOrOddball())) { 585 // TODO(jarin) Here we should check that truncation is Number. 586 op = simplified()->TruncateTaggedToFloat64(); 587 } else if (use_info.type_check() == TypeCheckKind::kNumber || 588 (use_info.type_check() == TypeCheckKind::kNumberOrOddball && 589 !output_type.Maybe(Type::BooleanOrNullOrNumber()))) { 590 op = simplified()->CheckedTaggedToFloat64(CheckTaggedInputMode::kNumber, 591 use_info.feedback()); 592 } else if (use_info.type_check() == TypeCheckKind::kNumberOrOddball) { 593 op = simplified()->CheckedTaggedToFloat64( 594 CheckTaggedInputMode::kNumberOrOddball, use_info.feedback()); 595 } 596 } else if (output_rep == MachineRepresentation::kFloat32) { 597 op = machine()->ChangeFloat32ToFloat64(); 598 } 599 if (op == nullptr) { 600 return TypeError(node, output_rep, output_type, 601 MachineRepresentation::kFloat64); 602 } 603 return InsertConversion(node, op, use_node); 604 } 605 606 Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) { 607 return jsgraph()->Int32Constant(DoubleToInt32(value)); 608 } 609 610 void RepresentationChanger::InsertUnconditionalDeopt(Node* node, 611 DeoptimizeReason reason) { 612 Node* effect = NodeProperties::GetEffectInput(node); 613 Node* control = NodeProperties::GetControlInput(node); 614 Node* deopt = 615 jsgraph()->graph()->NewNode(simplified()->CheckIf(reason), 616 jsgraph()->Int32Constant(0), effect, control); 617 NodeProperties::ReplaceEffectInput(node, deopt); 618 } 619 620 Node* RepresentationChanger::GetWord32RepresentationFor( 621 Node* node, MachineRepresentation output_rep, Type output_type, 622 Node* use_node, UseInfo use_info) { 623 // Eagerly fold representation changes for constants. 624 switch (node->opcode()) { 625 case IrOpcode::kInt32Constant: 626 case IrOpcode::kFloat32Constant: 627 case IrOpcode::kFloat64Constant: 628 UNREACHABLE(); 629 break; 630 case IrOpcode::kNumberConstant: { 631 double const fv = OpParameter<double>(node->op()); 632 if (use_info.type_check() == TypeCheckKind::kNone || 633 ((use_info.type_check() == TypeCheckKind::kSignedSmall || 634 use_info.type_check() == TypeCheckKind::kSigned32) && 635 IsInt32Double(fv))) { 636 return MakeTruncatedInt32Constant(fv); 637 } 638 break; 639 } 640 default: 641 break; 642 } 643 644 // Select the correct X -> Word32 operator. 645 const Operator* op = nullptr; 646 if (output_type.Is(Type::None())) { 647 // This is an impossible value; it should not be used at runtime. 648 return jsgraph()->graph()->NewNode( 649 jsgraph()->common()->DeadValue(MachineRepresentation::kWord32), node); 650 } else if (output_rep == MachineRepresentation::kBit) { 651 CHECK(output_type.Is(Type::Boolean())); 652 if (use_info.truncation().IsUsedAsWord32()) { 653 return node; 654 } else { 655 CHECK(Truncation::Any(kIdentifyZeros) 656 .IsLessGeneralThan(use_info.truncation())); 657 CHECK_NE(use_info.type_check(), TypeCheckKind::kNone); 658 InsertUnconditionalDeopt(use_node, DeoptimizeReason::kNotASmi); 659 return jsgraph()->graph()->NewNode( 660 jsgraph()->common()->DeadValue(MachineRepresentation::kWord32), node); 661 } 662 } else if (output_rep == MachineRepresentation::kFloat64) { 663 if (output_type.Is(Type::Signed32())) { 664 op = machine()->ChangeFloat64ToInt32(); 665 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall || 666 use_info.type_check() == TypeCheckKind::kSigned32) { 667 op = simplified()->CheckedFloat64ToInt32( 668 output_type.Maybe(Type::MinusZero()) 669 ? use_info.minus_zero_check() 670 : CheckForMinusZeroMode::kDontCheckForMinusZero, 671 use_info.feedback()); 672 } else if (output_type.Is(Type::Unsigned32())) { 673 op = machine()->ChangeFloat64ToUint32(); 674 } else if (use_info.truncation().IsUsedAsWord32()) { 675 op = machine()->TruncateFloat64ToWord32(); 676 } else { 677 return TypeError(node, output_rep, output_type, 678 MachineRepresentation::kWord32); 679 } 680 } else if (output_rep == MachineRepresentation::kFloat32) { 681 node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32 682 if (output_type.Is(Type::Signed32())) { 683 op = machine()->ChangeFloat64ToInt32(); 684 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall || 685 use_info.type_check() == TypeCheckKind::kSigned32) { 686 op = simplified()->CheckedFloat64ToInt32( 687 output_type.Maybe(Type::MinusZero()) 688 ? use_info.minus_zero_check() 689 : CheckForMinusZeroMode::kDontCheckForMinusZero, 690 use_info.feedback()); 691 } else if (output_type.Is(Type::Unsigned32())) { 692 op = machine()->ChangeFloat64ToUint32(); 693 } else if (use_info.truncation().IsUsedAsWord32()) { 694 op = machine()->TruncateFloat64ToWord32(); 695 } else { 696 return TypeError(node, output_rep, output_type, 697 MachineRepresentation::kWord32); 698 } 699 } else if (IsAnyTagged(output_rep)) { 700 if (output_rep == MachineRepresentation::kTaggedSigned && 701 output_type.Is(Type::SignedSmall())) { 702 op = simplified()->ChangeTaggedSignedToInt32(); 703 } else if (output_type.Is(Type::Signed32())) { 704 op = simplified()->ChangeTaggedToInt32(); 705 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) { 706 op = simplified()->CheckedTaggedSignedToInt32(use_info.feedback()); 707 } else if (use_info.type_check() == TypeCheckKind::kSigned32) { 708 op = simplified()->CheckedTaggedToInt32( 709 output_type.Maybe(Type::MinusZero()) 710 ? use_info.minus_zero_check() 711 : CheckForMinusZeroMode::kDontCheckForMinusZero, 712 use_info.feedback()); 713 } else if (output_type.Is(Type::Unsigned32())) { 714 op = simplified()->ChangeTaggedToUint32(); 715 } else if (use_info.truncation().IsUsedAsWord32()) { 716 if (output_type.Is(Type::NumberOrOddball())) { 717 op = simplified()->TruncateTaggedToWord32(); 718 } else if (use_info.type_check() == TypeCheckKind::kNumber) { 719 op = simplified()->CheckedTruncateTaggedToWord32( 720 CheckTaggedInputMode::kNumber, use_info.feedback()); 721 } else if (use_info.type_check() == TypeCheckKind::kNumberOrOddball) { 722 op = simplified()->CheckedTruncateTaggedToWord32( 723 CheckTaggedInputMode::kNumberOrOddball, use_info.feedback()); 724 } else { 725 return TypeError(node, output_rep, output_type, 726 MachineRepresentation::kWord32); 727 } 728 } else { 729 return TypeError(node, output_rep, output_type, 730 MachineRepresentation::kWord32); 731 } 732 } else if (output_rep == MachineRepresentation::kWord32) { 733 // Only the checked case should get here, the non-checked case is 734 // handled in GetRepresentationFor. 735 if (use_info.type_check() == TypeCheckKind::kSignedSmall || 736 use_info.type_check() == TypeCheckKind::kSigned32) { 737 if (output_type.Is(Type::Signed32())) { 738 return node; 739 } else if (output_type.Is(Type::Unsigned32())) { 740 op = simplified()->CheckedUint32ToInt32(use_info.feedback()); 741 } else { 742 return TypeError(node, output_rep, output_type, 743 MachineRepresentation::kWord32); 744 } 745 } else if (use_info.type_check() == TypeCheckKind::kNumber || 746 use_info.type_check() == TypeCheckKind::kNumberOrOddball) { 747 return node; 748 } 749 } else if (output_rep == MachineRepresentation::kWord8 || 750 output_rep == MachineRepresentation::kWord16) { 751 DCHECK_EQ(MachineRepresentation::kWord32, use_info.representation()); 752 DCHECK(use_info.type_check() == TypeCheckKind::kSignedSmall || 753 use_info.type_check() == TypeCheckKind::kSigned32); 754 return node; 755 } 756 757 if (op == nullptr) { 758 return TypeError(node, output_rep, output_type, 759 MachineRepresentation::kWord32); 760 } 761 return InsertConversion(node, op, use_node); 762 } 763 764 Node* RepresentationChanger::InsertConversion(Node* node, const Operator* op, 765 Node* use_node) { 766 if (op->ControlInputCount() > 0) { 767 // If the operator can deoptimize (which means it has control 768 // input), we need to connect it to the effect and control chains. 769 Node* effect = NodeProperties::GetEffectInput(use_node); 770 Node* control = NodeProperties::GetControlInput(use_node); 771 Node* conversion = jsgraph()->graph()->NewNode(op, node, effect, control); 772 NodeProperties::ReplaceEffectInput(use_node, conversion); 773 return conversion; 774 } 775 return jsgraph()->graph()->NewNode(op, node); 776 } 777 778 Node* RepresentationChanger::GetBitRepresentationFor( 779 Node* node, MachineRepresentation output_rep, Type output_type) { 780 // Eagerly fold representation changes for constants. 781 switch (node->opcode()) { 782 case IrOpcode::kHeapConstant: { 783 HeapObjectMatcher m(node); 784 if (m.Is(factory()->false_value())) { 785 return jsgraph()->Int32Constant(0); 786 } else if (m.Is(factory()->true_value())) { 787 return jsgraph()->Int32Constant(1); 788 } 789 break; 790 } 791 default: 792 break; 793 } 794 // Select the correct X -> Bit operator. 795 const Operator* op; 796 if (output_type.Is(Type::None())) { 797 // This is an impossible value; it should not be used at runtime. 798 return jsgraph()->graph()->NewNode( 799 jsgraph()->common()->DeadValue(MachineRepresentation::kBit), node); 800 } else if (output_rep == MachineRepresentation::kTagged || 801 output_rep == MachineRepresentation::kTaggedPointer) { 802 if (output_type.Is(Type::BooleanOrNullOrUndefined())) { 803 // true is the only trueish Oddball. 804 op = simplified()->ChangeTaggedToBit(); 805 } else { 806 if (output_rep == MachineRepresentation::kTagged && 807 output_type.Maybe(Type::SignedSmall())) { 808 op = simplified()->TruncateTaggedToBit(); 809 } else { 810 // The {output_type} either doesn't include the Smi range, 811 // or the {output_rep} is known to be TaggedPointer. 812 op = simplified()->TruncateTaggedPointerToBit(); 813 } 814 } 815 } else if (output_rep == MachineRepresentation::kTaggedSigned) { 816 node = jsgraph()->graph()->NewNode(machine()->WordEqual(), node, 817 jsgraph()->IntPtrConstant(0)); 818 return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node, 819 jsgraph()->Int32Constant(0)); 820 } else if (IsWord(output_rep)) { 821 node = jsgraph()->graph()->NewNode(machine()->Word32Equal(), node, 822 jsgraph()->Int32Constant(0)); 823 return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node, 824 jsgraph()->Int32Constant(0)); 825 } else if (output_rep == MachineRepresentation::kFloat32) { 826 node = jsgraph()->graph()->NewNode(machine()->Float32Abs(), node); 827 return jsgraph()->graph()->NewNode(machine()->Float32LessThan(), 828 jsgraph()->Float32Constant(0.0), node); 829 } else if (output_rep == MachineRepresentation::kFloat64) { 830 node = jsgraph()->graph()->NewNode(machine()->Float64Abs(), node); 831 return jsgraph()->graph()->NewNode(machine()->Float64LessThan(), 832 jsgraph()->Float64Constant(0.0), node); 833 } else { 834 return TypeError(node, output_rep, output_type, 835 MachineRepresentation::kBit); 836 } 837 return jsgraph()->graph()->NewNode(op, node); 838 } 839 840 Node* RepresentationChanger::GetWord64RepresentationFor( 841 Node* node, MachineRepresentation output_rep, Type output_type) { 842 if (output_type.Is(Type::None())) { 843 // This is an impossible value; it should not be used at runtime. 844 return jsgraph()->graph()->NewNode( 845 jsgraph()->common()->DeadValue(MachineRepresentation::kWord32), node); 846 } else if (output_rep == MachineRepresentation::kBit) { 847 return node; // Sloppy comparison -> word64 848 } 849 // Can't really convert Word64 to anything else. Purported to be internal. 850 return TypeError(node, output_rep, output_type, 851 MachineRepresentation::kWord64); 852 } 853 854 const Operator* RepresentationChanger::Int32OperatorFor( 855 IrOpcode::Value opcode) { 856 switch (opcode) { 857 case IrOpcode::kSpeculativeNumberAdd: // Fall through. 858 case IrOpcode::kSpeculativeSafeIntegerAdd: 859 case IrOpcode::kNumberAdd: 860 return machine()->Int32Add(); 861 case IrOpcode::kSpeculativeNumberSubtract: // Fall through. 862 case IrOpcode::kSpeculativeSafeIntegerSubtract: 863 case IrOpcode::kNumberSubtract: 864 return machine()->Int32Sub(); 865 case IrOpcode::kSpeculativeNumberMultiply: 866 case IrOpcode::kNumberMultiply: 867 return machine()->Int32Mul(); 868 case IrOpcode::kSpeculativeNumberDivide: 869 case IrOpcode::kNumberDivide: 870 return machine()->Int32Div(); 871 case IrOpcode::kSpeculativeNumberModulus: 872 case IrOpcode::kNumberModulus: 873 return machine()->Int32Mod(); 874 case IrOpcode::kSpeculativeNumberBitwiseOr: // Fall through. 875 case IrOpcode::kNumberBitwiseOr: 876 return machine()->Word32Or(); 877 case IrOpcode::kSpeculativeNumberBitwiseXor: // Fall through. 878 case IrOpcode::kNumberBitwiseXor: 879 return machine()->Word32Xor(); 880 case IrOpcode::kSpeculativeNumberBitwiseAnd: // Fall through. 881 case IrOpcode::kNumberBitwiseAnd: 882 return machine()->Word32And(); 883 case IrOpcode::kNumberEqual: 884 case IrOpcode::kSpeculativeNumberEqual: 885 return machine()->Word32Equal(); 886 case IrOpcode::kNumberLessThan: 887 case IrOpcode::kSpeculativeNumberLessThan: 888 return machine()->Int32LessThan(); 889 case IrOpcode::kNumberLessThanOrEqual: 890 case IrOpcode::kSpeculativeNumberLessThanOrEqual: 891 return machine()->Int32LessThanOrEqual(); 892 default: 893 UNREACHABLE(); 894 } 895 } 896 897 const Operator* RepresentationChanger::Int32OverflowOperatorFor( 898 IrOpcode::Value opcode) { 899 switch (opcode) { 900 case IrOpcode::kSpeculativeSafeIntegerAdd: 901 return simplified()->CheckedInt32Add(); 902 case IrOpcode::kSpeculativeSafeIntegerSubtract: 903 return simplified()->CheckedInt32Sub(); 904 case IrOpcode::kSpeculativeNumberDivide: 905 return simplified()->CheckedInt32Div(); 906 case IrOpcode::kSpeculativeNumberModulus: 907 return simplified()->CheckedInt32Mod(); 908 default: 909 UNREACHABLE(); 910 } 911 } 912 913 const Operator* RepresentationChanger::TaggedSignedOperatorFor( 914 IrOpcode::Value opcode) { 915 switch (opcode) { 916 case IrOpcode::kSpeculativeNumberLessThan: 917 return machine()->Is32() ? machine()->Int32LessThan() 918 : machine()->Int64LessThan(); 919 case IrOpcode::kSpeculativeNumberLessThanOrEqual: 920 return machine()->Is32() ? machine()->Int32LessThanOrEqual() 921 : machine()->Int64LessThanOrEqual(); 922 case IrOpcode::kSpeculativeNumberEqual: 923 return machine()->Is32() ? machine()->Word32Equal() 924 : machine()->Word64Equal(); 925 default: 926 UNREACHABLE(); 927 } 928 } 929 930 const Operator* RepresentationChanger::Uint32OperatorFor( 931 IrOpcode::Value opcode) { 932 switch (opcode) { 933 case IrOpcode::kNumberAdd: 934 return machine()->Int32Add(); 935 case IrOpcode::kNumberSubtract: 936 return machine()->Int32Sub(); 937 case IrOpcode::kSpeculativeNumberMultiply: 938 case IrOpcode::kNumberMultiply: 939 return machine()->Int32Mul(); 940 case IrOpcode::kSpeculativeNumberDivide: 941 case IrOpcode::kNumberDivide: 942 return machine()->Uint32Div(); 943 case IrOpcode::kSpeculativeNumberModulus: 944 case IrOpcode::kNumberModulus: 945 return machine()->Uint32Mod(); 946 case IrOpcode::kNumberEqual: 947 case IrOpcode::kSpeculativeNumberEqual: 948 return machine()->Word32Equal(); 949 case IrOpcode::kNumberLessThan: 950 case IrOpcode::kSpeculativeNumberLessThan: 951 return machine()->Uint32LessThan(); 952 case IrOpcode::kNumberLessThanOrEqual: 953 case IrOpcode::kSpeculativeNumberLessThanOrEqual: 954 return machine()->Uint32LessThanOrEqual(); 955 case IrOpcode::kNumberClz32: 956 return machine()->Word32Clz(); 957 case IrOpcode::kNumberImul: 958 return machine()->Int32Mul(); 959 default: 960 UNREACHABLE(); 961 } 962 } 963 964 const Operator* RepresentationChanger::Uint32OverflowOperatorFor( 965 IrOpcode::Value opcode) { 966 switch (opcode) { 967 case IrOpcode::kSpeculativeNumberDivide: 968 return simplified()->CheckedUint32Div(); 969 case IrOpcode::kSpeculativeNumberModulus: 970 return simplified()->CheckedUint32Mod(); 971 default: 972 UNREACHABLE(); 973 } 974 } 975 976 const Operator* RepresentationChanger::Float64OperatorFor( 977 IrOpcode::Value opcode) { 978 switch (opcode) { 979 case IrOpcode::kSpeculativeNumberAdd: 980 case IrOpcode::kSpeculativeSafeIntegerAdd: 981 case IrOpcode::kNumberAdd: 982 return machine()->Float64Add(); 983 case IrOpcode::kSpeculativeNumberSubtract: 984 case IrOpcode::kSpeculativeSafeIntegerSubtract: 985 case IrOpcode::kNumberSubtract: 986 return machine()->Float64Sub(); 987 case IrOpcode::kSpeculativeNumberMultiply: 988 case IrOpcode::kNumberMultiply: 989 return machine()->Float64Mul(); 990 case IrOpcode::kSpeculativeNumberDivide: 991 case IrOpcode::kNumberDivide: 992 return machine()->Float64Div(); 993 case IrOpcode::kSpeculativeNumberModulus: 994 case IrOpcode::kNumberModulus: 995 return machine()->Float64Mod(); 996 case IrOpcode::kNumberEqual: 997 case IrOpcode::kSpeculativeNumberEqual: 998 return machine()->Float64Equal(); 999 case IrOpcode::kNumberLessThan: 1000 case IrOpcode::kSpeculativeNumberLessThan: 1001 return machine()->Float64LessThan(); 1002 case IrOpcode::kNumberLessThanOrEqual: 1003 case IrOpcode::kSpeculativeNumberLessThanOrEqual: 1004 return machine()->Float64LessThanOrEqual(); 1005 case IrOpcode::kNumberAbs: 1006 return machine()->Float64Abs(); 1007 case IrOpcode::kNumberAcos: 1008 return machine()->Float64Acos(); 1009 case IrOpcode::kNumberAcosh: 1010 return machine()->Float64Acosh(); 1011 case IrOpcode::kNumberAsin: 1012 return machine()->Float64Asin(); 1013 case IrOpcode::kNumberAsinh: 1014 return machine()->Float64Asinh(); 1015 case IrOpcode::kNumberAtan: 1016 return machine()->Float64Atan(); 1017 case IrOpcode::kNumberAtanh: 1018 return machine()->Float64Atanh(); 1019 case IrOpcode::kNumberAtan2: 1020 return machine()->Float64Atan2(); 1021 case IrOpcode::kNumberCbrt: 1022 return machine()->Float64Cbrt(); 1023 case IrOpcode::kNumberCeil: 1024 return machine()->Float64RoundUp().placeholder(); 1025 case IrOpcode::kNumberCos: 1026 return machine()->Float64Cos(); 1027 case IrOpcode::kNumberCosh: 1028 return machine()->Float64Cosh(); 1029 case IrOpcode::kNumberExp: 1030 return machine()->Float64Exp(); 1031 case IrOpcode::kNumberExpm1: 1032 return machine()->Float64Expm1(); 1033 case IrOpcode::kNumberFloor: 1034 return machine()->Float64RoundDown().placeholder(); 1035 case IrOpcode::kNumberFround: 1036 return machine()->TruncateFloat64ToFloat32(); 1037 case IrOpcode::kNumberLog: 1038 return machine()->Float64Log(); 1039 case IrOpcode::kNumberLog1p: 1040 return machine()->Float64Log1p(); 1041 case IrOpcode::kNumberLog2: 1042 return machine()->Float64Log2(); 1043 case IrOpcode::kNumberLog10: 1044 return machine()->Float64Log10(); 1045 case IrOpcode::kNumberMax: 1046 return machine()->Float64Max(); 1047 case IrOpcode::kNumberMin: 1048 return machine()->Float64Min(); 1049 case IrOpcode::kNumberPow: 1050 return machine()->Float64Pow(); 1051 case IrOpcode::kNumberSin: 1052 return machine()->Float64Sin(); 1053 case IrOpcode::kNumberSinh: 1054 return machine()->Float64Sinh(); 1055 case IrOpcode::kNumberSqrt: 1056 return machine()->Float64Sqrt(); 1057 case IrOpcode::kNumberTan: 1058 return machine()->Float64Tan(); 1059 case IrOpcode::kNumberTanh: 1060 return machine()->Float64Tanh(); 1061 case IrOpcode::kNumberTrunc: 1062 return machine()->Float64RoundTruncate().placeholder(); 1063 case IrOpcode::kNumberSilenceNaN: 1064 return machine()->Float64SilenceNaN(); 1065 default: 1066 UNREACHABLE(); 1067 } 1068 } 1069 1070 Node* RepresentationChanger::TypeError(Node* node, 1071 MachineRepresentation output_rep, 1072 Type output_type, 1073 MachineRepresentation use) { 1074 type_error_ = true; 1075 if (!testing_type_errors_) { 1076 std::ostringstream out_str; 1077 out_str << output_rep << " ("; 1078 output_type.PrintTo(out_str); 1079 out_str << ")"; 1080 1081 std::ostringstream use_str; 1082 use_str << use; 1083 1084 FATAL( 1085 "RepresentationChangerError: node #%d:%s of " 1086 "%s cannot be changed to %s", 1087 node->id(), node->op()->mnemonic(), out_str.str().c_str(), 1088 use_str.str().c_str()); 1089 } 1090 return node; 1091 } 1092 1093 Node* RepresentationChanger::InsertChangeBitToTagged(Node* node) { 1094 return jsgraph()->graph()->NewNode(simplified()->ChangeBitToTagged(), node); 1095 } 1096 1097 Node* RepresentationChanger::InsertChangeFloat32ToFloat64(Node* node) { 1098 return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node); 1099 } 1100 1101 Node* RepresentationChanger::InsertChangeFloat64ToUint32(Node* node) { 1102 return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToUint32(), node); 1103 } 1104 1105 Node* RepresentationChanger::InsertChangeFloat64ToInt32(Node* node) { 1106 return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToInt32(), node); 1107 } 1108 1109 Node* RepresentationChanger::InsertChangeInt32ToFloat64(Node* node) { 1110 return jsgraph()->graph()->NewNode(machine()->ChangeInt32ToFloat64(), node); 1111 } 1112 1113 Node* RepresentationChanger::InsertChangeTaggedSignedToInt32(Node* node) { 1114 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), 1115 node); 1116 } 1117 1118 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { 1119 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), 1120 node); 1121 } 1122 1123 Node* RepresentationChanger::InsertChangeUint32ToFloat64(Node* node) { 1124 return jsgraph()->graph()->NewNode(machine()->ChangeUint32ToFloat64(), node); 1125 } 1126 1127 } // namespace compiler 1128 } // namespace internal 1129 } // namespace v8 1130