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