| 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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 } | 197 } |
| 198 case IrOpcode::kFloat64Constant: | 198 case IrOpcode::kFloat64Constant: |
| 199 return jsgraph()->Constant(OpParameter<double>(node)); | 199 return jsgraph()->Constant(OpParameter<double>(node)); |
| 200 case IrOpcode::kFloat32Constant: | 200 case IrOpcode::kFloat32Constant: |
| 201 return jsgraph()->Constant(OpParameter<float>(node)); | 201 return jsgraph()->Constant(OpParameter<float>(node)); |
| 202 default: | 202 default: |
| 203 break; | 203 break; |
| 204 } | 204 } |
| 205 // Select the correct X -> Tagged operator. | 205 // Select the correct X -> Tagged operator. |
| 206 const Operator* op; | 206 const Operator* op; |
| 207 if (output_rep == MachineRepresentation::kNone) { | 207 if (output_type->Is(Type::None())) { |
| 208 // We should only asisgn this representation if the type is empty. | 208 // This is an impossible value; it should not be used at runtime. |
| 209 CHECK(!output_type->IsInhabited()); | 209 // We just provide a dummy value here. |
| 210 op = machine()->ImpossibleToTagged(); | 210 return jsgraph()->TheHoleConstant(); |
| 211 } else if (output_rep == MachineRepresentation::kBit) { | 211 } else if (output_rep == MachineRepresentation::kBit) { |
| 212 if (output_type->Is(Type::Boolean())) { | 212 if (output_type->Is(Type::Boolean())) { |
| 213 op = simplified()->ChangeBitToTagged(); | 213 op = simplified()->ChangeBitToTagged(); |
| 214 } else { | 214 } else { |
| 215 return TypeError(node, output_rep, output_type, | 215 return TypeError(node, output_rep, output_type, |
| 216 MachineRepresentation::kTagged); | 216 MachineRepresentation::kTagged); |
| 217 } | 217 } |
| 218 } else if (IsWord(output_rep)) { | 218 } else if (IsWord(output_rep)) { |
| 219 if (output_type->Is(Type::Signed31())) { | 219 if (output_type->Is(Type::Signed31())) { |
| 220 op = simplified()->ChangeInt31ToTaggedSigned(); | 220 op = simplified()->ChangeInt31ToTaggedSigned(); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 int32_t value = OpParameter<int32_t>(node); | 276 int32_t value = OpParameter<int32_t>(node); |
| 277 return jsgraph()->Float32Constant(static_cast<float>(value)); | 277 return jsgraph()->Float32Constant(static_cast<float>(value)); |
| 278 } | 278 } |
| 279 case IrOpcode::kFloat32Constant: | 279 case IrOpcode::kFloat32Constant: |
| 280 return node; // No change necessary. | 280 return node; // No change necessary. |
| 281 default: | 281 default: |
| 282 break; | 282 break; |
| 283 } | 283 } |
| 284 // Select the correct X -> Float32 operator. | 284 // Select the correct X -> Float32 operator. |
| 285 const Operator* op = nullptr; | 285 const Operator* op = nullptr; |
| 286 if (output_rep == MachineRepresentation::kNone) { | 286 if (output_type->Is(Type::None())) { |
| 287 // We should only use kNone representation if the type is empty. | 287 // This is an impossible value; it should not be used at runtime. |
| 288 CHECK(!output_type->IsInhabited()); | 288 // We just provide a dummy value here. |
| 289 op = machine()->ImpossibleToFloat32(); | 289 return jsgraph()->Float32Constant(0.0f); |
| 290 } else if (IsWord(output_rep)) { | 290 } else if (IsWord(output_rep)) { |
| 291 if (output_type->Is(Type::Signed32())) { | 291 if (output_type->Is(Type::Signed32())) { |
| 292 // int32 -> float64 -> float32 | 292 // int32 -> float64 -> float32 |
| 293 op = machine()->ChangeInt32ToFloat64(); | 293 op = machine()->ChangeInt32ToFloat64(); |
| 294 node = jsgraph()->graph()->NewNode(op, node); | 294 node = jsgraph()->graph()->NewNode(op, node); |
| 295 op = machine()->TruncateFloat64ToFloat32(); | 295 op = machine()->TruncateFloat64ToFloat32(); |
| 296 } else if (output_type->Is(Type::Unsigned32()) || | 296 } else if (output_type->Is(Type::Unsigned32()) || |
| 297 truncation.IsUsedAsWord32()) { | 297 truncation.IsUsedAsWord32()) { |
| 298 // Either the output is uint32 or the uses only care about the | 298 // Either the output is uint32 or the uses only care about the |
| 299 // low 32 bits (so we can pick uint32 safely). | 299 // low 32 bits (so we can pick uint32 safely). |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 case IrOpcode::kFloat64Constant: | 345 case IrOpcode::kFloat64Constant: |
| 346 return node; // No change necessary. | 346 return node; // No change necessary. |
| 347 case IrOpcode::kFloat32Constant: | 347 case IrOpcode::kFloat32Constant: |
| 348 return jsgraph()->Float64Constant(OpParameter<float>(node)); | 348 return jsgraph()->Float64Constant(OpParameter<float>(node)); |
| 349 default: | 349 default: |
| 350 break; | 350 break; |
| 351 } | 351 } |
| 352 } | 352 } |
| 353 // Select the correct X -> Float64 operator. | 353 // Select the correct X -> Float64 operator. |
| 354 const Operator* op = nullptr; | 354 const Operator* op = nullptr; |
| 355 if (output_rep == MachineRepresentation::kNone) { | 355 if (output_type->Is(Type::None())) { |
| 356 // We should only use kNone representation if the type is empty. | 356 // This is an impossible value; it should not be used at runtime. |
| 357 CHECK(!output_type->IsInhabited()); | 357 // We just provide a dummy value here. |
| 358 op = machine()->ImpossibleToFloat64(); | 358 return jsgraph()->Float64Constant(0.0); |
| 359 } else if (IsWord(output_rep)) { | 359 } else if (IsWord(output_rep)) { |
| 360 if (output_type->Is(Type::Signed32())) { | 360 if (output_type->Is(Type::Signed32())) { |
| 361 op = machine()->ChangeInt32ToFloat64(); | 361 op = machine()->ChangeInt32ToFloat64(); |
| 362 } else if (output_type->Is(Type::Unsigned32()) || | 362 } else if (output_type->Is(Type::Unsigned32()) || |
| 363 use_info.truncation().IsUsedAsWord32()) { | 363 use_info.truncation().IsUsedAsWord32()) { |
| 364 // Either the output is uint32 or the uses only care about the | 364 // Either the output is uint32 or the uses only care about the |
| 365 // low 32 bits (so we can pick uint32 safely). | 365 // low 32 bits (so we can pick uint32 safely). |
| 366 op = machine()->ChangeUint32ToFloat64(); | 366 op = machine()->ChangeUint32ToFloat64(); |
| 367 } | 367 } |
| 368 } else if (output_rep == MachineRepresentation::kBit) { | 368 } else if (output_rep == MachineRepresentation::kBit) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 return MakeTruncatedInt32Constant(fv); | 428 return MakeTruncatedInt32Constant(fv); |
| 429 } | 429 } |
| 430 break; | 430 break; |
| 431 } | 431 } |
| 432 default: | 432 default: |
| 433 break; | 433 break; |
| 434 } | 434 } |
| 435 | 435 |
| 436 // Select the correct X -> Word32 operator. | 436 // Select the correct X -> Word32 operator. |
| 437 const Operator* op = nullptr; | 437 const Operator* op = nullptr; |
| 438 if (output_rep == MachineRepresentation::kNone) { | 438 if (output_type->Is(Type::None())) { |
| 439 // We should only use kNone representation if the type is empty. | 439 // This is an impossible value; it should not be used at runtime. |
| 440 CHECK(!output_type->IsInhabited()); | 440 // We just provide a dummy value here. |
| 441 op = machine()->ImpossibleToWord32(); | 441 return jsgraph()->Int32Constant(0); |
| 442 } else if (output_rep == MachineRepresentation::kBit) { | 442 } else if (output_rep == MachineRepresentation::kBit) { |
| 443 return node; // Sloppy comparison -> word32 | 443 return node; // Sloppy comparison -> word32 |
| 444 } else if (output_rep == MachineRepresentation::kFloat64) { | 444 } else if (output_rep == MachineRepresentation::kFloat64) { |
| 445 if (output_type->Is(Type::Unsigned32())) { | 445 if (output_type->Is(Type::Unsigned32())) { |
| 446 op = machine()->ChangeFloat64ToUint32(); | 446 op = machine()->ChangeFloat64ToUint32(); |
| 447 } else if (output_type->Is(Type::Signed32())) { | 447 } else if (output_type->Is(Type::Signed32())) { |
| 448 op = machine()->ChangeFloat64ToInt32(); | 448 op = machine()->ChangeFloat64ToInt32(); |
| 449 } else if (use_info.truncation().IsUsedAsWord32()) { | 449 } else if (use_info.truncation().IsUsedAsWord32()) { |
| 450 op = machine()->TruncateFloat64ToWord32(); | 450 op = machine()->TruncateFloat64ToWord32(); |
| 451 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall || | 451 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall || |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 DCHECK(value.is_identical_to(factory()->true_value()) || | 544 DCHECK(value.is_identical_to(factory()->true_value()) || |
| 545 value.is_identical_to(factory()->false_value())); | 545 value.is_identical_to(factory()->false_value())); |
| 546 return jsgraph()->Int32Constant( | 546 return jsgraph()->Int32Constant( |
| 547 value.is_identical_to(factory()->true_value()) ? 1 : 0); | 547 value.is_identical_to(factory()->true_value()) ? 1 : 0); |
| 548 } | 548 } |
| 549 default: | 549 default: |
| 550 break; | 550 break; |
| 551 } | 551 } |
| 552 // Select the correct X -> Bit operator. | 552 // Select the correct X -> Bit operator. |
| 553 const Operator* op; | 553 const Operator* op; |
| 554 if (output_rep == MachineRepresentation::kNone) { | 554 if (output_type->Is(Type::None())) { |
| 555 // We should only use kNone representation if the type is empty. | 555 // This is an impossible value; it should not be used at runtime. |
| 556 CHECK(!output_type->IsInhabited()); | 556 // We just provide a dummy value here. |
| 557 op = machine()->ImpossibleToBit(); | 557 return jsgraph()->Int32Constant(0); |
| 558 } else if (output_rep == MachineRepresentation::kTagged) { | 558 } else if (output_rep == MachineRepresentation::kTagged) { |
| 559 op = simplified()->ChangeTaggedToBit(); | 559 op = simplified()->ChangeTaggedToBit(); |
| 560 } else { | 560 } else { |
| 561 return TypeError(node, output_rep, output_type, | 561 return TypeError(node, output_rep, output_type, |
| 562 MachineRepresentation::kBit); | 562 MachineRepresentation::kBit); |
| 563 } | 563 } |
| 564 return jsgraph()->graph()->NewNode(op, node); | 564 return jsgraph()->graph()->NewNode(op, node); |
| 565 } | 565 } |
| 566 | 566 |
| 567 Node* RepresentationChanger::GetWord64RepresentationFor( | 567 Node* RepresentationChanger::GetWord64RepresentationFor( |
| 568 Node* node, MachineRepresentation output_rep, Type* output_type) { | 568 Node* node, MachineRepresentation output_rep, Type* output_type) { |
| 569 if (output_rep == MachineRepresentation::kNone) { | 569 if (output_type->Is(Type::None())) { |
| 570 // We should only use kNone representation if the type is empty. | 570 // This is an impossible value; it should not be used at runtime. |
| 571 CHECK(!output_type->IsInhabited()); | 571 // We just provide a dummy value here. |
| 572 return jsgraph()->graph()->NewNode(machine()->ImpossibleToFloat64(), node); | 572 return jsgraph()->Int64Constant(0); |
| 573 } else if (output_rep == MachineRepresentation::kBit) { | 573 } else if (output_rep == MachineRepresentation::kBit) { |
| 574 return node; // Sloppy comparison -> word64 | 574 return node; // Sloppy comparison -> word64 |
| 575 } | 575 } |
| 576 // Can't really convert Word64 to anything else. Purported to be internal. | 576 // Can't really convert Word64 to anything else. Purported to be internal. |
| 577 return TypeError(node, output_rep, output_type, | 577 return TypeError(node, output_rep, output_type, |
| 578 MachineRepresentation::kWord64); | 578 MachineRepresentation::kWord64); |
| 579 } | 579 } |
| 580 | 580 |
| 581 const Operator* RepresentationChanger::Int32OperatorFor( | 581 const Operator* RepresentationChanger::Int32OperatorFor( |
| 582 IrOpcode::Value opcode) { | 582 IrOpcode::Value opcode) { |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 } | 821 } |
| 822 | 822 |
| 823 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { | 823 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { |
| 824 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), | 824 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), |
| 825 node); | 825 node); |
| 826 } | 826 } |
| 827 | 827 |
| 828 } // namespace compiler | 828 } // namespace compiler |
| 829 } // namespace internal | 829 } // namespace internal |
| 830 } // namespace v8 | 830 } // namespace v8 |
| OLD | NEW |