| 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 |