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/compiler/access-builder.h" | 6 #include "src/compiler/access-builder.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/linkage.h" | 9 #include "src/compiler/linkage.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
11 #include "src/compiler/node-properties.h" | 11 #include "src/compiler/node-properties.h" |
12 #include "src/compiler/operator-properties.h" | 12 #include "src/compiler/operator-properties.h" |
13 #include "src/types.h" | 13 #include "src/types.h" |
14 | 14 |
15 namespace v8 { | 15 namespace v8 { |
16 namespace internal { | 16 namespace internal { |
17 namespace compiler { | 17 namespace compiler { |
18 | 18 |
19 // TODO(turbofan): js-typed-lowering improvements possible | 19 // TODO(turbofan): js-typed-lowering improvements possible |
20 // - immediately put in type bounds for all new nodes | 20 // - immediately put in type bounds for all new nodes |
21 // - relax effects from generic but not-side-effecting operations | 21 // - relax effects from generic but not-side-effecting operations |
22 | 22 |
23 | 23 |
24 // Relax the effects of {node} by immediately replacing effect and control uses | 24 JSTypedLowering::JSTypedLowering(Editor* editor, JSGraph* jsgraph, Zone* zone) |
25 // of {node} with the effect and control input to {node}. | 25 : AdvancedReducer(editor), jsgraph_(jsgraph), simplified_(graph()->zone()) { |
26 // TODO(turbofan): replace the effect input to {node} with {graph->start()}. | |
27 // TODO(titzer): move into a GraphEditor? | |
28 static void RelaxEffectsAndControls(Node* node) { | |
29 NodeProperties::ReplaceWithValue(node, node, NULL); | |
30 } | |
31 | |
32 | |
33 // Relax the control uses of {node} by immediately replacing them with the | |
34 // control input to {node}. | |
35 // TODO(titzer): move into a GraphEditor? | |
36 static void RelaxControls(Node* node) { | |
37 NodeProperties::ReplaceWithValue(node, node, node); | |
38 } | |
39 | |
40 | |
41 JSTypedLowering::JSTypedLowering(JSGraph* jsgraph, Zone* zone) | |
42 : jsgraph_(jsgraph), simplified_(graph()->zone()) { | |
43 zero_range_ = Type::Range(0.0, 0.0, graph()->zone()); | 26 zero_range_ = Type::Range(0.0, 0.0, graph()->zone()); |
44 one_range_ = Type::Range(1.0, 1.0, graph()->zone()); | 27 one_range_ = Type::Range(1.0, 1.0, graph()->zone()); |
45 zero_thirtyone_range_ = Type::Range(0.0, 31.0, graph()->zone()); | 28 zero_thirtyone_range_ = Type::Range(0.0, 31.0, graph()->zone()); |
46 for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) { | 29 for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) { |
47 double min = kMinInt / (1 << k); | 30 double min = kMinInt / (1 << k); |
48 double max = kMaxInt / (1 << k); | 31 double max = kMaxInt / (1 << k); |
49 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); | 32 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); |
50 } | 33 } |
51 } | 34 } |
52 | 35 |
53 | 36 |
54 Reduction JSTypedLowering::ReplaceEagerly(Node* old, Node* node) { | |
55 NodeProperties::ReplaceWithValue(old, node, node); | |
56 return Changed(node); | |
57 } | |
58 | |
59 | |
60 // A helper class to construct inline allocations on the simplified operator | 37 // A helper class to construct inline allocations on the simplified operator |
61 // level. This keeps track of the effect chain for initial stores on a newly | 38 // level. This keeps track of the effect chain for initial stores on a newly |
62 // allocated object and also provides helpers for commonly allocated objects. | 39 // allocated object and also provides helpers for commonly allocated objects. |
63 class AllocationBuilder final { | 40 class AllocationBuilder final { |
64 public: | 41 public: |
65 AllocationBuilder(JSGraph* jsgraph, SimplifiedOperatorBuilder* simplified, | 42 AllocationBuilder(JSGraph* jsgraph, SimplifiedOperatorBuilder* simplified, |
66 Node* effect, Node* control) | 43 Node* effect, Node* control) |
67 : jsgraph_(jsgraph), | 44 : jsgraph_(jsgraph), |
68 simplified_(simplified), | 45 simplified_(simplified), |
69 allocation_(nullptr), | 46 allocation_(nullptr), |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 // to the pure operator {op}, possibly inserting a boolean inversion. | 159 // to the pure operator {op}, possibly inserting a boolean inversion. |
183 Reduction ChangeToPureOperator(const Operator* op, bool invert = false, | 160 Reduction ChangeToPureOperator(const Operator* op, bool invert = false, |
184 Type* type = Type::Any()) { | 161 Type* type = Type::Any()) { |
185 DCHECK_EQ(0, op->EffectInputCount()); | 162 DCHECK_EQ(0, op->EffectInputCount()); |
186 DCHECK_EQ(false, OperatorProperties::HasContextInput(op)); | 163 DCHECK_EQ(false, OperatorProperties::HasContextInput(op)); |
187 DCHECK_EQ(0, op->ControlInputCount()); | 164 DCHECK_EQ(0, op->ControlInputCount()); |
188 DCHECK_EQ(2, op->ValueInputCount()); | 165 DCHECK_EQ(2, op->ValueInputCount()); |
189 | 166 |
190 // Remove the effects from the node, and update its effect/control usages. | 167 // Remove the effects from the node, and update its effect/control usages. |
191 if (node_->op()->EffectInputCount() > 0) { | 168 if (node_->op()->EffectInputCount() > 0) { |
192 RelaxEffectsAndControls(node_); | 169 lowering_->RelaxEffectsAndControls(node_); |
193 } | 170 } |
194 // Remove the inputs corresponding to context, effect, and control. | 171 // Remove the inputs corresponding to context, effect, and control. |
195 NodeProperties::RemoveNonValueInputs(node_); | 172 NodeProperties::RemoveNonValueInputs(node_); |
196 // Finally, update the operator to the new one. | 173 // Finally, update the operator to the new one. |
197 node_->set_op(op); | 174 node_->set_op(op); |
198 | 175 |
199 // TODO(jarin): Replace the explicit typing hack with a call to some method | 176 // TODO(jarin): Replace the explicit typing hack with a call to some method |
200 // that encapsulates changing the operator and re-typing. | 177 // that encapsulates changing the operator and re-typing. |
201 Bounds const bounds = NodeProperties::GetBounds(node_); | 178 Bounds const bounds = NodeProperties::GetBounds(node_); |
202 NodeProperties::SetBounds(node_, Bounds::NarrowUpper(bounds, type, zone())); | 179 NodeProperties::SetBounds(node_, Bounds::NarrowUpper(bounds, type, zone())); |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 // TODO(turbofan): js-typed-lowering of Equal(boolean) | 520 // TODO(turbofan): js-typed-lowering of Equal(boolean) |
544 return NoChange(); | 521 return NoChange(); |
545 } | 522 } |
546 | 523 |
547 | 524 |
548 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) { | 525 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) { |
549 JSBinopReduction r(this, node); | 526 JSBinopReduction r(this, node); |
550 if (r.left() == r.right()) { | 527 if (r.left() == r.right()) { |
551 // x === x is always true if x != NaN | 528 // x === x is always true if x != NaN |
552 if (!r.left_type()->Maybe(Type::NaN())) { | 529 if (!r.left_type()->Maybe(Type::NaN())) { |
553 return ReplaceEagerly(node, jsgraph()->BooleanConstant(!invert)); | 530 Node* replacement = jsgraph()->BooleanConstant(!invert); |
| 531 Replace(node, replacement); |
| 532 return Replace(replacement); |
554 } | 533 } |
555 } | 534 } |
556 if (r.OneInputCannotBe(Type::NumberOrString())) { | 535 if (r.OneInputCannotBe(Type::NumberOrString())) { |
557 // For values with canonical representation (i.e. not string nor number) an | 536 // For values with canonical representation (i.e. not string nor number) an |
558 // empty type intersection means the values cannot be strictly equal. | 537 // empty type intersection means the values cannot be strictly equal. |
559 if (!r.left_type()->Maybe(r.right_type())) { | 538 if (!r.left_type()->Maybe(r.right_type())) { |
560 return ReplaceEagerly(node, jsgraph()->BooleanConstant(invert)); | 539 Node* replacement = jsgraph()->BooleanConstant(invert); |
| 540 Replace(node, replacement); |
| 541 return Replace(replacement); |
561 } | 542 } |
562 } | 543 } |
563 if (r.OneInputIs(Type::Undefined())) { | 544 if (r.OneInputIs(Type::Undefined())) { |
564 return r.ChangeToPureOperator( | 545 return r.ChangeToPureOperator( |
565 simplified()->ReferenceEqual(Type::Undefined()), invert); | 546 simplified()->ReferenceEqual(Type::Undefined()), invert); |
566 } | 547 } |
567 if (r.OneInputIs(Type::Null())) { | 548 if (r.OneInputIs(Type::Null())) { |
568 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Null()), | 549 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Null()), |
569 invert); | 550 invert); |
570 } | 551 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 } else if (input_type->Is(Type::String())) { | 589 } else if (input_type->Is(Type::String())) { |
609 // JSUnaryNot(x:string) => NumberEqual(x.length,#0) | 590 // JSUnaryNot(x:string) => NumberEqual(x.length,#0) |
610 FieldAccess const access = AccessBuilder::ForStringLength(graph()->zone()); | 591 FieldAccess const access = AccessBuilder::ForStringLength(graph()->zone()); |
611 // It is safe for the load to be effect-free (i.e. not linked into effect | 592 // It is safe for the load to be effect-free (i.e. not linked into effect |
612 // chain) because we assume String::length to be immutable. | 593 // chain) because we assume String::length to be immutable. |
613 Node* length = graph()->NewNode(simplified()->LoadField(access), input, | 594 Node* length = graph()->NewNode(simplified()->LoadField(access), input, |
614 graph()->start(), graph()->start()); | 595 graph()->start(), graph()->start()); |
615 node->set_op(simplified()->NumberEqual()); | 596 node->set_op(simplified()->NumberEqual()); |
616 node->ReplaceInput(0, length); | 597 node->ReplaceInput(0, length); |
617 node->ReplaceInput(1, jsgraph()->ZeroConstant()); | 598 node->ReplaceInput(1, jsgraph()->ZeroConstant()); |
618 NodeProperties::ReplaceWithValue(node, node, length); | 599 ReplaceWithValue(node, node, length); |
619 DCHECK_EQ(2, node->InputCount()); | 600 DCHECK_EQ(2, node->InputCount()); |
620 return Changed(node); | 601 return Changed(node); |
621 } | 602 } |
622 return NoChange(); | 603 return NoChange(); |
623 } | 604 } |
624 | 605 |
625 | 606 |
626 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { | 607 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { |
627 Node* const input = node->InputAt(0); | 608 Node* const input = node->InputAt(0); |
628 Type* const input_type = NodeProperties::GetBounds(input).upper; | 609 Type* const input_type = NodeProperties::GetBounds(input).upper; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 // TODO(turbofan): js-typed-lowering of ToNumber(x:string) | 662 // TODO(turbofan): js-typed-lowering of ToNumber(x:string) |
682 return NoChange(); | 663 return NoChange(); |
683 } | 664 } |
684 | 665 |
685 | 666 |
686 Reduction JSTypedLowering::ReduceJSToNumber(Node* node) { | 667 Reduction JSTypedLowering::ReduceJSToNumber(Node* node) { |
687 // Try to reduce the input first. | 668 // Try to reduce the input first. |
688 Node* const input = node->InputAt(0); | 669 Node* const input = node->InputAt(0); |
689 Reduction reduction = ReduceJSToNumberInput(input); | 670 Reduction reduction = ReduceJSToNumberInput(input); |
690 if (reduction.Changed()) { | 671 if (reduction.Changed()) { |
691 NodeProperties::ReplaceWithValue(node, reduction.replacement()); | 672 ReplaceWithValue(node, reduction.replacement()); |
692 return reduction; | 673 return reduction; |
693 } | 674 } |
694 Type* const input_type = NodeProperties::GetBounds(input).upper; | 675 Type* const input_type = NodeProperties::GetBounds(input).upper; |
695 if (input_type->Is(Type::PlainPrimitive())) { | 676 if (input_type->Is(Type::PlainPrimitive())) { |
696 if (NodeProperties::GetContextInput(node) != | 677 if (NodeProperties::GetContextInput(node) != |
697 jsgraph()->NoContextConstant() || | 678 jsgraph()->NoContextConstant() || |
698 NodeProperties::GetEffectInput(node) != graph()->start() || | 679 NodeProperties::GetEffectInput(node) != graph()->start() || |
699 NodeProperties::GetControlInput(node) != graph()->start()) { | 680 NodeProperties::GetControlInput(node) != graph()->start()) { |
700 // JSToNumber(x:plain-primitive,context,effect,control) | 681 // JSToNumber(x:plain-primitive,context,effect,control) |
701 // => JSToNumber(x,no-context,start,start) | 682 // => JSToNumber(x,no-context,start,start) |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 // TODO(turbofan): js-typed-lowering of ToString(x:number) | 715 // TODO(turbofan): js-typed-lowering of ToString(x:number) |
735 return NoChange(); | 716 return NoChange(); |
736 } | 717 } |
737 | 718 |
738 | 719 |
739 Reduction JSTypedLowering::ReduceJSToString(Node* node) { | 720 Reduction JSTypedLowering::ReduceJSToString(Node* node) { |
740 // Try to reduce the input first. | 721 // Try to reduce the input first. |
741 Node* const input = node->InputAt(0); | 722 Node* const input = node->InputAt(0); |
742 Reduction reduction = ReduceJSToStringInput(input); | 723 Reduction reduction = ReduceJSToStringInput(input); |
743 if (reduction.Changed()) { | 724 if (reduction.Changed()) { |
744 NodeProperties::ReplaceWithValue(node, reduction.replacement()); | 725 ReplaceWithValue(node, reduction.replacement()); |
745 return reduction; | 726 return reduction; |
746 } | 727 } |
747 return NoChange(); | 728 return NoChange(); |
748 } | 729 } |
749 | 730 |
750 | 731 |
751 Reduction JSTypedLowering::ReduceJSLoadNamed(Node* node) { | 732 Reduction JSTypedLowering::ReduceJSLoadNamed(Node* node) { |
752 Node* object = NodeProperties::GetValueInput(node, 0); | 733 Node* object = NodeProperties::GetValueInput(node, 0); |
753 Type* object_type = NodeProperties::GetBounds(object).upper; | 734 Type* object_type = NodeProperties::GetBounds(object).upper; |
754 if (object_type->Is(Type::GlobalObject())) { | 735 if (object_type->Is(Type::GlobalObject())) { |
755 // Optimize global constants like "undefined", "Infinity", and "NaN". | 736 // Optimize global constants like "undefined", "Infinity", and "NaN". |
756 Handle<Name> name = LoadNamedParametersOf(node->op()).name().handle(); | 737 Handle<Name> name = LoadNamedParametersOf(node->op()).name().handle(); |
757 Handle<Object> constant_value = factory()->GlobalConstantFor(name); | 738 Handle<Object> constant_value = factory()->GlobalConstantFor(name); |
758 if (!constant_value.is_null()) { | 739 if (!constant_value.is_null()) { |
759 Node* constant = jsgraph()->Constant(constant_value); | 740 Node* constant = jsgraph()->Constant(constant_value); |
760 NodeProperties::ReplaceWithValue(node, constant); | 741 ReplaceWithValue(node, constant); |
761 return Replace(constant); | 742 return Replace(constant); |
762 } | 743 } |
763 } | 744 } |
764 return NoChange(); | 745 return NoChange(); |
765 } | 746 } |
766 | 747 |
767 | 748 |
768 Reduction JSTypedLowering::ReduceJSLoadProperty(Node* node) { | 749 Reduction JSTypedLowering::ReduceJSLoadProperty(Node* node) { |
769 Node* key = NodeProperties::GetValueInput(node, 1); | 750 Node* key = NodeProperties::GetValueInput(node, 1); |
770 Node* base = NodeProperties::GetValueInput(node, 0); | 751 Node* base = NodeProperties::GetValueInput(node, 0); |
(...skipping 17 matching lines...) Expand all Loading... |
788 Node* length = jsgraph()->Constant(byte_length); | 769 Node* length = jsgraph()->Constant(byte_length); |
789 Node* effect = NodeProperties::GetEffectInput(node); | 770 Node* effect = NodeProperties::GetEffectInput(node); |
790 Node* control = NodeProperties::GetControlInput(node); | 771 Node* control = NodeProperties::GetControlInput(node); |
791 // Check if we can avoid the bounds check. | 772 // Check if we can avoid the bounds check. |
792 if (key_type->Min() >= 0 && | 773 if (key_type->Min() >= 0 && |
793 key_type->Max() < array->length()->Number()) { | 774 key_type->Max() < array->length()->Number()) { |
794 Node* load = graph()->NewNode( | 775 Node* load = graph()->NewNode( |
795 simplified()->LoadElement( | 776 simplified()->LoadElement( |
796 AccessBuilder::ForTypedArrayElement(array->type(), true)), | 777 AccessBuilder::ForTypedArrayElement(array->type(), true)), |
797 buffer, key, effect, control); | 778 buffer, key, effect, control); |
798 return ReplaceEagerly(node, load); | 779 ReplaceWithValue(node, load, load); |
| 780 return Replace(load); |
799 } | 781 } |
800 // Compute byte offset. | 782 // Compute byte offset. |
801 Node* offset = Word32Shl(key, static_cast<int>(k)); | 783 Node* offset = Word32Shl(key, static_cast<int>(k)); |
802 Node* load = graph()->NewNode(simplified()->LoadBuffer(access), buffer, | 784 Node* load = graph()->NewNode(simplified()->LoadBuffer(access), buffer, |
803 offset, length, effect, control); | 785 offset, length, effect, control); |
804 return ReplaceEagerly(node, load); | 786 ReplaceWithValue(node, load, load); |
| 787 return Replace(load); |
805 } | 788 } |
806 } | 789 } |
807 } | 790 } |
808 return NoChange(); | 791 return NoChange(); |
809 } | 792 } |
810 | 793 |
811 | 794 |
812 Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) { | 795 Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) { |
813 Node* key = NodeProperties::GetValueInput(node, 1); | 796 Node* key = NodeProperties::GetValueInput(node, 1); |
814 Node* base = NodeProperties::GetValueInput(node, 0); | 797 Node* base = NodeProperties::GetValueInput(node, 0); |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 context, effect, control); | 1015 context, effect, control); |
1033 AllocationBuilder a(jsgraph(), simplified(), effect, control); | 1016 AllocationBuilder a(jsgraph(), simplified(), effect, control); |
1034 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. | 1017 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4); // Ensure fully covered. |
1035 a.AllocateArray(Context::MIN_CONTEXT_SLOTS, factory()->with_context_map()); | 1018 a.AllocateArray(Context::MIN_CONTEXT_SLOTS, factory()->with_context_map()); |
1036 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); | 1019 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); |
1037 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); | 1020 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); |
1038 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), input); | 1021 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), input); |
1039 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); | 1022 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); |
1040 // TODO(mstarzinger): We could mutate {node} into the allocation instead. | 1023 // TODO(mstarzinger): We could mutate {node} into the allocation instead. |
1041 NodeProperties::SetBounds(a.allocation(), NodeProperties::GetBounds(node)); | 1024 NodeProperties::SetBounds(a.allocation(), NodeProperties::GetBounds(node)); |
1042 NodeProperties::ReplaceWithValue(node, node, a.effect()); | 1025 ReplaceWithValue(node, node, a.effect()); |
1043 node->ReplaceInput(0, a.allocation()); | 1026 node->ReplaceInput(0, a.allocation()); |
1044 node->ReplaceInput(1, a.effect()); | 1027 node->ReplaceInput(1, a.effect()); |
1045 node->set_op(common()->Finish(1)); | 1028 node->set_op(common()->Finish(1)); |
1046 node->TrimInputCount(2); | 1029 node->TrimInputCount(2); |
1047 return Changed(node); | 1030 return Changed(node); |
1048 } | 1031 } |
1049 return NoChange(); | 1032 return NoChange(); |
1050 } | 1033 } |
1051 | 1034 |
1052 | 1035 |
(...skipping 18 matching lines...) Expand all Loading... |
1071 a.AllocateArray(context_length, factory()->block_context_map()); | 1054 a.AllocateArray(context_length, factory()->block_context_map()); |
1072 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); | 1055 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); |
1073 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); | 1056 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); |
1074 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), input); | 1057 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), input); |
1075 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); | 1058 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); |
1076 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) { | 1059 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) { |
1077 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->TheHoleConstant()); | 1060 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->TheHoleConstant()); |
1078 } | 1061 } |
1079 // TODO(mstarzinger): We could mutate {node} into the allocation instead. | 1062 // TODO(mstarzinger): We could mutate {node} into the allocation instead. |
1080 NodeProperties::SetBounds(a.allocation(), NodeProperties::GetBounds(node)); | 1063 NodeProperties::SetBounds(a.allocation(), NodeProperties::GetBounds(node)); |
1081 NodeProperties::ReplaceWithValue(node, node, a.effect()); | 1064 ReplaceWithValue(node, node, a.effect()); |
1082 node->ReplaceInput(0, a.allocation()); | 1065 node->ReplaceInput(0, a.allocation()); |
1083 node->ReplaceInput(1, a.effect()); | 1066 node->ReplaceInput(1, a.effect()); |
1084 node->set_op(common()->Finish(1)); | 1067 node->set_op(common()->Finish(1)); |
1085 node->TrimInputCount(2); | 1068 node->TrimInputCount(2); |
1086 return Changed(node); | 1069 return Changed(node); |
1087 } | 1070 } |
1088 return NoChange(); | 1071 return NoChange(); |
1089 } | 1072 } |
1090 | 1073 |
1091 | 1074 |
1092 Reduction JSTypedLowering::Reduce(Node* node) { | 1075 Reduction JSTypedLowering::Reduce(Node* node) { |
1093 // Check if the output type is a singleton. In that case we already know the | 1076 // Check if the output type is a singleton. In that case we already know the |
1094 // result value and can simply replace the node if it's eliminable. | 1077 // result value and can simply replace the node if it's eliminable. |
1095 if (!NodeProperties::IsConstant(node) && NodeProperties::IsTyped(node) && | 1078 if (!NodeProperties::IsConstant(node) && NodeProperties::IsTyped(node) && |
1096 node->op()->HasProperty(Operator::kEliminatable)) { | 1079 node->op()->HasProperty(Operator::kEliminatable)) { |
1097 Type* upper = NodeProperties::GetBounds(node).upper; | 1080 Type* upper = NodeProperties::GetBounds(node).upper; |
1098 if (upper->IsConstant()) { | 1081 if (upper->IsConstant()) { |
1099 Node* replacement = jsgraph()->Constant(upper->AsConstant()->Value()); | 1082 Node* replacement = jsgraph()->Constant(upper->AsConstant()->Value()); |
1100 NodeProperties::ReplaceWithValue(node, replacement); | 1083 ReplaceWithValue(node, replacement); |
1101 return Changed(replacement); | 1084 return Changed(replacement); |
1102 } else if (upper->Is(Type::MinusZero())) { | 1085 } else if (upper->Is(Type::MinusZero())) { |
1103 Node* replacement = jsgraph()->Constant(factory()->minus_zero_value()); | 1086 Node* replacement = jsgraph()->Constant(factory()->minus_zero_value()); |
1104 NodeProperties::ReplaceWithValue(node, replacement); | 1087 ReplaceWithValue(node, replacement); |
1105 return Changed(replacement); | 1088 return Changed(replacement); |
1106 } else if (upper->Is(Type::NaN())) { | 1089 } else if (upper->Is(Type::NaN())) { |
1107 Node* replacement = jsgraph()->NaNConstant(); | 1090 Node* replacement = jsgraph()->NaNConstant(); |
1108 NodeProperties::ReplaceWithValue(node, replacement); | 1091 ReplaceWithValue(node, replacement); |
1109 return Changed(replacement); | 1092 return Changed(replacement); |
1110 } else if (upper->Is(Type::Null())) { | 1093 } else if (upper->Is(Type::Null())) { |
1111 Node* replacement = jsgraph()->NullConstant(); | 1094 Node* replacement = jsgraph()->NullConstant(); |
1112 NodeProperties::ReplaceWithValue(node, replacement); | 1095 ReplaceWithValue(node, replacement); |
1113 return Changed(replacement); | 1096 return Changed(replacement); |
1114 } else if (upper->Is(Type::PlainNumber()) && upper->Min() == upper->Max()) { | 1097 } else if (upper->Is(Type::PlainNumber()) && upper->Min() == upper->Max()) { |
1115 Node* replacement = jsgraph()->Constant(upper->Min()); | 1098 Node* replacement = jsgraph()->Constant(upper->Min()); |
1116 NodeProperties::ReplaceWithValue(node, replacement); | 1099 ReplaceWithValue(node, replacement); |
1117 return Changed(replacement); | 1100 return Changed(replacement); |
1118 } else if (upper->Is(Type::Undefined())) { | 1101 } else if (upper->Is(Type::Undefined())) { |
1119 Node* replacement = jsgraph()->UndefinedConstant(); | 1102 Node* replacement = jsgraph()->UndefinedConstant(); |
1120 NodeProperties::ReplaceWithValue(node, replacement); | 1103 ReplaceWithValue(node, replacement); |
1121 return Changed(replacement); | 1104 return Changed(replacement); |
1122 } | 1105 } |
1123 } | 1106 } |
1124 switch (node->opcode()) { | 1107 switch (node->opcode()) { |
1125 case IrOpcode::kJSEqual: | 1108 case IrOpcode::kJSEqual: |
1126 return ReduceJSEqual(node, false); | 1109 return ReduceJSEqual(node, false); |
1127 case IrOpcode::kJSNotEqual: | 1110 case IrOpcode::kJSNotEqual: |
1128 return ReduceJSEqual(node, true); | 1111 return ReduceJSEqual(node, true); |
1129 case IrOpcode::kJSStrictEqual: | 1112 case IrOpcode::kJSStrictEqual: |
1130 return ReduceJSStrictEqual(node, false); | 1113 return ReduceJSStrictEqual(node, false); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1215 } | 1198 } |
1216 | 1199 |
1217 | 1200 |
1218 MachineOperatorBuilder* JSTypedLowering::machine() const { | 1201 MachineOperatorBuilder* JSTypedLowering::machine() const { |
1219 return jsgraph()->machine(); | 1202 return jsgraph()->machine(); |
1220 } | 1203 } |
1221 | 1204 |
1222 } // namespace compiler | 1205 } // namespace compiler |
1223 } // namespace internal | 1206 } // namespace internal |
1224 } // namespace v8 | 1207 } // namespace v8 |
OLD | NEW |