Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/compiler/js-typed-lowering.cc

Issue 1134303003: [turbofan] Turn JSTypedLowering into an AdvancedReducer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comments. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/js-typed-lowering.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/js-typed-lowering.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698