| 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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 case IrOpcode::kNumberConstant: | 189 case IrOpcode::kNumberConstant: |
| 190 if (output_type->Is(Type::SignedSmall())) { | 190 if (output_type->Is(Type::SignedSmall())) { |
| 191 return node; | 191 return node; |
| 192 } | 192 } |
| 193 break; | 193 break; |
| 194 default: | 194 default: |
| 195 break; | 195 break; |
| 196 } | 196 } |
| 197 // Select the correct X -> Tagged operator. | 197 // Select the correct X -> Tagged operator. |
| 198 const Operator* op; | 198 const Operator* op; |
| 199 if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) { | 199 if (output_type->Is(Type::None())) { |
| 200 // This is an impossible value; it should not be used at runtime. | 200 // This is an impossible value; it should not be used at runtime. |
| 201 // We just provide a dummy value here. | 201 // We just provide a dummy value here. |
| 202 return jsgraph()->Constant(0); | 202 return jsgraph()->Constant(0); |
| 203 } else if (IsWord(output_rep)) { | 203 } else if (IsWord(output_rep)) { |
| 204 if (output_type->Is(Type::Signed31())) { | 204 if (output_type->Is(Type::Signed31())) { |
| 205 op = simplified()->ChangeInt31ToTaggedSigned(); | 205 op = simplified()->ChangeInt31ToTaggedSigned(); |
| 206 } else if (output_type->Is(Type::Signed32())) { | 206 } else if (output_type->Is(Type::Signed32())) { |
| 207 if (SmiValuesAre32Bits()) { | 207 if (SmiValuesAre32Bits()) { |
| 208 op = simplified()->ChangeInt32ToTagged(); | 208 op = simplified()->ChangeInt32ToTagged(); |
| 209 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) { | 209 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 MachineRepresentation::kTaggedPointer); | 286 MachineRepresentation::kTaggedPointer); |
| 287 } | 287 } |
| 288 case IrOpcode::kFloat64Constant: | 288 case IrOpcode::kFloat64Constant: |
| 289 case IrOpcode::kFloat32Constant: | 289 case IrOpcode::kFloat32Constant: |
| 290 return TypeError(node, output_rep, output_type, | 290 return TypeError(node, output_rep, output_type, |
| 291 MachineRepresentation::kTaggedPointer); | 291 MachineRepresentation::kTaggedPointer); |
| 292 default: | 292 default: |
| 293 break; | 293 break; |
| 294 } | 294 } |
| 295 // Select the correct X -> Tagged operator. | 295 // Select the correct X -> Tagged operator. |
| 296 if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) { | 296 if (output_type->Is(Type::None())) { |
| 297 // This is an impossible value; it should not be used at runtime. | 297 // This is an impossible value; it should not be used at runtime. |
| 298 // We just provide a dummy value here. | 298 // We just provide a dummy value here. |
| 299 return jsgraph()->TheHoleConstant(); | 299 return jsgraph()->TheHoleConstant(); |
| 300 } | 300 } |
| 301 return TypeError(node, output_rep, output_type, | 301 return TypeError(node, output_rep, output_type, |
| 302 MachineRepresentation::kTaggedPointer); | 302 MachineRepresentation::kTaggedPointer); |
| 303 } | 303 } |
| 304 | 304 |
| 305 Node* RepresentationChanger::GetTaggedRepresentationFor( | 305 Node* RepresentationChanger::GetTaggedRepresentationFor( |
| 306 Node* node, MachineRepresentation output_rep, Type* output_type, | 306 Node* node, MachineRepresentation output_rep, Type* output_type, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 331 default: | 331 default: |
| 332 break; | 332 break; |
| 333 } | 333 } |
| 334 if (output_rep == MachineRepresentation::kTaggedSigned || | 334 if (output_rep == MachineRepresentation::kTaggedSigned || |
| 335 output_rep == MachineRepresentation::kTaggedPointer) { | 335 output_rep == MachineRepresentation::kTaggedPointer) { |
| 336 // this is a no-op. | 336 // this is a no-op. |
| 337 return node; | 337 return node; |
| 338 } | 338 } |
| 339 // Select the correct X -> Tagged operator. | 339 // Select the correct X -> Tagged operator. |
| 340 const Operator* op; | 340 const Operator* op; |
| 341 if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) { | 341 if (output_type->Is(Type::None())) { |
| 342 // This is an impossible value; it should not be used at runtime. | 342 // This is an impossible value; it should not be used at runtime. |
| 343 // We just provide a dummy value here. | 343 // We just provide a dummy value here. |
| 344 return jsgraph()->TheHoleConstant(); | 344 return jsgraph()->TheHoleConstant(); |
| 345 } else if (output_rep == MachineRepresentation::kBit) { | 345 } else if (output_rep == MachineRepresentation::kBit) { |
| 346 if (output_type->Is(Type::Boolean())) { | 346 if (output_type->Is(Type::Boolean())) { |
| 347 op = simplified()->ChangeBitToTagged(); | 347 op = simplified()->ChangeBitToTagged(); |
| 348 } else { | 348 } else { |
| 349 return TypeError(node, output_rep, output_type, | 349 return TypeError(node, output_rep, output_type, |
| 350 MachineRepresentation::kTagged); | 350 MachineRepresentation::kTagged); |
| 351 } | 351 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 int32_t value = OpParameter<int32_t>(node); | 407 int32_t value = OpParameter<int32_t>(node); |
| 408 return jsgraph()->Float32Constant(static_cast<float>(value)); | 408 return jsgraph()->Float32Constant(static_cast<float>(value)); |
| 409 } | 409 } |
| 410 case IrOpcode::kFloat32Constant: | 410 case IrOpcode::kFloat32Constant: |
| 411 return node; // No change necessary. | 411 return node; // No change necessary. |
| 412 default: | 412 default: |
| 413 break; | 413 break; |
| 414 } | 414 } |
| 415 // Select the correct X -> Float32 operator. | 415 // Select the correct X -> Float32 operator. |
| 416 const Operator* op = nullptr; | 416 const Operator* op = nullptr; |
| 417 if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) { | 417 if (output_type->Is(Type::None())) { |
| 418 // This is an impossible value; it should not be used at runtime. | 418 // This is an impossible value; it should not be used at runtime. |
| 419 // We just provide a dummy value here. | 419 // We just provide a dummy value here. |
| 420 return jsgraph()->Float32Constant(0.0f); | 420 return jsgraph()->Float32Constant(0.0f); |
| 421 } else if (IsWord(output_rep)) { | 421 } else if (IsWord(output_rep)) { |
| 422 if (output_type->Is(Type::Signed32())) { | 422 if (output_type->Is(Type::Signed32())) { |
| 423 // int32 -> float64 -> float32 | 423 // int32 -> float64 -> float32 |
| 424 op = machine()->ChangeInt32ToFloat64(); | 424 op = machine()->ChangeInt32ToFloat64(); |
| 425 node = jsgraph()->graph()->NewNode(op, node); | 425 node = jsgraph()->graph()->NewNode(op, node); |
| 426 op = machine()->TruncateFloat64ToFloat32(); | 426 op = machine()->TruncateFloat64ToFloat32(); |
| 427 } else if (output_type->Is(Type::Unsigned32()) || | 427 } else if (output_type->Is(Type::Unsigned32()) || |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 case IrOpcode::kFloat64Constant: | 477 case IrOpcode::kFloat64Constant: |
| 478 return node; // No change necessary. | 478 return node; // No change necessary. |
| 479 case IrOpcode::kFloat32Constant: | 479 case IrOpcode::kFloat32Constant: |
| 480 return jsgraph()->Float64Constant(OpParameter<float>(node)); | 480 return jsgraph()->Float64Constant(OpParameter<float>(node)); |
| 481 default: | 481 default: |
| 482 break; | 482 break; |
| 483 } | 483 } |
| 484 } | 484 } |
| 485 // Select the correct X -> Float64 operator. | 485 // Select the correct X -> Float64 operator. |
| 486 const Operator* op = nullptr; | 486 const Operator* op = nullptr; |
| 487 if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) { | 487 if (output_type->Is(Type::None())) { |
| 488 // This is an impossible value; it should not be used at runtime. | 488 // This is an impossible value; it should not be used at runtime. |
| 489 // We just provide a dummy value here. | 489 // We just provide a dummy value here. |
| 490 return jsgraph()->Float64Constant(0.0); | 490 return jsgraph()->Float64Constant(0.0); |
| 491 } else if (IsWord(output_rep)) { | 491 } else if (IsWord(output_rep)) { |
| 492 if (output_type->Is(Type::Signed32())) { | 492 if (output_type->Is(Type::Signed32())) { |
| 493 op = machine()->ChangeInt32ToFloat64(); | 493 op = machine()->ChangeInt32ToFloat64(); |
| 494 } else if (output_type->Is(Type::Unsigned32()) || | 494 } else if (output_type->Is(Type::Unsigned32()) || |
| 495 use_info.truncation().IsUsedAsWord32()) { | 495 use_info.truncation().IsUsedAsWord32()) { |
| 496 // Either the output is uint32 or the uses only care about the | 496 // Either the output is uint32 or the uses only care about the |
| 497 // low 32 bits (so we can pick uint32 safely). | 497 // low 32 bits (so we can pick uint32 safely). |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 return MakeTruncatedInt32Constant(fv); | 563 return MakeTruncatedInt32Constant(fv); |
| 564 } | 564 } |
| 565 break; | 565 break; |
| 566 } | 566 } |
| 567 default: | 567 default: |
| 568 break; | 568 break; |
| 569 } | 569 } |
| 570 | 570 |
| 571 // Select the correct X -> Word32 operator. | 571 // Select the correct X -> Word32 operator. |
| 572 const Operator* op = nullptr; | 572 const Operator* op = nullptr; |
| 573 if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) { | 573 if (output_type->Is(Type::None())) { |
| 574 // This is an impossible value; it should not be used at runtime. | 574 // This is an impossible value; it should not be used at runtime. |
| 575 // We just provide a dummy value here. | 575 // We just provide a dummy value here. |
| 576 return jsgraph()->Int32Constant(0); | 576 return jsgraph()->Int32Constant(0); |
| 577 } else if (output_rep == MachineRepresentation::kBit) { | 577 } else if (output_rep == MachineRepresentation::kBit) { |
| 578 return node; // Sloppy comparison -> word32 | 578 return node; // Sloppy comparison -> word32 |
| 579 } else if (output_rep == MachineRepresentation::kFloat64) { | 579 } else if (output_rep == MachineRepresentation::kFloat64) { |
| 580 if (output_type->Is(Type::Unsigned32())) { | 580 if (output_type->Is(Type::Unsigned32())) { |
| 581 op = machine()->ChangeFloat64ToUint32(); | 581 op = machine()->ChangeFloat64ToUint32(); |
| 582 } else if (output_type->Is(Type::Signed32())) { | 582 } else if (output_type->Is(Type::Signed32())) { |
| 583 op = machine()->ChangeFloat64ToInt32(); | 583 op = machine()->ChangeFloat64ToInt32(); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 685 switch (node->opcode()) { | 685 switch (node->opcode()) { |
| 686 case IrOpcode::kHeapConstant: { | 686 case IrOpcode::kHeapConstant: { |
| 687 Handle<HeapObject> value = OpParameter<Handle<HeapObject>>(node); | 687 Handle<HeapObject> value = OpParameter<Handle<HeapObject>>(node); |
| 688 return jsgraph()->Int32Constant(value->BooleanValue() ? 1 : 0); | 688 return jsgraph()->Int32Constant(value->BooleanValue() ? 1 : 0); |
| 689 } | 689 } |
| 690 default: | 690 default: |
| 691 break; | 691 break; |
| 692 } | 692 } |
| 693 // Select the correct X -> Bit operator. | 693 // Select the correct X -> Bit operator. |
| 694 const Operator* op; | 694 const Operator* op; |
| 695 if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) { | 695 if (output_type->Is(Type::None())) { |
| 696 // This is an impossible value; it should not be used at runtime. | 696 // This is an impossible value; it should not be used at runtime. |
| 697 // We just provide a dummy value here. | 697 // We just provide a dummy value here. |
| 698 return jsgraph()->Int32Constant(0); | 698 return jsgraph()->Int32Constant(0); |
| 699 } else if (output_rep == MachineRepresentation::kTagged || | 699 } else if (output_rep == MachineRepresentation::kTagged || |
| 700 output_rep == MachineRepresentation::kTaggedPointer) { | 700 output_rep == MachineRepresentation::kTaggedPointer) { |
| 701 if (output_type->Is(Type::BooleanOrNullOrUndefined())) { | 701 if (output_type->Is(Type::BooleanOrNullOrUndefined())) { |
| 702 // true is the only trueish Oddball. | 702 // true is the only trueish Oddball. |
| 703 op = simplified()->ChangeTaggedToBit(); | 703 op = simplified()->ChangeTaggedToBit(); |
| 704 } else { | 704 } else { |
| 705 op = simplified()->TruncateTaggedToBit(); | 705 op = simplified()->TruncateTaggedToBit(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 724 jsgraph()->Float64Constant(0.0), node); | 724 jsgraph()->Float64Constant(0.0), node); |
| 725 } else { | 725 } else { |
| 726 return TypeError(node, output_rep, output_type, | 726 return TypeError(node, output_rep, output_type, |
| 727 MachineRepresentation::kBit); | 727 MachineRepresentation::kBit); |
| 728 } | 728 } |
| 729 return jsgraph()->graph()->NewNode(op, node); | 729 return jsgraph()->graph()->NewNode(op, node); |
| 730 } | 730 } |
| 731 | 731 |
| 732 Node* RepresentationChanger::GetWord64RepresentationFor( | 732 Node* RepresentationChanger::GetWord64RepresentationFor( |
| 733 Node* node, MachineRepresentation output_rep, Type* output_type) { | 733 Node* node, MachineRepresentation output_rep, Type* output_type) { |
| 734 if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) { | 734 if (output_type->Is(Type::None())) { |
| 735 // This is an impossible value; it should not be used at runtime. | 735 // This is an impossible value; it should not be used at runtime. |
| 736 // We just provide a dummy value here. | 736 // We just provide a dummy value here. |
| 737 return jsgraph()->Int64Constant(0); | 737 return jsgraph()->Int64Constant(0); |
| 738 } else if (output_rep == MachineRepresentation::kBit) { | 738 } else if (output_rep == MachineRepresentation::kBit) { |
| 739 return node; // Sloppy comparison -> word64 | 739 return node; // Sloppy comparison -> word64 |
| 740 } | 740 } |
| 741 // Can't really convert Word64 to anything else. Purported to be internal. | 741 // Can't really convert Word64 to anything else. Purported to be internal. |
| 742 return TypeError(node, output_rep, output_type, | 742 return TypeError(node, output_rep, output_type, |
| 743 MachineRepresentation::kWord64); | 743 MachineRepresentation::kWord64); |
| 744 } | 744 } |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 } | 989 } |
| 990 | 990 |
| 991 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { | 991 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { |
| 992 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), | 992 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), |
| 993 node); | 993 node); |
| 994 } | 994 } |
| 995 | 995 |
| 996 } // namespace compiler | 996 } // namespace compiler |
| 997 } // namespace internal | 997 } // namespace internal |
| 998 } // namespace v8 | 998 } // namespace v8 |
| OLD | NEW |