| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/representation-change.h" | 5 #include "src/compiler/representation-change.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 return InsertConversion(node, op, use_node); | 284 return InsertConversion(node, op, use_node); |
| 285 } | 285 } |
| 286 | 286 |
| 287 Node* RepresentationChanger::GetTaggedPointerRepresentationFor( | 287 Node* RepresentationChanger::GetTaggedPointerRepresentationFor( |
| 288 Node* node, MachineRepresentation output_rep, Type* output_type) { | 288 Node* node, MachineRepresentation output_rep, Type* output_type) { |
| 289 // Eagerly fold representation changes for constants. | 289 // Eagerly fold representation changes for constants. |
| 290 switch (node->opcode()) { | 290 switch (node->opcode()) { |
| 291 case IrOpcode::kHeapConstant: | 291 case IrOpcode::kHeapConstant: |
| 292 return node; // No change necessary. | 292 return node; // No change necessary. |
| 293 case IrOpcode::kInt32Constant: | 293 case IrOpcode::kInt32Constant: |
| 294 if (output_type->Is(Type::Boolean())) { | |
| 295 return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant() | |
| 296 : jsgraph()->TrueConstant(); | |
| 297 } else { | |
| 298 return TypeError(node, output_rep, output_type, | |
| 299 MachineRepresentation::kTaggedPointer); | |
| 300 } | |
| 301 case IrOpcode::kFloat64Constant: | 294 case IrOpcode::kFloat64Constant: |
| 302 case IrOpcode::kFloat32Constant: | 295 case IrOpcode::kFloat32Constant: |
| 303 return TypeError(node, output_rep, output_type, | 296 UNREACHABLE(); |
| 304 MachineRepresentation::kTaggedPointer); | |
| 305 default: | 297 default: |
| 306 break; | 298 break; |
| 307 } | 299 } |
| 308 // Select the correct X -> Tagged operator. | 300 // Select the correct X -> Tagged operator. |
| 309 if (output_type->Is(Type::None())) { | 301 if (output_type->Is(Type::None())) { |
| 310 // This is an impossible value; it should not be used at runtime. | 302 // This is an impossible value; it should not be used at runtime. |
| 311 // We just provide a dummy value here. | 303 // We just provide a dummy value here. |
| 312 return jsgraph()->TheHoleConstant(); | 304 return jsgraph()->TheHoleConstant(); |
| 313 } | 305 } |
| 314 return TypeError(node, output_rep, output_type, | 306 return TypeError(node, output_rep, output_type, |
| 315 MachineRepresentation::kTaggedPointer); | 307 MachineRepresentation::kTaggedPointer); |
| 316 } | 308 } |
| 317 | 309 |
| 318 Node* RepresentationChanger::GetTaggedRepresentationFor( | 310 Node* RepresentationChanger::GetTaggedRepresentationFor( |
| 319 Node* node, MachineRepresentation output_rep, Type* output_type, | 311 Node* node, MachineRepresentation output_rep, Type* output_type, |
| 320 Truncation truncation) { | 312 Truncation truncation) { |
| 321 // Eagerly fold representation changes for constants. | 313 // Eagerly fold representation changes for constants. |
| 322 switch (node->opcode()) { | 314 switch (node->opcode()) { |
| 323 case IrOpcode::kNumberConstant: | 315 case IrOpcode::kNumberConstant: |
| 324 case IrOpcode::kHeapConstant: | 316 case IrOpcode::kHeapConstant: |
| 325 return node; // No change necessary. | 317 return node; // No change necessary. |
| 326 case IrOpcode::kInt32Constant: | 318 case IrOpcode::kInt32Constant: |
| 327 if (output_type->Is(Type::Signed32())) { | |
| 328 int32_t value = OpParameter<int32_t>(node); | |
| 329 return jsgraph()->Constant(value); | |
| 330 } else if (output_type->Is(Type::Unsigned32())) { | |
| 331 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node)); | |
| 332 return jsgraph()->Constant(static_cast<double>(value)); | |
| 333 } else if (output_type->Is(Type::Boolean())) { | |
| 334 return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant() | |
| 335 : jsgraph()->TrueConstant(); | |
| 336 } else { | |
| 337 return TypeError(node, output_rep, output_type, | |
| 338 MachineRepresentation::kTagged); | |
| 339 } | |
| 340 case IrOpcode::kFloat64Constant: | 319 case IrOpcode::kFloat64Constant: |
| 341 return jsgraph()->Constant(OpParameter<double>(node)); | |
| 342 case IrOpcode::kFloat32Constant: | 320 case IrOpcode::kFloat32Constant: |
| 343 return jsgraph()->Constant(OpParameter<float>(node)); | 321 UNREACHABLE(); |
| 322 break; |
| 344 default: | 323 default: |
| 345 break; | 324 break; |
| 346 } | 325 } |
| 347 if (output_rep == MachineRepresentation::kTaggedSigned || | 326 if (output_rep == MachineRepresentation::kTaggedSigned || |
| 348 output_rep == MachineRepresentation::kTaggedPointer) { | 327 output_rep == MachineRepresentation::kTaggedPointer) { |
| 349 // this is a no-op. | 328 // this is a no-op. |
| 350 return node; | 329 return node; |
| 351 } | 330 } |
| 352 // Select the correct X -> Tagged operator. | 331 // Select the correct X -> Tagged operator. |
| 353 const Operator* op; | 332 const Operator* op; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 } | 380 } |
| 402 return jsgraph()->graph()->NewNode(op, node); | 381 return jsgraph()->graph()->NewNode(op, node); |
| 403 } | 382 } |
| 404 | 383 |
| 405 | 384 |
| 406 Node* RepresentationChanger::GetFloat32RepresentationFor( | 385 Node* RepresentationChanger::GetFloat32RepresentationFor( |
| 407 Node* node, MachineRepresentation output_rep, Type* output_type, | 386 Node* node, MachineRepresentation output_rep, Type* output_type, |
| 408 Truncation truncation) { | 387 Truncation truncation) { |
| 409 // Eagerly fold representation changes for constants. | 388 // Eagerly fold representation changes for constants. |
| 410 switch (node->opcode()) { | 389 switch (node->opcode()) { |
| 411 case IrOpcode::kFloat64Constant: | |
| 412 case IrOpcode::kNumberConstant: | 390 case IrOpcode::kNumberConstant: |
| 413 return jsgraph()->Float32Constant( | 391 return jsgraph()->Float32Constant( |
| 414 DoubleToFloat32(OpParameter<double>(node))); | 392 DoubleToFloat32(OpParameter<double>(node))); |
| 415 case IrOpcode::kInt32Constant: | 393 case IrOpcode::kInt32Constant: |
| 416 if (output_type->Is(Type::Unsigned32())) { | 394 case IrOpcode::kFloat64Constant: |
| 417 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node)); | |
| 418 return jsgraph()->Float32Constant(static_cast<float>(value)); | |
| 419 } else { | |
| 420 int32_t value = OpParameter<int32_t>(node); | |
| 421 return jsgraph()->Float32Constant(static_cast<float>(value)); | |
| 422 } | |
| 423 case IrOpcode::kFloat32Constant: | 395 case IrOpcode::kFloat32Constant: |
| 424 return node; // No change necessary. | 396 UNREACHABLE(); |
| 397 break; |
| 425 default: | 398 default: |
| 426 break; | 399 break; |
| 427 } | 400 } |
| 428 // Select the correct X -> Float32 operator. | 401 // Select the correct X -> Float32 operator. |
| 429 const Operator* op = nullptr; | 402 const Operator* op = nullptr; |
| 430 if (output_type->Is(Type::None())) { | 403 if (output_type->Is(Type::None())) { |
| 431 // This is an impossible value; it should not be used at runtime. | 404 // This is an impossible value; it should not be used at runtime. |
| 432 // We just provide a dummy value here. | 405 // We just provide a dummy value here. |
| 433 return jsgraph()->Float32Constant(0.0f); | 406 return jsgraph()->Float32Constant(0.0f); |
| 434 } else if (IsWord(output_rep)) { | 407 } else if (IsWord(output_rep)) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 Node* RepresentationChanger::GetFloat64RepresentationFor( | 445 Node* RepresentationChanger::GetFloat64RepresentationFor( |
| 473 Node* node, MachineRepresentation output_rep, Type* output_type, | 446 Node* node, MachineRepresentation output_rep, Type* output_type, |
| 474 Node* use_node, UseInfo use_info) { | 447 Node* use_node, UseInfo use_info) { |
| 475 // Eagerly fold representation changes for constants. | 448 // Eagerly fold representation changes for constants. |
| 476 if ((use_info.type_check() == TypeCheckKind::kNone)) { | 449 if ((use_info.type_check() == TypeCheckKind::kNone)) { |
| 477 // TODO(jarin) Handle checked constant conversions. | 450 // TODO(jarin) Handle checked constant conversions. |
| 478 switch (node->opcode()) { | 451 switch (node->opcode()) { |
| 479 case IrOpcode::kNumberConstant: | 452 case IrOpcode::kNumberConstant: |
| 480 return jsgraph()->Float64Constant(OpParameter<double>(node)); | 453 return jsgraph()->Float64Constant(OpParameter<double>(node)); |
| 481 case IrOpcode::kInt32Constant: | 454 case IrOpcode::kInt32Constant: |
| 482 if (output_type->Is(Type::Signed32())) { | |
| 483 int32_t value = OpParameter<int32_t>(node); | |
| 484 return jsgraph()->Float64Constant(value); | |
| 485 } else { | |
| 486 DCHECK(output_type->Is(Type::Unsigned32())); | |
| 487 uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node)); | |
| 488 return jsgraph()->Float64Constant(static_cast<double>(value)); | |
| 489 } | |
| 490 case IrOpcode::kFloat64Constant: | 455 case IrOpcode::kFloat64Constant: |
| 491 return node; // No change necessary. | |
| 492 case IrOpcode::kFloat32Constant: | 456 case IrOpcode::kFloat32Constant: |
| 493 return jsgraph()->Float64Constant(OpParameter<float>(node)); | 457 UNREACHABLE(); |
| 458 break; |
| 494 default: | 459 default: |
| 495 break; | 460 break; |
| 496 } | 461 } |
| 497 } | 462 } |
| 498 // Select the correct X -> Float64 operator. | 463 // Select the correct X -> Float64 operator. |
| 499 const Operator* op = nullptr; | 464 const Operator* op = nullptr; |
| 500 if (output_type->Is(Type::None())) { | 465 if (output_type->Is(Type::None())) { |
| 501 // This is an impossible value; it should not be used at runtime. | 466 // This is an impossible value; it should not be used at runtime. |
| 502 // We just provide a dummy value here. | 467 // We just provide a dummy value here. |
| 503 return jsgraph()->Float64Constant(0.0); | 468 return jsgraph()->Float64Constant(0.0); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) { | 513 Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) { |
| 549 return jsgraph()->Int32Constant(DoubleToInt32(value)); | 514 return jsgraph()->Int32Constant(DoubleToInt32(value)); |
| 550 } | 515 } |
| 551 | 516 |
| 552 Node* RepresentationChanger::GetWord32RepresentationFor( | 517 Node* RepresentationChanger::GetWord32RepresentationFor( |
| 553 Node* node, MachineRepresentation output_rep, Type* output_type, | 518 Node* node, MachineRepresentation output_rep, Type* output_type, |
| 554 Node* use_node, UseInfo use_info) { | 519 Node* use_node, UseInfo use_info) { |
| 555 // Eagerly fold representation changes for constants. | 520 // Eagerly fold representation changes for constants. |
| 556 switch (node->opcode()) { | 521 switch (node->opcode()) { |
| 557 case IrOpcode::kInt32Constant: | 522 case IrOpcode::kInt32Constant: |
| 558 return node; // No change necessary. | 523 case IrOpcode::kFloat32Constant: |
| 559 case IrOpcode::kFloat32Constant: { | 524 case IrOpcode::kFloat64Constant: |
| 560 float const fv = OpParameter<float>(node); | 525 UNREACHABLE(); |
| 561 if (use_info.type_check() == TypeCheckKind::kNone || | |
| 562 ((use_info.type_check() == TypeCheckKind::kSignedSmall || | |
| 563 use_info.type_check() == TypeCheckKind::kSigned32) && | |
| 564 IsInt32Double(fv))) { | |
| 565 return MakeTruncatedInt32Constant(fv); | |
| 566 } | |
| 567 break; | 526 break; |
| 568 } | 527 case IrOpcode::kNumberConstant: { |
| 569 case IrOpcode::kNumberConstant: | |
| 570 case IrOpcode::kFloat64Constant: { | |
| 571 double const fv = OpParameter<double>(node); | 528 double const fv = OpParameter<double>(node); |
| 572 if (use_info.type_check() == TypeCheckKind::kNone || | 529 if (use_info.type_check() == TypeCheckKind::kNone || |
| 573 ((use_info.type_check() == TypeCheckKind::kSignedSmall || | 530 ((use_info.type_check() == TypeCheckKind::kSignedSmall || |
| 574 use_info.type_check() == TypeCheckKind::kSigned32) && | 531 use_info.type_check() == TypeCheckKind::kSigned32) && |
| 575 IsInt32Double(fv))) { | 532 IsInt32Double(fv))) { |
| 576 return MakeTruncatedInt32Constant(fv); | 533 return MakeTruncatedInt32Constant(fv); |
| 577 } | 534 } |
| 578 break; | 535 break; |
| 579 } | 536 } |
| 580 default: | 537 default: |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1002 } | 959 } |
| 1003 | 960 |
| 1004 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { | 961 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { |
| 1005 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), | 962 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), |
| 1006 node); | 963 node); |
| 1007 } | 964 } |
| 1008 | 965 |
| 1009 } // namespace compiler | 966 } // namespace compiler |
| 1010 } // namespace internal | 967 } // namespace internal |
| 1011 } // namespace v8 | 968 } // namespace v8 |
| OLD | NEW |