OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/address-map.h" | 9 #include "src/address-map.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 break; | 408 break; |
409 | 409 |
410 case IrOpcode::kPhi: { | 410 case IrOpcode::kPhi: { |
411 new_type = TypePhi(node); | 411 new_type = TypePhi(node); |
412 if (type != nullptr) { | 412 if (type != nullptr) { |
413 new_type = Weaken(node, type, new_type); | 413 new_type = Weaken(node, type, new_type); |
414 } | 414 } |
415 break; | 415 break; |
416 } | 416 } |
417 | 417 |
| 418 case IrOpcode::kTypeGuard: { |
| 419 new_type = op_typer_.TypeTypeGuard(node->op(), |
| 420 FeedbackTypeOf(node->InputAt(0))); |
| 421 break; |
| 422 } |
| 423 |
418 case IrOpcode::kSelect: { | 424 case IrOpcode::kSelect: { |
419 new_type = TypeSelect(node); | 425 new_type = TypeSelect(node); |
420 break; | 426 break; |
421 } | 427 } |
422 | 428 |
423 default: | 429 default: |
424 // Shortcut for operations that we do not handle. | 430 // Shortcut for operations that we do not handle. |
425 if (type == nullptr) { | 431 if (type == nullptr) { |
426 GetInfo(node)->set_feedback_type(NodeProperties::GetType(node)); | 432 GetInfo(node)->set_feedback_type(NodeProperties::GetType(node)); |
427 return true; | 433 return true; |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
812 VisitBinop(node, UseInfo::TruncatingWord32(), MachineRepresentation::kBit); | 818 VisitBinop(node, UseInfo::TruncatingWord32(), MachineRepresentation::kBit); |
813 } | 819 } |
814 void VisitInt64Cmp(Node* node) { | 820 void VisitInt64Cmp(Node* node) { |
815 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit); | 821 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit); |
816 } | 822 } |
817 void VisitUint64Cmp(Node* node) { | 823 void VisitUint64Cmp(Node* node) { |
818 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit); | 824 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit); |
819 } | 825 } |
820 | 826 |
821 // Infer representation for phi-like nodes. | 827 // Infer representation for phi-like nodes. |
822 MachineRepresentation GetOutputInfoForPhi(Node* node, Truncation use) { | 828 // The {node} parameter is only used to decide on the int64 representation. |
| 829 // Once the type system supports an external pointer type, the {node} |
| 830 // parameter can be removed. |
| 831 MachineRepresentation GetOutputInfoForPhi(Node* node, Type* type, |
| 832 Truncation use) { |
823 // Compute the representation. | 833 // Compute the representation. |
824 Type* type = TypeOf(node); | |
825 if (type->Is(Type::None())) { | 834 if (type->Is(Type::None())) { |
826 return MachineRepresentation::kNone; | 835 return MachineRepresentation::kNone; |
827 } else if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) { | 836 } else if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) { |
828 return MachineRepresentation::kWord32; | 837 return MachineRepresentation::kWord32; |
829 } else if (type->Is(Type::NumberOrOddball()) && use.IsUsedAsWord32()) { | 838 } else if (type->Is(Type::NumberOrOddball()) && use.IsUsedAsWord32()) { |
830 return MachineRepresentation::kWord32; | 839 return MachineRepresentation::kWord32; |
831 } else if (type->Is(Type::Boolean())) { | 840 } else if (type->Is(Type::Boolean())) { |
832 return MachineRepresentation::kBit; | 841 return MachineRepresentation::kBit; |
833 } else if (type->Is(Type::NumberOrOddball()) && use.IsUsedAsFloat64()) { | 842 } else if (type->Is(Type::NumberOrOddball()) && use.IsUsedAsFloat64()) { |
834 return MachineRepresentation::kFloat64; | 843 return MachineRepresentation::kFloat64; |
(...skipping 26 matching lines...) Expand all Loading... |
861 : MachineRepresentation::kTagged; | 870 : MachineRepresentation::kTagged; |
862 } | 871 } |
863 return MachineRepresentation::kTagged; | 872 return MachineRepresentation::kTagged; |
864 } | 873 } |
865 | 874 |
866 // Helper for handling selects. | 875 // Helper for handling selects. |
867 void VisitSelect(Node* node, Truncation truncation, | 876 void VisitSelect(Node* node, Truncation truncation, |
868 SimplifiedLowering* lowering) { | 877 SimplifiedLowering* lowering) { |
869 ProcessInput(node, 0, UseInfo::Bool()); | 878 ProcessInput(node, 0, UseInfo::Bool()); |
870 | 879 |
871 MachineRepresentation output = GetOutputInfoForPhi(node, truncation); | 880 MachineRepresentation output = |
| 881 GetOutputInfoForPhi(node, TypeOf(node), truncation); |
872 SetOutput(node, output); | 882 SetOutput(node, output); |
873 | 883 |
874 if (lower()) { | 884 if (lower()) { |
875 // Update the select operator. | 885 // Update the select operator. |
876 SelectParameters p = SelectParametersOf(node->op()); | 886 SelectParameters p = SelectParametersOf(node->op()); |
877 if (output != p.representation()) { | 887 if (output != p.representation()) { |
878 NodeProperties::ChangeOp(node, | 888 NodeProperties::ChangeOp(node, |
879 lowering->common()->Select(output, p.hint())); | 889 lowering->common()->Select(output, p.hint())); |
880 } | 890 } |
881 } | 891 } |
882 // Convert inputs to the output representation of this phi, pass the | 892 // Convert inputs to the output representation of this phi, pass the |
883 // truncation truncation along. | 893 // truncation truncation along. |
884 UseInfo input_use(output, truncation); | 894 UseInfo input_use(output, truncation); |
885 ProcessInput(node, 1, input_use); | 895 ProcessInput(node, 1, input_use); |
886 ProcessInput(node, 2, input_use); | 896 ProcessInput(node, 2, input_use); |
887 } | 897 } |
888 | 898 |
889 // Helper for handling phis. | 899 // Helper for handling phis. |
890 void VisitPhi(Node* node, Truncation truncation, | 900 void VisitPhi(Node* node, Truncation truncation, |
891 SimplifiedLowering* lowering) { | 901 SimplifiedLowering* lowering) { |
892 MachineRepresentation output = GetOutputInfoForPhi(node, truncation); | 902 MachineRepresentation output = |
| 903 GetOutputInfoForPhi(node, TypeOf(node), truncation); |
893 // Only set the output representation if not running with type | 904 // Only set the output representation if not running with type |
894 // feedback. (Feedback typing will set the representation.) | 905 // feedback. (Feedback typing will set the representation.) |
895 SetOutput(node, output); | 906 SetOutput(node, output); |
896 | 907 |
897 int values = node->op()->ValueInputCount(); | 908 int values = node->op()->ValueInputCount(); |
898 if (lower()) { | 909 if (lower()) { |
899 // Update the phi operator. | 910 // Update the phi operator. |
900 if (output != PhiRepresentationOf(node->op())) { | 911 if (output != PhiRepresentationOf(node->op())) { |
901 NodeProperties::ChangeOp(node, lowering->common()->Phi(output, values)); | 912 NodeProperties::ChangeOp(node, lowering->common()->Phi(output, values)); |
902 } | 913 } |
903 } | 914 } |
904 | 915 |
905 // Convert inputs to the output representation of this phi, pass the | 916 // Convert inputs to the output representation of this phi, pass the |
906 // truncation truncation along. | 917 // truncation along. |
907 UseInfo input_use(output, truncation); | 918 UseInfo input_use(output, truncation); |
908 for (int i = 0; i < node->InputCount(); i++) { | 919 for (int i = 0; i < node->InputCount(); i++) { |
909 ProcessInput(node, i, i < values ? input_use : UseInfo::None()); | 920 ProcessInput(node, i, i < values ? input_use : UseInfo::None()); |
910 } | 921 } |
911 } | 922 } |
912 | 923 |
913 void VisitCall(Node* node, SimplifiedLowering* lowering) { | 924 void VisitCall(Node* node, SimplifiedLowering* lowering) { |
914 const CallDescriptor* desc = CallDescriptorOf(node->op()); | 925 const CallDescriptor* desc = CallDescriptorOf(node->op()); |
915 int params = static_cast<int>(desc->ParameterCount()); | 926 int params = static_cast<int>(desc->ParameterCount()); |
916 int value_input_count = node->op()->ValueInputCount(); | 927 int value_input_count = node->op()->ValueInputCount(); |
(...skipping 1606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2523 VisitUnop(node, UseInfo::TruncatingFloat64(), | 2534 VisitUnop(node, UseInfo::TruncatingFloat64(), |
2524 MachineRepresentation::kFloat64); | 2535 MachineRepresentation::kFloat64); |
2525 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); | 2536 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
2526 return; | 2537 return; |
2527 case IrOpcode::kLoadStackPointer: | 2538 case IrOpcode::kLoadStackPointer: |
2528 case IrOpcode::kLoadFramePointer: | 2539 case IrOpcode::kLoadFramePointer: |
2529 case IrOpcode::kLoadParentFramePointer: | 2540 case IrOpcode::kLoadParentFramePointer: |
2530 return VisitLeaf(node, MachineType::PointerRepresentation()); | 2541 return VisitLeaf(node, MachineType::PointerRepresentation()); |
2531 case IrOpcode::kStateValues: | 2542 case IrOpcode::kStateValues: |
2532 return VisitStateValues(node); | 2543 return VisitStateValues(node); |
| 2544 case IrOpcode::kTypeGuard: { |
| 2545 // We just get rid of the sigma here. In principle, it should be |
| 2546 // possible to refine the truncation and representation based on |
| 2547 // the sigma's type. |
| 2548 MachineRepresentation output = |
| 2549 GetOutputInfoForPhi(node, TypeOf(node->InputAt(0)), truncation); |
| 2550 |
| 2551 VisitUnop(node, UseInfo(output, truncation), output); |
| 2552 if (lower()) DeferReplacement(node, node->InputAt(0)); |
| 2553 return; |
| 2554 } |
2533 | 2555 |
2534 // The following opcodes are not produced before representation | 2556 // The following opcodes are not produced before representation |
2535 // inference runs, so we do not have any real test coverage. | 2557 // inference runs, so we do not have any real test coverage. |
2536 // Simply fail here. | 2558 // Simply fail here. |
2537 case IrOpcode::kChangeFloat64ToInt32: | 2559 case IrOpcode::kChangeFloat64ToInt32: |
2538 case IrOpcode::kChangeFloat64ToUint32: | 2560 case IrOpcode::kChangeFloat64ToUint32: |
2539 case IrOpcode::kTruncateInt64ToInt32: | 2561 case IrOpcode::kTruncateInt64ToInt32: |
2540 case IrOpcode::kChangeFloat32ToFloat64: | 2562 case IrOpcode::kChangeFloat32ToFloat64: |
2541 case IrOpcode::kCheckedInt32Add: | 2563 case IrOpcode::kCheckedInt32Add: |
2542 case IrOpcode::kCheckedInt32Sub: | 2564 case IrOpcode::kCheckedInt32Sub: |
(...skipping 22 matching lines...) Expand all Loading... |
2565 node->op()->mnemonic(), replacement->id(), | 2587 node->op()->mnemonic(), replacement->id(), |
2566 replacement->op()->mnemonic()); | 2588 replacement->op()->mnemonic()); |
2567 | 2589 |
2568 // Disconnect the node from effect and control chains, if necessary. | 2590 // Disconnect the node from effect and control chains, if necessary. |
2569 if (node->op()->EffectInputCount() > 0) { | 2591 if (node->op()->EffectInputCount() > 0) { |
2570 DCHECK_LT(0, node->op()->ControlInputCount()); | 2592 DCHECK_LT(0, node->op()->ControlInputCount()); |
2571 // Disconnect the node from effect and control chains. | 2593 // Disconnect the node from effect and control chains. |
2572 Node* control = NodeProperties::GetControlInput(node); | 2594 Node* control = NodeProperties::GetControlInput(node); |
2573 Node* effect = NodeProperties::GetEffectInput(node); | 2595 Node* effect = NodeProperties::GetEffectInput(node); |
2574 ReplaceEffectControlUses(node, effect, control); | 2596 ReplaceEffectControlUses(node, effect, control); |
2575 } else { | |
2576 DCHECK_EQ(0, node->op()->ControlInputCount()); | |
2577 } | 2597 } |
2578 | 2598 |
2579 replacements_.push_back(node); | 2599 replacements_.push_back(node); |
2580 replacements_.push_back(replacement); | 2600 replacements_.push_back(replacement); |
2581 | 2601 |
2582 node->NullAllInputs(); // Node is now dead. | 2602 node->NullAllInputs(); // Node is now dead. |
2583 } | 2603 } |
2584 | 2604 |
2585 void Kill(Node* node) { | 2605 void Kill(Node* node) { |
2586 TRACE("killing #%d:%s\n", node->id(), node->op()->mnemonic()); | 2606 TRACE("killing #%d:%s\n", node->id(), node->op()->mnemonic()); |
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3287 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3307 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
3288 Operator::kNoProperties); | 3308 Operator::kNoProperties); |
3289 to_number_operator_.set(common()->Call(desc)); | 3309 to_number_operator_.set(common()->Call(desc)); |
3290 } | 3310 } |
3291 return to_number_operator_.get(); | 3311 return to_number_operator_.get(); |
3292 } | 3312 } |
3293 | 3313 |
3294 } // namespace compiler | 3314 } // namespace compiler |
3295 } // namespace internal | 3315 } // namespace internal |
3296 } // namespace v8 | 3316 } // namespace v8 |
OLD | NEW |