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/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/code-stubs.h" | 6 #include "src/code-stubs.h" |
7 #include "src/compiler/common-operator.h" | 7 #include "src/compiler/common-operator.h" |
8 #include "src/compiler/js-generic-lowering.h" | 8 #include "src/compiler/js-generic-lowering.h" |
9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
10 #include "src/compiler/machine-operator.h" | 10 #include "src/compiler/machine-operator.h" |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 case Token::GTE: // a >= 0 becomes !(a < 0) | 188 case Token::GTE: // a >= 0 becomes !(a < 0) |
189 op = machine()->IntLessThan(); | 189 op = machine()->IntLessThan(); |
190 std::swap(true_value, false_value); | 190 std::swap(true_value, false_value); |
191 break; | 191 break; |
192 default: | 192 default: |
193 UNREACHABLE(); | 193 UNREACHABLE(); |
194 } | 194 } |
195 Node* booleanize = graph()->NewNode(op, compare, jsgraph()->ZeroConstant()); | 195 Node* booleanize = graph()->NewNode(op, compare, jsgraph()->ZeroConstant()); |
196 | 196 |
197 // Finally patch the original node to select a boolean. | 197 // Finally patch the original node to select a boolean. |
198 NodeProperties::ReplaceWithValue(node, node, compare); | 198 NodeProperties::ReplaceUses(node, node, compare, compare, compare); |
199 // TODO(mstarzinger): Just a work-around because SelectLowering might | 199 // TODO(mstarzinger): Just a work-around because SelectLowering might |
200 // otherwise introduce a Phi without any uses, making Scheduler unhappy. | 200 // otherwise introduce a Phi without any uses, making Scheduler unhappy. |
201 if (node->UseCount() == 0) return; | 201 if (node->UseCount() == 0) return; |
202 node->TrimInputCount(3); | 202 node->TrimInputCount(3); |
203 node->ReplaceInput(0, booleanize); | 203 node->ReplaceInput(0, booleanize); |
204 node->ReplaceInput(1, true_value); | 204 node->ReplaceInput(1, true_value); |
205 node->ReplaceInput(2, false_value); | 205 node->ReplaceInput(2, false_value); |
206 node->set_op(common()->Select(kMachAnyTagged)); | 206 node->set_op(common()->Select(kMachAnyTagged)); |
207 } | 207 } |
208 | 208 |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 machine()->Store(StoreRepresentation(kMachAnyTagged, kFullWriteBarrier))); | 442 machine()->Store(StoreRepresentation(kMachAnyTagged, kFullWriteBarrier))); |
443 } | 443 } |
444 | 444 |
445 | 445 |
446 void JSGenericLowering::LowerJSLoadDynamicGlobal(Node* node) { | 446 void JSGenericLowering::LowerJSLoadDynamicGlobal(Node* node) { |
447 const DynamicGlobalAccess& access = DynamicGlobalAccessOf(node->op()); | 447 const DynamicGlobalAccess& access = DynamicGlobalAccessOf(node->op()); |
448 Runtime::FunctionId function_id = | 448 Runtime::FunctionId function_id = |
449 (access.mode() == CONTEXTUAL) ? Runtime::kLoadLookupSlot | 449 (access.mode() == CONTEXTUAL) ? Runtime::kLoadLookupSlot |
450 : Runtime::kLoadLookupSlotNoReferenceError; | 450 : Runtime::kLoadLookupSlotNoReferenceError; |
451 Node* projection = graph()->NewNode(common()->Projection(0), node); | 451 Node* projection = graph()->NewNode(common()->Projection(0), node); |
452 NodeProperties::ReplaceWithValue(node, projection, node, node); | 452 NodeProperties::ReplaceUses(node, projection, node, node, node); |
453 node->RemoveInput(NodeProperties::FirstFrameStateIndex(node) + 1); | 453 node->RemoveInput(NodeProperties::FirstFrameStateIndex(node) + 1); |
454 node->RemoveInput(NodeProperties::FirstValueIndex(node)); | 454 node->RemoveInput(NodeProperties::FirstValueIndex(node)); |
455 node->InsertInput(zone(), 1, jsgraph()->Constant(access.name())); | 455 node->InsertInput(zone(), 1, jsgraph()->Constant(access.name())); |
456 ReplaceWithRuntimeCall(node, function_id); | 456 ReplaceWithRuntimeCall(node, function_id); |
457 projection->ReplaceInput(0, node); | 457 projection->ReplaceInput(0, node); |
458 } | 458 } |
459 | 459 |
460 | 460 |
461 void JSGenericLowering::LowerJSLoadDynamicContext(Node* node) { | 461 void JSGenericLowering::LowerJSLoadDynamicContext(Node* node) { |
462 const DynamicContextAccess& access = DynamicContextAccessOf(node->op()); | 462 const DynamicContextAccess& access = DynamicContextAccessOf(node->op()); |
463 Node* projection = graph()->NewNode(common()->Projection(0), node); | 463 Node* projection = graph()->NewNode(common()->Projection(0), node); |
464 NodeProperties::ReplaceWithValue(node, projection, node, node); | 464 NodeProperties::ReplaceUses(node, projection, node, node, node); |
465 node->InsertInput(zone(), 1, jsgraph()->Constant(access.name())); | 465 node->InsertInput(zone(), 1, jsgraph()->Constant(access.name())); |
466 ReplaceWithRuntimeCall(node, Runtime::kLoadLookupSlot); | 466 ReplaceWithRuntimeCall(node, Runtime::kLoadLookupSlot); |
467 projection->ReplaceInput(0, node); | 467 projection->ReplaceInput(0, node); |
468 } | 468 } |
469 | 469 |
470 | 470 |
471 void JSGenericLowering::LowerJSCreateClosure(Node* node) { | 471 void JSGenericLowering::LowerJSCreateClosure(Node* node) { |
472 CreateClosureParameters p = CreateClosureParametersOf(node->op()); | 472 CreateClosureParameters p = CreateClosureParametersOf(node->op()); |
473 node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.shared_info())); | 473 node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.shared_info())); |
474 node->InsertInput(zone(), 2, jsgraph()->BooleanConstant(p.pretenure())); | 474 node->InsertInput(zone(), 2, jsgraph()->BooleanConstant(p.pretenure())); |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), cache_length_true0, | 741 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), cache_length_true0, |
742 cache_length_false0, control); | 742 cache_length_false0, control); |
743 cache_type = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), | 743 cache_type = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), |
744 cache_type_true0, cache_type_false0, control); | 744 cache_type_true0, cache_type_false0, control); |
745 | 745 |
746 for (auto edge : node->use_edges()) { | 746 for (auto edge : node->use_edges()) { |
747 if (NodeProperties::IsEffectEdge(edge)) { | 747 if (NodeProperties::IsEffectEdge(edge)) { |
748 edge.UpdateTo(effect); | 748 edge.UpdateTo(effect); |
749 } else if (NodeProperties::IsControlEdge(edge)) { | 749 } else if (NodeProperties::IsControlEdge(edge)) { |
750 Node* const use = edge.from(); | 750 Node* const use = edge.from(); |
751 DCHECK_EQ(IrOpcode::kIfSuccess, use->opcode()); | 751 if (use->opcode() == IrOpcode::kIfSuccess) { |
752 use->ReplaceUses(control); | 752 use->ReplaceUses(control); |
753 use->Kill(); | 753 use->Kill(); |
| 754 } else if (use->opcode() == IrOpcode::kIfException) { |
| 755 edge.UpdateTo(cache_type_true0); |
| 756 } else { |
| 757 UNREACHABLE(); |
| 758 } |
754 } else { | 759 } else { |
755 Node* const use = edge.from(); | 760 Node* const use = edge.from(); |
756 DCHECK(NodeProperties::IsValueEdge(edge)); | 761 DCHECK(NodeProperties::IsValueEdge(edge)); |
757 DCHECK_EQ(IrOpcode::kProjection, use->opcode()); | 762 DCHECK_EQ(IrOpcode::kProjection, use->opcode()); |
758 switch (ProjectionIndexOf(use->op())) { | 763 switch (ProjectionIndexOf(use->op())) { |
759 case 0: | 764 case 0: |
760 use->ReplaceUses(cache_type); | 765 use->ReplaceUses(cache_type); |
761 break; | 766 break; |
762 case 1: | 767 case 1: |
763 use->ReplaceUses(cache_array); | 768 use->ReplaceUses(cache_array); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
798 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 803 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
799 Node* etrue = effect; | 804 Node* etrue = effect; |
800 | 805 |
801 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 806 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
802 NodeProperties::ReplaceControlInput(node, if_false); | 807 NodeProperties::ReplaceControlInput(node, if_false); |
803 Node* efalse = node; | 808 Node* efalse = node; |
804 | 809 |
805 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); | 810 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); |
806 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge); | 811 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge); |
807 | 812 |
808 // Relax controls of {node}, i.e. make it free floating. | 813 // Wire the new diamond into the graph, {node} can still throw. |
809 NodeProperties::ReplaceWithValue(node, node, ephi, merge); | 814 NodeProperties::ReplaceUses(node, node, ephi, node, node); |
810 NodeProperties::ReplaceEffectInput(ephi, efalse, 1); | 815 NodeProperties::ReplaceEffectInput(ephi, efalse, 1); |
811 | 816 |
| 817 // TODO(mstarzinger): This iteration cuts out the IfSuccess projection from |
| 818 // the node and places it inside the diamond. Come up with a helper method! |
| 819 for (Node* use : node->uses()) { |
| 820 if (use->opcode() == IrOpcode::kIfSuccess) { |
| 821 use->ReplaceUses(merge); |
| 822 merge->ReplaceInput(1, use); |
| 823 } |
| 824 } |
| 825 |
812 // Turn the stack check into a runtime call. | 826 // Turn the stack check into a runtime call. |
813 ReplaceWithRuntimeCall(node, Runtime::kStackGuard); | 827 ReplaceWithRuntimeCall(node, Runtime::kStackGuard); |
814 } | 828 } |
815 | 829 |
816 | 830 |
817 Zone* JSGenericLowering::zone() const { return graph()->zone(); } | 831 Zone* JSGenericLowering::zone() const { return graph()->zone(); } |
818 | 832 |
819 | 833 |
820 Isolate* JSGenericLowering::isolate() const { return jsgraph()->isolate(); } | 834 Isolate* JSGenericLowering::isolate() const { return jsgraph()->isolate(); } |
821 | 835 |
822 | 836 |
823 Graph* JSGenericLowering::graph() const { return jsgraph()->graph(); } | 837 Graph* JSGenericLowering::graph() const { return jsgraph()->graph(); } |
824 | 838 |
825 | 839 |
826 CommonOperatorBuilder* JSGenericLowering::common() const { | 840 CommonOperatorBuilder* JSGenericLowering::common() const { |
827 return jsgraph()->common(); | 841 return jsgraph()->common(); |
828 } | 842 } |
829 | 843 |
830 | 844 |
831 MachineOperatorBuilder* JSGenericLowering::machine() const { | 845 MachineOperatorBuilder* JSGenericLowering::machine() const { |
832 return jsgraph()->machine(); | 846 return jsgraph()->machine(); |
833 } | 847 } |
834 | 848 |
835 } // namespace compiler | 849 } // namespace compiler |
836 } // namespace internal | 850 } // namespace internal |
837 } // namespace v8 | 851 } // namespace v8 |
OLD | NEW |