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/access-builder.h" | 5 #include "src/compiler/access-builder.h" |
6 #include "src/compiler/graph-inl.h" | 6 #include "src/compiler/graph-inl.h" |
7 #include "src/compiler/js-graph.h" | 7 #include "src/compiler/js-graph.h" |
8 #include "src/compiler/js-typed-lowering.h" | 8 #include "src/compiler/js-typed-lowering.h" |
9 #include "src/compiler/node-aux-data-inl.h" | 9 #include "src/compiler/node-aux-data-inl.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 Node* n = graph()->NewNode(javascript()->ToString(), node, context(), | 191 Node* n = graph()->NewNode(javascript()->ToString(), node, context(), |
192 effect(), control()); | 192 effect(), control()); |
193 update_effect(n); | 193 update_effect(n); |
194 return n; | 194 return n; |
195 } | 195 } |
196 | 196 |
197 Node* ConvertToNumber(Node* node) { | 197 Node* ConvertToNumber(Node* node) { |
198 if (NodeProperties::GetBounds(node).upper->Is(Type::PlainPrimitive())) { | 198 if (NodeProperties::GetBounds(node).upper->Is(Type::PlainPrimitive())) { |
199 return lowering_->ConvertToNumber(node); | 199 return lowering_->ConvertToNumber(node); |
200 } | 200 } |
201 Node* n = graph()->NewNode(javascript()->ToNumber(), node, context(), | 201 // TODO(jarin) This ToNumber conversion can deoptimize, but we do not really |
202 effect(), control()); | 202 // have a frame state to deoptimize to. Either we provide such a frame state |
| 203 // or we exclude the values that could lead to deoptimization (e.g., by |
| 204 // triggering eager deopt if the value is not plain). |
| 205 Node* const n = FLAG_turbo_deoptimization |
| 206 ? graph()->NewNode( |
| 207 javascript()->ToNumber(), node, context(), |
| 208 jsgraph()->EmptyFrameState(), effect(), control()) |
| 209 : graph()->NewNode(javascript()->ToNumber(), node, |
| 210 context(), effect(), control()); |
203 update_effect(n); | 211 update_effect(n); |
204 return n; | 212 return n; |
205 } | 213 } |
206 | 214 |
207 Node* ConvertToUI32(Node* node, Signedness signedness) { | 215 Node* ConvertToUI32(Node* node, Signedness signedness) { |
208 // Avoid introducing too many eager NumberToXXnt32() operations. | 216 // Avoid introducing too many eager NumberToXXnt32() operations. |
209 node = ConvertToNumber(node); | 217 node = ConvertToNumber(node); |
210 Type* type = NodeProperties::GetBounds(node).upper; | 218 Type* type = NodeProperties::GetBounds(node).upper; |
211 if (signedness == kSigned) { | 219 if (signedness == kSigned) { |
212 if (!type->Is(Type::Signed32())) { | 220 if (!type->Is(Type::Signed32())) { |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 // does not require a context anyways, so it's safe to discard it | 625 // does not require a context anyways, so it's safe to discard it |
618 // here and pass the dummy context. | 626 // here and pass the dummy context. |
619 Node* const value = ConvertToNumber(input->InputAt(i)); | 627 Node* const value = ConvertToNumber(input->InputAt(i)); |
620 node->ReplaceInput(i, value); | 628 node->ReplaceInput(i, value); |
621 } | 629 } |
622 node->TrimInputCount(input_count); | 630 node->TrimInputCount(input_count); |
623 return Changed(node); | 631 return Changed(node); |
624 } | 632 } |
625 // Remember this conversion. | 633 // Remember this conversion. |
626 InsertConversion(node); | 634 InsertConversion(node); |
627 if (node->InputAt(1) != jsgraph()->NoContextConstant() || | 635 if (NodeProperties::GetContextInput(node) != |
628 node->InputAt(2) != graph()->start() || | 636 jsgraph()->NoContextConstant() || |
629 node->InputAt(3) != graph()->start()) { | 637 NodeProperties::GetEffectInput(node) != graph()->start() || |
| 638 NodeProperties::GetControlInput(node) != graph()->start()) { |
630 // JSToNumber(x:plain-primitive,context,effect,control) | 639 // JSToNumber(x:plain-primitive,context,effect,control) |
631 // => JSToNumber(x,no-context,start,start) | 640 // => JSToNumber(x,no-context,start,start) |
632 RelaxEffects(node); | 641 RelaxEffects(node); |
633 node->ReplaceInput(1, jsgraph()->NoContextConstant()); | 642 NodeProperties::ReplaceContextInput(node, jsgraph()->NoContextConstant()); |
634 node->ReplaceInput(2, graph()->start()); | 643 NodeProperties::ReplaceControlInput(node, graph()->start()); |
635 node->ReplaceInput(3, graph()->start()); | 644 NodeProperties::ReplaceEffectInput(node, graph()->start()); |
| 645 if (OperatorProperties::HasFrameStateInput(node->op())) { |
| 646 NodeProperties::ReplaceFrameStateInput(node, |
| 647 jsgraph()->EmptyFrameState()); |
| 648 } |
636 return Changed(node); | 649 return Changed(node); |
637 } | 650 } |
638 } | 651 } |
639 return NoChange(); | 652 return NoChange(); |
640 } | 653 } |
641 | 654 |
642 | 655 |
643 Reduction JSTypedLowering::ReduceJSToStringInput(Node* input) { | 656 Reduction JSTypedLowering::ReduceJSToStringInput(Node* input) { |
644 if (input->opcode() == IrOpcode::kJSToString) { | 657 if (input->opcode() == IrOpcode::kJSToString) { |
645 // Recursively try to reduce the input first. | 658 // Recursively try to reduce the input first. |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 Node* length = jsgraph()->Constant(byte_length); | 758 Node* length = jsgraph()->Constant(byte_length); |
746 Node* context = NodeProperties::GetContextInput(node); | 759 Node* context = NodeProperties::GetContextInput(node); |
747 Node* effect = NodeProperties::GetEffectInput(node); | 760 Node* effect = NodeProperties::GetEffectInput(node); |
748 Node* control = NodeProperties::GetControlInput(node); | 761 Node* control = NodeProperties::GetControlInput(node); |
749 // Convert to a number first. | 762 // Convert to a number first. |
750 if (!value_type->Is(Type::Number())) { | 763 if (!value_type->Is(Type::Number())) { |
751 Reduction number_reduction = ReduceJSToNumberInput(value); | 764 Reduction number_reduction = ReduceJSToNumberInput(value); |
752 if (number_reduction.Changed()) { | 765 if (number_reduction.Changed()) { |
753 value = number_reduction.replacement(); | 766 value = number_reduction.replacement(); |
754 } else { | 767 } else { |
755 value = effect = graph()->NewNode(javascript()->ToNumber(), value, | 768 if (OperatorProperties::HasFrameStateInput( |
756 context, effect, control); | 769 javascript()->ToNumber())) { |
| 770 value = effect = |
| 771 graph()->NewNode(javascript()->ToNumber(), value, context, |
| 772 jsgraph()->EmptyFrameState(), effect, control); |
| 773 } else { |
| 774 value = effect = graph()->NewNode(javascript()->ToNumber(), value, |
| 775 context, effect, control); |
| 776 } |
757 } | 777 } |
758 } | 778 } |
759 // For integer-typed arrays, convert to the integer type. | 779 // For integer-typed arrays, convert to the integer type. |
760 if (TypeOf(access.machine_type()) == kTypeInt32 && | 780 if (TypeOf(access.machine_type()) == kTypeInt32 && |
761 !value_type->Is(Type::Signed32())) { | 781 !value_type->Is(Type::Signed32())) { |
762 value = graph()->NewNode(simplified()->NumberToInt32(), value); | 782 value = graph()->NewNode(simplified()->NumberToInt32(), value); |
763 } else if (TypeOf(access.machine_type()) == kTypeUint32 && | 783 } else if (TypeOf(access.machine_type()) == kTypeUint32 && |
764 !value_type->Is(Type::Unsigned32())) { | 784 !value_type->Is(Type::Unsigned32())) { |
765 value = graph()->NewNode(simplified()->NumberToUint32(), value); | 785 value = graph()->NewNode(simplified()->NumberToUint32(), value); |
766 } | 786 } |
(...skipping 11 matching lines...) Expand all Loading... |
778 } | 798 } |
779 // Compute byte offset. | 799 // Compute byte offset. |
780 Node* offset = Word32Shl(key, static_cast<int>(k)); | 800 Node* offset = Word32Shl(key, static_cast<int>(k)); |
781 // Turn into a StoreBuffer operation. | 801 // Turn into a StoreBuffer operation. |
782 node->set_op(simplified()->StoreBuffer(access)); | 802 node->set_op(simplified()->StoreBuffer(access)); |
783 node->ReplaceInput(0, buffer); | 803 node->ReplaceInput(0, buffer); |
784 node->ReplaceInput(1, offset); | 804 node->ReplaceInput(1, offset); |
785 node->ReplaceInput(2, length); | 805 node->ReplaceInput(2, length); |
786 node->ReplaceInput(3, value); | 806 node->ReplaceInput(3, value); |
787 node->ReplaceInput(4, effect); | 807 node->ReplaceInput(4, effect); |
788 DCHECK_EQ(control, node->InputAt(5)); | 808 node->ReplaceInput(5, control); |
789 DCHECK_EQ(6, node->InputCount()); | 809 node->TrimInputCount(6); |
790 return Changed(node); | 810 return Changed(node); |
791 } | 811 } |
792 } | 812 } |
793 return NoChange(); | 813 return NoChange(); |
794 } | 814 } |
795 | 815 |
796 | 816 |
797 Reduction JSTypedLowering::ReduceJSLoadContext(Node* node) { | 817 Reduction JSTypedLowering::ReduceJSLoadContext(Node* node) { |
798 DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode()); | 818 DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode()); |
799 ContextAccess const& access = ContextAccessOf(node->op()); | 819 ContextAccess const& access = ContextAccessOf(node->op()); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
925 } | 945 } |
926 return NoChange(); | 946 return NoChange(); |
927 } | 947 } |
928 | 948 |
929 | 949 |
930 Node* JSTypedLowering::ConvertToNumber(Node* input) { | 950 Node* JSTypedLowering::ConvertToNumber(Node* input) { |
931 DCHECK(NodeProperties::GetBounds(input).upper->Is(Type::PlainPrimitive())); | 951 DCHECK(NodeProperties::GetBounds(input).upper->Is(Type::PlainPrimitive())); |
932 // Avoid inserting too many eager ToNumber() operations. | 952 // Avoid inserting too many eager ToNumber() operations. |
933 Reduction const reduction = ReduceJSToNumberInput(input); | 953 Reduction const reduction = ReduceJSToNumberInput(input); |
934 if (reduction.Changed()) return reduction.replacement(); | 954 if (reduction.Changed()) return reduction.replacement(); |
935 Node* const conversion = graph()->NewNode(javascript()->ToNumber(), input, | 955 // TODO(jarin) Use PlainPrimitiveToNumber once we have it. |
936 jsgraph()->NoContextConstant(), | 956 Node* const conversion = |
937 graph()->start(), graph()->start()); | 957 FLAG_turbo_deoptimization |
| 958 ? graph()->NewNode(javascript()->ToNumber(), input, |
| 959 jsgraph()->NoContextConstant(), |
| 960 jsgraph()->EmptyFrameState(), graph()->start(), |
| 961 graph()->start()) |
| 962 : graph()->NewNode(javascript()->ToNumber(), input, |
| 963 jsgraph()->NoContextConstant(), graph()->start(), |
| 964 graph()->start()); |
938 InsertConversion(conversion); | 965 InsertConversion(conversion); |
939 return conversion; | 966 return conversion; |
940 } | 967 } |
941 | 968 |
942 | 969 |
943 template <IrOpcode::Value kOpcode> | 970 template <IrOpcode::Value kOpcode> |
944 Node* JSTypedLowering::FindConversion(Node* input) { | 971 Node* JSTypedLowering::FindConversion(Node* input) { |
945 size_t const input_id = input->id(); | 972 size_t const input_id = input->id(); |
946 if (input_id < conversions_.size()) { | 973 if (input_id < conversions_.size()) { |
947 Node* const conversion = conversions_[input_id]; | 974 Node* const conversion = conversions_[input_id]; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
986 } | 1013 } |
987 | 1014 |
988 | 1015 |
989 MachineOperatorBuilder* JSTypedLowering::machine() const { | 1016 MachineOperatorBuilder* JSTypedLowering::machine() const { |
990 return jsgraph()->machine(); | 1017 return jsgraph()->machine(); |
991 } | 1018 } |
992 | 1019 |
993 } // namespace compiler | 1020 } // namespace compiler |
994 } // namespace internal | 1021 } // namespace internal |
995 } // namespace v8 | 1022 } // namespace v8 |
OLD | NEW |