Chromium Code Reviews| 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 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 417 } | 417 } |
| 418 | 418 |
| 419 case IrOpcode::kPhi: { | 419 case IrOpcode::kPhi: { |
| 420 new_type = TypePhi(node); | 420 new_type = TypePhi(node); |
| 421 if (type != nullptr) { | 421 if (type != nullptr) { |
| 422 new_type = Weaken(node, type, new_type); | 422 new_type = Weaken(node, type, new_type); |
| 423 } | 423 } |
| 424 break; | 424 break; |
| 425 } | 425 } |
| 426 | 426 |
| 427 case IrOpcode::kSigma: { | |
| 428 new_type = | |
| 429 op_typer_.TypeSigma(node->op(), FeedbackTypeOf(node->InputAt(0))); | |
| 430 break; | |
| 431 } | |
| 432 | |
| 427 case IrOpcode::kSelect: { | 433 case IrOpcode::kSelect: { |
| 428 new_type = TypeSelect(node); | 434 new_type = TypeSelect(node); |
| 429 break; | 435 break; |
| 430 } | 436 } |
| 431 | 437 |
| 432 default: | 438 default: |
| 433 // Shortcut for operations that we do not handle. | 439 // Shortcut for operations that we do not handle. |
| 434 if (type == nullptr) { | 440 if (type == nullptr) { |
| 435 GetInfo(node)->set_feedback_type(NodeProperties::GetType(node)); | 441 GetInfo(node)->set_feedback_type(NodeProperties::GetType(node)); |
| 436 return true; | 442 return true; |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 804 VisitBinop(node, UseInfo::TruncatingWord32(), MachineRepresentation::kBit); | 810 VisitBinop(node, UseInfo::TruncatingWord32(), MachineRepresentation::kBit); |
| 805 } | 811 } |
| 806 void VisitInt64Cmp(Node* node) { | 812 void VisitInt64Cmp(Node* node) { |
| 807 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit); | 813 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit); |
| 808 } | 814 } |
| 809 void VisitUint64Cmp(Node* node) { | 815 void VisitUint64Cmp(Node* node) { |
| 810 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit); | 816 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit); |
| 811 } | 817 } |
| 812 | 818 |
| 813 // Infer representation for phi-like nodes. | 819 // Infer representation for phi-like nodes. |
| 814 MachineRepresentation GetOutputInfoForPhi(Node* node, Truncation use) { | 820 // The {node} parameter is only used to decide on the int64 representation. |
| 821 // Once the type system supports an external pointer type, the {node} | |
| 822 // parameter can be removed. | |
| 823 MachineRepresentation GetOutputInfoForPhi(Node* node, Type* type, | |
| 824 Truncation use) { | |
| 815 // Compute the representation. | 825 // Compute the representation. |
| 816 Type* type = TypeOf(node); | |
| 817 if (type->Is(Type::None())) { | 826 if (type->Is(Type::None())) { |
| 818 return MachineRepresentation::kNone; | 827 return MachineRepresentation::kNone; |
| 819 } else if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) { | 828 } else if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) { |
| 820 return MachineRepresentation::kWord32; | 829 return MachineRepresentation::kWord32; |
| 821 } else if (use.IsUsedAsWord32()) { | 830 } else if (use.IsUsedAsWord32()) { |
| 822 return MachineRepresentation::kWord32; | 831 return MachineRepresentation::kWord32; |
| 823 } else if (type->Is(Type::Boolean())) { | 832 } else if (type->Is(Type::Boolean())) { |
| 824 return MachineRepresentation::kBit; | 833 return MachineRepresentation::kBit; |
| 825 } else if (use.IsUsedAsFloat64()) { | 834 } else if (use.IsUsedAsFloat64()) { |
| 826 return MachineRepresentation::kFloat64; | 835 return MachineRepresentation::kFloat64; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 853 : MachineRepresentation::kTagged; | 862 : MachineRepresentation::kTagged; |
| 854 } | 863 } |
| 855 return MachineRepresentation::kTagged; | 864 return MachineRepresentation::kTagged; |
| 856 } | 865 } |
| 857 | 866 |
| 858 // Helper for handling selects. | 867 // Helper for handling selects. |
| 859 void VisitSelect(Node* node, Truncation truncation, | 868 void VisitSelect(Node* node, Truncation truncation, |
| 860 SimplifiedLowering* lowering) { | 869 SimplifiedLowering* lowering) { |
| 861 ProcessInput(node, 0, UseInfo::Bool()); | 870 ProcessInput(node, 0, UseInfo::Bool()); |
| 862 | 871 |
| 863 MachineRepresentation output = GetOutputInfoForPhi(node, truncation); | 872 MachineRepresentation output = |
| 873 GetOutputInfoForPhi(node, TypeOf(node), truncation); | |
| 864 SetOutput(node, output); | 874 SetOutput(node, output); |
| 865 | 875 |
| 866 if (lower()) { | 876 if (lower()) { |
| 867 // Update the select operator. | 877 // Update the select operator. |
| 868 SelectParameters p = SelectParametersOf(node->op()); | 878 SelectParameters p = SelectParametersOf(node->op()); |
| 869 if (output != p.representation()) { | 879 if (output != p.representation()) { |
| 870 NodeProperties::ChangeOp(node, | 880 NodeProperties::ChangeOp(node, |
| 871 lowering->common()->Select(output, p.hint())); | 881 lowering->common()->Select(output, p.hint())); |
| 872 } | 882 } |
| 873 } | 883 } |
| 874 // Convert inputs to the output representation of this phi, pass the | 884 // Convert inputs to the output representation of this phi, pass the |
| 875 // truncation truncation along. | 885 // truncation truncation along. |
| 876 UseInfo input_use(output, truncation); | 886 UseInfo input_use(output, truncation); |
| 877 ProcessInput(node, 1, input_use); | 887 ProcessInput(node, 1, input_use); |
| 878 ProcessInput(node, 2, input_use); | 888 ProcessInput(node, 2, input_use); |
| 879 } | 889 } |
| 880 | 890 |
| 881 // Helper for handling phis. | 891 // Helper for handling phis. |
| 882 void VisitPhi(Node* node, Truncation truncation, | 892 void VisitPhi(Node* node, Truncation truncation, |
| 883 SimplifiedLowering* lowering) { | 893 SimplifiedLowering* lowering) { |
| 884 MachineRepresentation output = GetOutputInfoForPhi(node, truncation); | 894 MachineRepresentation output = |
| 895 GetOutputInfoForPhi(node, TypeOf(node), truncation); | |
| 885 // Only set the output representation if not running with type | 896 // Only set the output representation if not running with type |
| 886 // feedback. (Feedback typing will set the representation.) | 897 // feedback. (Feedback typing will set the representation.) |
| 887 SetOutput(node, output); | 898 SetOutput(node, output); |
| 888 | 899 |
| 889 int values = node->op()->ValueInputCount(); | 900 int values = node->op()->ValueInputCount(); |
| 890 if (lower()) { | 901 if (lower()) { |
| 891 // Update the phi operator. | 902 // Update the phi operator. |
| 892 if (output != PhiRepresentationOf(node->op())) { | 903 if (output != PhiRepresentationOf(node->op())) { |
| 893 NodeProperties::ChangeOp(node, lowering->common()->Phi(output, values)); | 904 NodeProperties::ChangeOp(node, lowering->common()->Phi(output, values)); |
| 894 } | 905 } |
| 895 } | 906 } |
| 896 | 907 |
| 897 // Convert inputs to the output representation of this phi, pass the | 908 // Convert inputs to the output representation of this phi, pass the |
| 898 // truncation truncation along. | 909 // truncation along. |
| 899 UseInfo input_use(output, truncation); | 910 UseInfo input_use(output, truncation); |
| 900 for (int i = 0; i < node->InputCount(); i++) { | 911 for (int i = 0; i < node->InputCount(); i++) { |
| 901 ProcessInput(node, i, i < values ? input_use : UseInfo::None()); | 912 ProcessInput(node, i, i < values ? input_use : UseInfo::None()); |
| 902 } | 913 } |
| 903 } | 914 } |
| 904 | 915 |
| 905 void VisitCall(Node* node, SimplifiedLowering* lowering) { | 916 void VisitCall(Node* node, SimplifiedLowering* lowering) { |
| 906 const CallDescriptor* desc = CallDescriptorOf(node->op()); | 917 const CallDescriptor* desc = CallDescriptorOf(node->op()); |
| 907 int params = static_cast<int>(desc->ParameterCount()); | 918 int params = static_cast<int>(desc->ParameterCount()); |
| 908 int value_input_count = node->op()->ValueInputCount(); | 919 int value_input_count = node->op()->ValueInputCount(); |
| (...skipping 1528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2437 VisitUnop(node, UseInfo::TruncatingFloat64(), | 2448 VisitUnop(node, UseInfo::TruncatingFloat64(), |
| 2438 MachineRepresentation::kFloat64); | 2449 MachineRepresentation::kFloat64); |
| 2439 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); | 2450 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
| 2440 return; | 2451 return; |
| 2441 case IrOpcode::kLoadStackPointer: | 2452 case IrOpcode::kLoadStackPointer: |
| 2442 case IrOpcode::kLoadFramePointer: | 2453 case IrOpcode::kLoadFramePointer: |
| 2443 case IrOpcode::kLoadParentFramePointer: | 2454 case IrOpcode::kLoadParentFramePointer: |
| 2444 return VisitLeaf(node, MachineType::PointerRepresentation()); | 2455 return VisitLeaf(node, MachineType::PointerRepresentation()); |
| 2445 case IrOpcode::kStateValues: | 2456 case IrOpcode::kStateValues: |
| 2446 return VisitStateValues(node); | 2457 return VisitStateValues(node); |
| 2458 case IrOpcode::kSigma: { | |
| 2459 // We just get rid of the sigma here. In principle, it should be | |
| 2460 // possible to refine the truncation and representation based on | |
| 2461 // the sigma's type. | |
| 2462 MachineRepresentation output = | |
| 2463 GetOutputInfoForPhi(node, TypeOf(node->InputAt(0)), truncation); | |
| 2464 | |
| 2465 ProcessInput(node, 0, UseInfo(output, truncation)); | |
| 2466 ProcessInput(node, 1, UseInfo::None()); | |
|
Benedikt Meurer
2016/08/05 12:54:20
Nit: You could use VisitUnop here.
| |
| 2467 | |
| 2468 SetOutput(node, output); | |
| 2469 if (lower()) DeferReplacement(node, node->InputAt(0)); | |
| 2470 return; | |
| 2471 } | |
| 2447 | 2472 |
| 2448 // The following opcodes are not produced before representation | 2473 // The following opcodes are not produced before representation |
| 2449 // inference runs, so we do not have any real test coverage. | 2474 // inference runs, so we do not have any real test coverage. |
| 2450 // Simply fail here. | 2475 // Simply fail here. |
| 2451 case IrOpcode::kChangeFloat64ToInt32: | 2476 case IrOpcode::kChangeFloat64ToInt32: |
| 2452 case IrOpcode::kChangeFloat64ToUint32: | 2477 case IrOpcode::kChangeFloat64ToUint32: |
| 2453 case IrOpcode::kTruncateInt64ToInt32: | 2478 case IrOpcode::kTruncateInt64ToInt32: |
| 2454 case IrOpcode::kChangeFloat32ToFloat64: | 2479 case IrOpcode::kChangeFloat32ToFloat64: |
| 2455 case IrOpcode::kCheckedInt32Add: | 2480 case IrOpcode::kCheckedInt32Add: |
| 2456 case IrOpcode::kCheckedInt32Sub: | 2481 case IrOpcode::kCheckedInt32Sub: |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 2479 node->op()->mnemonic(), replacement->id(), | 2504 node->op()->mnemonic(), replacement->id(), |
| 2480 replacement->op()->mnemonic()); | 2505 replacement->op()->mnemonic()); |
| 2481 | 2506 |
| 2482 // Disconnect the node from effect and control chains, if necessary. | 2507 // Disconnect the node from effect and control chains, if necessary. |
| 2483 if (node->op()->EffectInputCount() > 0) { | 2508 if (node->op()->EffectInputCount() > 0) { |
| 2484 DCHECK_LT(0, node->op()->ControlInputCount()); | 2509 DCHECK_LT(0, node->op()->ControlInputCount()); |
| 2485 // Disconnect the node from effect and control chains. | 2510 // Disconnect the node from effect and control chains. |
| 2486 Node* control = NodeProperties::GetControlInput(node); | 2511 Node* control = NodeProperties::GetControlInput(node); |
| 2487 Node* effect = NodeProperties::GetEffectInput(node); | 2512 Node* effect = NodeProperties::GetEffectInput(node); |
| 2488 ReplaceEffectControlUses(node, effect, control); | 2513 ReplaceEffectControlUses(node, effect, control); |
| 2489 } else { | |
| 2490 DCHECK_EQ(0, node->op()->ControlInputCount()); | |
| 2491 } | 2514 } |
| 2492 | 2515 |
| 2493 replacements_.push_back(node); | 2516 replacements_.push_back(node); |
| 2494 replacements_.push_back(replacement); | 2517 replacements_.push_back(replacement); |
| 2495 | 2518 |
| 2496 node->NullAllInputs(); // Node is now dead. | 2519 node->NullAllInputs(); // Node is now dead. |
| 2497 } | 2520 } |
| 2498 | 2521 |
| 2499 void Kill(Node* node) { | 2522 void Kill(Node* node) { |
| 2500 TRACE("killing #%d:%s\n", node->id(), node->op()->mnemonic()); | 2523 TRACE("killing #%d:%s\n", node->id(), node->op()->mnemonic()); |
| (...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3572 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3595 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
| 3573 Operator::kNoProperties); | 3596 Operator::kNoProperties); |
| 3574 to_number_operator_.set(common()->Call(desc)); | 3597 to_number_operator_.set(common()->Call(desc)); |
| 3575 } | 3598 } |
| 3576 return to_number_operator_.get(); | 3599 return to_number_operator_.get(); |
| 3577 } | 3600 } |
| 3578 | 3601 |
| 3579 } // namespace compiler | 3602 } // namespace compiler |
| 3580 } // namespace internal | 3603 } // namespace internal |
| 3581 } // namespace v8 | 3604 } // namespace v8 |
| OLD | NEW |