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/js-call-reducer.h" | 5 #include "src/compiler/js-call-reducer.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
10 #include "src/compiler/access-builder.h" | 10 #include "src/compiler/access-builder.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 case IrOpcode::kJSCallWithArrayLike: | 33 case IrOpcode::kJSCallWithArrayLike: |
34 return ReduceJSCallWithArrayLike(node); | 34 return ReduceJSCallWithArrayLike(node); |
35 case IrOpcode::kJSCallWithSpread: | 35 case IrOpcode::kJSCallWithSpread: |
36 return ReduceJSCallWithSpread(node); | 36 return ReduceJSCallWithSpread(node); |
37 default: | 37 default: |
38 break; | 38 break; |
39 } | 39 } |
40 return NoChange(); | 40 return NoChange(); |
41 } | 41 } |
42 | 42 |
| 43 void JSCallReducer::Finalize() { |
| 44 std::set<Node*> const waitlist = std::move(waitlist_); |
| 45 for (Node* node : waitlist) { |
| 46 if (!node->IsDead()) { |
| 47 Reduction const reduction = Reduce(node); |
| 48 if (reduction.Changed()) { |
| 49 Node* replacement = reduction.replacement(); |
| 50 if (replacement != node) { |
| 51 Replace(node, replacement); |
| 52 } |
| 53 } |
| 54 } |
| 55 } |
| 56 } |
43 | 57 |
44 // ES6 section 22.1.1 The Array Constructor | 58 // ES6 section 22.1.1 The Array Constructor |
45 Reduction JSCallReducer::ReduceArrayConstructor(Node* node) { | 59 Reduction JSCallReducer::ReduceArrayConstructor(Node* node) { |
46 DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); | 60 DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); |
47 Node* target = NodeProperties::GetValueInput(node, 0); | 61 Node* target = NodeProperties::GetValueInput(node, 0); |
48 CallParameters const& p = CallParametersOf(node->op()); | 62 CallParameters const& p = CallParametersOf(node->op()); |
49 | 63 |
50 // Check if we have an allocation site from the CallIC. | 64 // Check if we have an allocation site from the CallIC. |
51 Handle<AllocationSite> site; | 65 Handle<AllocationSite> site; |
52 if (p.feedback().IsValid()) { | 66 if (p.feedback().IsValid()) { |
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
700 !isolate()->initial_array_iterator_prototype_map()->is_stable()) { | 714 !isolate()->initial_array_iterator_prototype_map()->is_stable()) { |
701 return NoChange(); | 715 return NoChange(); |
702 } | 716 } |
703 | 717 |
704 // Check if {arguments_list} is an arguments object, and {node} is the only | 718 // Check if {arguments_list} is an arguments object, and {node} is the only |
705 // value user of {arguments_list} (except for value uses in frame states). | 719 // value user of {arguments_list} (except for value uses in frame states). |
706 Node* arguments_list = NodeProperties::GetValueInput(node, arity); | 720 Node* arguments_list = NodeProperties::GetValueInput(node, arity); |
707 if (arguments_list->opcode() != IrOpcode::kJSCreateArguments) | 721 if (arguments_list->opcode() != IrOpcode::kJSCreateArguments) |
708 return NoChange(); | 722 return NoChange(); |
709 for (Edge edge : arguments_list->use_edges()) { | 723 for (Edge edge : arguments_list->use_edges()) { |
| 724 if (!NodeProperties::IsValueEdge(edge)) continue; |
710 Node* const user = edge.from(); | 725 Node* const user = edge.from(); |
711 if (user == node) continue; | 726 switch (user->opcode()) { |
712 // Ignore uses as frame state's locals or parameters. | 727 case IrOpcode::kStateValues: |
713 if (user->opcode() == IrOpcode::kStateValues) continue; | 728 // Ignore uses as frame state's locals or parameters. |
714 // Ignore uses as frame state's accumulator. | 729 continue; |
715 if (user->opcode() == IrOpcode::kFrameState && | 730 case IrOpcode::kFrameState: |
716 user->InputAt(2) == arguments_list) { | 731 // Ignore uses as frame state's accumulator. |
717 continue; | 732 if (user->InputAt(2) == arguments_list) continue; |
| 733 break; |
| 734 case IrOpcode::kReferenceEqual: |
| 735 // Ignore uses for comparisons. |
| 736 continue; |
| 737 case IrOpcode::kJSCallWithArrayLike: |
| 738 // Ignore uses as argumentsList input to calls with array like. |
| 739 if (user->InputAt(2) == arguments_list) continue; |
| 740 break; |
| 741 case IrOpcode::kJSCallWithSpread: { |
| 742 // Ignore uses as spread input to calls with spread. |
| 743 SpreadWithArityParameter p = SpreadWithArityParameterOf(user->op()); |
| 744 int const arity = static_cast<int>(p.arity() - 1); |
| 745 if (user->InputAt(arity) == arguments_list) continue; |
| 746 break; |
| 747 } |
| 748 case IrOpcode::kJSConstructWithSpread: { |
| 749 // Ignore uses as spread input to construct with spread. |
| 750 SpreadWithArityParameter p = SpreadWithArityParameterOf(user->op()); |
| 751 int const arity = static_cast<int>(p.arity() - 2); |
| 752 if (user->InputAt(arity) == arguments_list) continue; |
| 753 break; |
| 754 } |
| 755 default: |
| 756 break; |
718 } | 757 } |
719 if (!NodeProperties::IsValueEdge(edge)) continue; | 758 // We currently reduce the {node} to something better than what |
| 759 // it already is, but we might be able to do something about the |
| 760 // {node} later, so put it onto the waitlist and try again during |
| 761 // the finalization phase. |
| 762 waitlist_.insert(node); |
720 return NoChange(); | 763 return NoChange(); |
721 } | 764 } |
722 | 765 |
723 // Get to the actual frame state from which to extract the arguments; | 766 // Get to the actual frame state from which to extract the arguments; |
724 // we can only optimize this in case the {node} was already inlined into | 767 // we can only optimize this in case the {node} was already inlined into |
725 // some other function (and same for the {arguments_list}). | 768 // some other function (and same for the {arguments_list}). |
726 CreateArgumentsType const type = CreateArgumentsTypeOf(arguments_list->op()); | 769 CreateArgumentsType const type = CreateArgumentsTypeOf(arguments_list->op()); |
727 Node* frame_state = NodeProperties::GetFrameStateInput(arguments_list); | 770 Node* frame_state = NodeProperties::GetFrameStateInput(arguments_list); |
728 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); | 771 FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state); |
729 int start_index = 0; | 772 int start_index = 0; |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1191 return jsgraph()->javascript(); | 1234 return jsgraph()->javascript(); |
1192 } | 1235 } |
1193 | 1236 |
1194 SimplifiedOperatorBuilder* JSCallReducer::simplified() const { | 1237 SimplifiedOperatorBuilder* JSCallReducer::simplified() const { |
1195 return jsgraph()->simplified(); | 1238 return jsgraph()->simplified(); |
1196 } | 1239 } |
1197 | 1240 |
1198 } // namespace compiler | 1241 } // namespace compiler |
1199 } // namespace internal | 1242 } // namespace internal |
1200 } // namespace v8 | 1243 } // namespace v8 |
OLD | NEW |