| 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" |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 DCHECK_EQ(0, op->ControlInputCount()); | 156 DCHECK_EQ(0, op->ControlInputCount()); |
| 157 DCHECK_EQ(2, op->ValueInputCount()); | 157 DCHECK_EQ(2, op->ValueInputCount()); |
| 158 | 158 |
| 159 // Remove the effects from the node, and update its effect/control usages. | 159 // Remove the effects from the node, and update its effect/control usages. |
| 160 if (node_->op()->EffectInputCount() > 0) { | 160 if (node_->op()->EffectInputCount() > 0) { |
| 161 lowering_->RelaxEffectsAndControls(node_); | 161 lowering_->RelaxEffectsAndControls(node_); |
| 162 } | 162 } |
| 163 // Remove the inputs corresponding to context, effect, and control. | 163 // Remove the inputs corresponding to context, effect, and control. |
| 164 NodeProperties::RemoveNonValueInputs(node_); | 164 NodeProperties::RemoveNonValueInputs(node_); |
| 165 // Finally, update the operator to the new one. | 165 // Finally, update the operator to the new one. |
| 166 node_->set_op(op); | 166 NodeProperties::ChangeOp(node_, op); |
| 167 | 167 |
| 168 // TODO(jarin): Replace the explicit typing hack with a call to some method | 168 // TODO(jarin): Replace the explicit typing hack with a call to some method |
| 169 // that encapsulates changing the operator and re-typing. | 169 // that encapsulates changing the operator and re-typing. |
| 170 Type* node_type = NodeProperties::GetType(node_); | 170 Type* node_type = NodeProperties::GetType(node_); |
| 171 NodeProperties::SetType(node_, Type::Intersect(node_type, type, zone())); | 171 NodeProperties::SetType(node_, Type::Intersect(node_type, type, zone())); |
| 172 | 172 |
| 173 if (invert) { | 173 if (invert) { |
| 174 // Insert an boolean not to invert the value. | 174 // Insert an boolean not to invert the value. |
| 175 Node* value = graph()->NewNode(simplified()->BooleanNot(), node_); | 175 Node* value = graph()->NewNode(simplified()->BooleanNot(), node_); |
| 176 node_->ReplaceUses(value); | 176 node_->ReplaceUses(value); |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 Node* exception_effect = | 355 Node* exception_effect = |
| 356 graph()->NewNode(common()->EffectPhi(2), left_exception, | 356 graph()->NewNode(common()->EffectPhi(2), left_exception, |
| 357 right_exception, exception_merge); | 357 right_exception, exception_merge); |
| 358 for (Edge edge : exception_merge->use_edges()) { | 358 for (Edge edge : exception_merge->use_edges()) { |
| 359 if (NodeProperties::IsEffectEdge(edge)) edge.UpdateTo(exception_effect); | 359 if (NodeProperties::IsEffectEdge(edge)) edge.UpdateTo(exception_effect); |
| 360 if (NodeProperties::IsValueEdge(edge)) edge.UpdateTo(exception_value); | 360 if (NodeProperties::IsValueEdge(edge)) edge.UpdateTo(exception_value); |
| 361 } | 361 } |
| 362 NodeProperties::RemoveType(exception_merge); | 362 NodeProperties::RemoveType(exception_merge); |
| 363 exception_merge->ReplaceInput(0, left_exception); | 363 exception_merge->ReplaceInput(0, left_exception); |
| 364 exception_merge->ReplaceInput(1, right_exception); | 364 exception_merge->ReplaceInput(1, right_exception); |
| 365 exception_merge->set_op(common()->Merge(2)); | 365 NodeProperties::ChangeOp(exception_merge, common()->Merge(2)); |
| 366 | 366 |
| 367 *left_result = left_conv; | 367 *left_result = left_conv; |
| 368 *right_result = right_conv; | 368 *right_result = right_conv; |
| 369 } | 369 } |
| 370 | 370 |
| 371 Node* ConvertToUI32(Node* node, Signedness signedness) { | 371 Node* ConvertToUI32(Node* node, Signedness signedness) { |
| 372 // Avoid introducing too many eager NumberToXXnt32() operations. | 372 // Avoid introducing too many eager NumberToXXnt32() operations. |
| 373 Type* type = NodeProperties::GetType(node); | 373 Type* type = NodeProperties::GetType(node); |
| 374 if (signedness == kSigned) { | 374 if (signedness == kSigned) { |
| 375 if (!type->Is(Type::Signed32())) { | 375 if (!type->Is(Type::Signed32())) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 406 // JSAdd(x:string, y:string) => CallStub[StringAdd](x, y) | 406 // JSAdd(x:string, y:string) => CallStub[StringAdd](x, y) |
| 407 Callable const callable = | 407 Callable const callable = |
| 408 CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED); | 408 CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED); |
| 409 CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( | 409 CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( |
| 410 isolate(), graph()->zone(), callable.descriptor(), 0, | 410 isolate(), graph()->zone(), callable.descriptor(), 0, |
| 411 CallDescriptor::kNeedsFrameState, node->op()->properties()); | 411 CallDescriptor::kNeedsFrameState, node->op()->properties()); |
| 412 DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node->op())); | 412 DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node->op())); |
| 413 node->RemoveInput(NodeProperties::FirstFrameStateIndex(node) + 1); | 413 node->RemoveInput(NodeProperties::FirstFrameStateIndex(node) + 1); |
| 414 node->InsertInput(graph()->zone(), 0, | 414 node->InsertInput(graph()->zone(), 0, |
| 415 jsgraph()->HeapConstant(callable.code())); | 415 jsgraph()->HeapConstant(callable.code())); |
| 416 node->set_op(common()->Call(desc)); | 416 NodeProperties::ChangeOp(node, common()->Call(desc)); |
| 417 return Changed(node); | 417 return Changed(node); |
| 418 } | 418 } |
| 419 return NoChange(); | 419 return NoChange(); |
| 420 } | 420 } |
| 421 | 421 |
| 422 | 422 |
| 423 Reduction JSTypedLowering::ReduceJSModulus(Node* node) { | 423 Reduction JSTypedLowering::ReduceJSModulus(Node* node) { |
| 424 JSBinopReduction r(this, node); | 424 JSBinopReduction r(this, node); |
| 425 if (r.BothInputsAre(Type::Number())) { | 425 if (r.BothInputsAre(Type::Number())) { |
| 426 // JSModulus(x:number, x:number) => NumberModulus(x, y) | 426 // JSModulus(x:number, x:number) => NumberModulus(x, y) |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 622 // TODO(turbofan): js-typed-lowering of StrictEqual(mixed types) | 622 // TODO(turbofan): js-typed-lowering of StrictEqual(mixed types) |
| 623 return NoChange(); | 623 return NoChange(); |
| 624 } | 624 } |
| 625 | 625 |
| 626 | 626 |
| 627 Reduction JSTypedLowering::ReduceJSUnaryNot(Node* node) { | 627 Reduction JSTypedLowering::ReduceJSUnaryNot(Node* node) { |
| 628 Node* const input = node->InputAt(0); | 628 Node* const input = node->InputAt(0); |
| 629 Type* const input_type = NodeProperties::GetType(input); | 629 Type* const input_type = NodeProperties::GetType(input); |
| 630 if (input_type->Is(Type::Boolean())) { | 630 if (input_type->Is(Type::Boolean())) { |
| 631 // JSUnaryNot(x:boolean) => BooleanNot(x) | 631 // JSUnaryNot(x:boolean) => BooleanNot(x) |
| 632 node->set_op(simplified()->BooleanNot()); | |
| 633 node->TrimInputCount(1); | 632 node->TrimInputCount(1); |
| 633 NodeProperties::ChangeOp(node, simplified()->BooleanNot()); |
| 634 return Changed(node); | 634 return Changed(node); |
| 635 } else if (input_type->Is(Type::OrderedNumber())) { | 635 } else if (input_type->Is(Type::OrderedNumber())) { |
| 636 // JSUnaryNot(x:number) => NumberEqual(x,#0) | 636 // JSUnaryNot(x:number) => NumberEqual(x,#0) |
| 637 node->set_op(simplified()->NumberEqual()); | |
| 638 node->ReplaceInput(1, jsgraph()->ZeroConstant()); | 637 node->ReplaceInput(1, jsgraph()->ZeroConstant()); |
| 639 DCHECK_EQ(2, node->InputCount()); | 638 NodeProperties::ChangeOp(node, simplified()->NumberEqual()); |
| 640 return Changed(node); | 639 return Changed(node); |
| 641 } else if (input_type->Is(Type::String())) { | 640 } else if (input_type->Is(Type::String())) { |
| 642 // JSUnaryNot(x:string) => NumberEqual(x.length,#0) | 641 // JSUnaryNot(x:string) => NumberEqual(x.length,#0) |
| 643 FieldAccess const access = AccessBuilder::ForStringLength(graph()->zone()); | 642 FieldAccess const access = AccessBuilder::ForStringLength(graph()->zone()); |
| 644 // It is safe for the load to be effect-free (i.e. not linked into effect | 643 // It is safe for the load to be effect-free (i.e. not linked into effect |
| 645 // chain) because we assume String::length to be immutable. | 644 // chain) because we assume String::length to be immutable. |
| 646 Node* length = graph()->NewNode(simplified()->LoadField(access), input, | 645 Node* length = graph()->NewNode(simplified()->LoadField(access), input, |
| 647 graph()->start(), graph()->start()); | 646 graph()->start(), graph()->start()); |
| 648 node->set_op(simplified()->NumberEqual()); | |
| 649 node->ReplaceInput(0, length); | 647 node->ReplaceInput(0, length); |
| 650 node->ReplaceInput(1, jsgraph()->ZeroConstant()); | 648 node->ReplaceInput(1, jsgraph()->ZeroConstant()); |
| 649 NodeProperties::ChangeOp(node, simplified()->NumberEqual()); |
| 651 ReplaceWithValue(node, node, length); | 650 ReplaceWithValue(node, node, length); |
| 652 DCHECK_EQ(2, node->InputCount()); | |
| 653 return Changed(node); | 651 return Changed(node); |
| 654 } | 652 } |
| 655 return NoChange(); | 653 return NoChange(); |
| 656 } | 654 } |
| 657 | 655 |
| 658 | 656 |
| 659 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { | 657 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { |
| 660 Node* const input = node->InputAt(0); | 658 Node* const input = node->InputAt(0); |
| 661 Type* const input_type = NodeProperties::GetType(input); | 659 Type* const input_type = NodeProperties::GetType(input); |
| 662 if (input_type->Is(Type::Boolean())) { | 660 if (input_type->Is(Type::Boolean())) { |
| 663 // JSToBoolean(x:boolean) => x | 661 // JSToBoolean(x:boolean) => x |
| 664 return Replace(input); | 662 return Replace(input); |
| 665 } else if (input_type->Is(Type::OrderedNumber())) { | 663 } else if (input_type->Is(Type::OrderedNumber())) { |
| 666 // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0)) | 664 // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0)) |
| 667 node->set_op(simplified()->BooleanNot()); | |
| 668 node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input, | 665 node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input, |
| 669 jsgraph()->ZeroConstant())); | 666 jsgraph()->ZeroConstant())); |
| 670 node->TrimInputCount(1); | 667 node->TrimInputCount(1); |
| 668 NodeProperties::ChangeOp(node, simplified()->BooleanNot()); |
| 671 return Changed(node); | 669 return Changed(node); |
| 672 } else if (input_type->Is(Type::String())) { | 670 } else if (input_type->Is(Type::String())) { |
| 673 // JSToBoolean(x:string) => NumberLessThan(#0,x.length) | 671 // JSToBoolean(x:string) => NumberLessThan(#0,x.length) |
| 674 FieldAccess const access = AccessBuilder::ForStringLength(graph()->zone()); | 672 FieldAccess const access = AccessBuilder::ForStringLength(graph()->zone()); |
| 675 // It is safe for the load to be effect-free (i.e. not linked into effect | 673 // It is safe for the load to be effect-free (i.e. not linked into effect |
| 676 // chain) because we assume String::length to be immutable. | 674 // chain) because we assume String::length to be immutable. |
| 677 Node* length = graph()->NewNode(simplified()->LoadField(access), input, | 675 Node* length = graph()->NewNode(simplified()->LoadField(access), input, |
| 678 graph()->start(), graph()->start()); | 676 graph()->start(), graph()->start()); |
| 679 node->set_op(simplified()->NumberLessThan()); | |
| 680 node->ReplaceInput(0, jsgraph()->ZeroConstant()); | 677 node->ReplaceInput(0, jsgraph()->ZeroConstant()); |
| 681 node->ReplaceInput(1, length); | 678 node->ReplaceInput(1, length); |
| 682 DCHECK_EQ(2, node->InputCount()); | 679 NodeProperties::ChangeOp(node, simplified()->NumberLessThan()); |
| 683 return Changed(node); | 680 return Changed(node); |
| 684 } | 681 } |
| 685 return NoChange(); | 682 return NoChange(); |
| 686 } | 683 } |
| 687 | 684 |
| 688 | 685 |
| 689 Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) { | 686 Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) { |
| 690 if (input->opcode() == IrOpcode::kJSToNumber) { | 687 if (input->opcode() == IrOpcode::kJSToNumber) { |
| 691 // Recursively try to reduce the input first. | 688 // Recursively try to reduce the input first. |
| 692 Reduction result = ReduceJSToNumber(input); | 689 Reduction result = ReduceJSToNumber(input); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 901 // For integer-typed arrays, convert to the integer type. | 898 // For integer-typed arrays, convert to the integer type. |
| 902 if (TypeOf(access.machine_type()) == kTypeInt32 && | 899 if (TypeOf(access.machine_type()) == kTypeInt32 && |
| 903 !value_type->Is(Type::Signed32())) { | 900 !value_type->Is(Type::Signed32())) { |
| 904 value = graph()->NewNode(simplified()->NumberToInt32(), value); | 901 value = graph()->NewNode(simplified()->NumberToInt32(), value); |
| 905 } else if (TypeOf(access.machine_type()) == kTypeUint32 && | 902 } else if (TypeOf(access.machine_type()) == kTypeUint32 && |
| 906 !value_type->Is(Type::Unsigned32())) { | 903 !value_type->Is(Type::Unsigned32())) { |
| 907 value = graph()->NewNode(simplified()->NumberToUint32(), value); | 904 value = graph()->NewNode(simplified()->NumberToUint32(), value); |
| 908 } | 905 } |
| 909 // Check if we can avoid the bounds check. | 906 // Check if we can avoid the bounds check. |
| 910 if (key_type->Min() >= 0 && key_type->Max() < array->length_value()) { | 907 if (key_type->Min() >= 0 && key_type->Max() < array->length_value()) { |
| 911 node->set_op(simplified()->StoreElement( | |
| 912 AccessBuilder::ForTypedArrayElement(array->type(), true))); | |
| 913 node->ReplaceInput(0, buffer); | 908 node->ReplaceInput(0, buffer); |
| 914 DCHECK_EQ(key, node->InputAt(1)); | 909 DCHECK_EQ(key, node->InputAt(1)); |
| 915 node->ReplaceInput(2, value); | 910 node->ReplaceInput(2, value); |
| 916 node->ReplaceInput(3, effect); | 911 node->ReplaceInput(3, effect); |
| 917 node->ReplaceInput(4, control); | 912 node->ReplaceInput(4, control); |
| 918 node->TrimInputCount(5); | 913 node->TrimInputCount(5); |
| 914 NodeProperties::ChangeOp( |
| 915 node, |
| 916 simplified()->StoreElement( |
| 917 AccessBuilder::ForTypedArrayElement(array->type(), true))); |
| 919 RelaxControls(node); | 918 RelaxControls(node); |
| 920 return Changed(node); | 919 return Changed(node); |
| 921 } | 920 } |
| 922 // Compute byte offset. | 921 // Compute byte offset. |
| 923 Node* offset = Word32Shl(key, static_cast<int>(k)); | 922 Node* offset = Word32Shl(key, static_cast<int>(k)); |
| 924 // Turn into a StoreBuffer operation. | 923 // Turn into a StoreBuffer operation. |
| 925 node->set_op(simplified()->StoreBuffer(access)); | |
| 926 node->ReplaceInput(0, buffer); | 924 node->ReplaceInput(0, buffer); |
| 927 node->ReplaceInput(1, offset); | 925 node->ReplaceInput(1, offset); |
| 928 node->ReplaceInput(2, length); | 926 node->ReplaceInput(2, length); |
| 929 node->ReplaceInput(3, value); | 927 node->ReplaceInput(3, value); |
| 930 node->ReplaceInput(4, effect); | 928 node->ReplaceInput(4, effect); |
| 931 node->ReplaceInput(5, control); | 929 node->ReplaceInput(5, control); |
| 932 node->TrimInputCount(6); | 930 node->TrimInputCount(6); |
| 931 NodeProperties::ChangeOp(node, simplified()->StoreBuffer(access)); |
| 933 RelaxControls(node); | 932 RelaxControls(node); |
| 934 return Changed(node); | 933 return Changed(node); |
| 935 } | 934 } |
| 936 } | 935 } |
| 937 } | 936 } |
| 938 return NoChange(); | 937 return NoChange(); |
| 939 } | 938 } |
| 940 | 939 |
| 941 | 940 |
| 942 Reduction JSTypedLowering::ReduceJSLoadContext(Node* node) { | 941 Reduction JSTypedLowering::ReduceJSLoadContext(Node* node) { |
| 943 DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode()); | 942 DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode()); |
| 944 ContextAccess const& access = ContextAccessOf(node->op()); | 943 ContextAccess const& access = ContextAccessOf(node->op()); |
| 945 Node* const effect = NodeProperties::GetEffectInput(node); | 944 Node* const effect = NodeProperties::GetEffectInput(node); |
| 946 Node* const control = graph()->start(); | 945 Node* const control = graph()->start(); |
| 947 for (size_t i = 0; i < access.depth(); ++i) { | 946 for (size_t i = 0; i < access.depth(); ++i) { |
| 948 node->ReplaceInput( | 947 node->ReplaceInput( |
| 949 0, graph()->NewNode( | 948 0, graph()->NewNode( |
| 950 simplified()->LoadField( | 949 simplified()->LoadField( |
| 951 AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)), | 950 AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)), |
| 952 NodeProperties::GetValueInput(node, 0), effect, control)); | 951 NodeProperties::GetValueInput(node, 0), effect, control)); |
| 953 } | 952 } |
| 954 node->set_op( | |
| 955 simplified()->LoadField(AccessBuilder::ForContextSlot(access.index()))); | |
| 956 node->ReplaceInput(1, effect); | 953 node->ReplaceInput(1, effect); |
| 957 node->ReplaceInput(2, control); | 954 node->ReplaceInput(2, control); |
| 958 DCHECK_EQ(3, node->InputCount()); | 955 NodeProperties::ChangeOp( |
| 956 node, |
| 957 simplified()->LoadField(AccessBuilder::ForContextSlot(access.index()))); |
| 959 return Changed(node); | 958 return Changed(node); |
| 960 } | 959 } |
| 961 | 960 |
| 962 | 961 |
| 963 Reduction JSTypedLowering::ReduceJSStoreContext(Node* node) { | 962 Reduction JSTypedLowering::ReduceJSStoreContext(Node* node) { |
| 964 DCHECK_EQ(IrOpcode::kJSStoreContext, node->opcode()); | 963 DCHECK_EQ(IrOpcode::kJSStoreContext, node->opcode()); |
| 965 ContextAccess const& access = ContextAccessOf(node->op()); | 964 ContextAccess const& access = ContextAccessOf(node->op()); |
| 966 Node* const effect = NodeProperties::GetEffectInput(node); | 965 Node* const effect = NodeProperties::GetEffectInput(node); |
| 967 Node* const control = graph()->start(); | 966 Node* const control = graph()->start(); |
| 968 for (size_t i = 0; i < access.depth(); ++i) { | 967 for (size_t i = 0; i < access.depth(); ++i) { |
| 969 node->ReplaceInput( | 968 node->ReplaceInput( |
| 970 0, graph()->NewNode( | 969 0, graph()->NewNode( |
| 971 simplified()->LoadField( | 970 simplified()->LoadField( |
| 972 AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)), | 971 AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)), |
| 973 NodeProperties::GetValueInput(node, 0), effect, control)); | 972 NodeProperties::GetValueInput(node, 0), effect, control)); |
| 974 } | 973 } |
| 975 node->set_op( | 974 node->RemoveInput(2); |
| 975 NodeProperties::ChangeOp( |
| 976 node, |
| 976 simplified()->StoreField(AccessBuilder::ForContextSlot(access.index()))); | 977 simplified()->StoreField(AccessBuilder::ForContextSlot(access.index()))); |
| 977 node->RemoveInput(2); | |
| 978 DCHECK_EQ(4, node->InputCount()); | |
| 979 return Changed(node); | 978 return Changed(node); |
| 980 } | 979 } |
| 981 | 980 |
| 982 | 981 |
| 983 Reduction JSTypedLowering::ReduceJSLoadDynamicGlobal(Node* node) { | 982 Reduction JSTypedLowering::ReduceJSLoadDynamicGlobal(Node* node) { |
| 984 DCHECK_EQ(IrOpcode::kJSLoadDynamicGlobal, node->opcode()); | 983 DCHECK_EQ(IrOpcode::kJSLoadDynamicGlobal, node->opcode()); |
| 985 DynamicGlobalAccess const& access = DynamicGlobalAccessOf(node->op()); | 984 DynamicGlobalAccess const& access = DynamicGlobalAccessOf(node->op()); |
| 986 Node* const vector = NodeProperties::GetValueInput(node, 0); | 985 Node* const vector = NodeProperties::GetValueInput(node, 0); |
| 987 Node* const context = NodeProperties::GetContextInput(node); | 986 Node* const context = NodeProperties::GetContextInput(node); |
| 988 Node* const state1 = NodeProperties::GetFrameStateInput(node, 0); | 987 Node* const state1 = NodeProperties::GetFrameStateInput(node, 0); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1000 if ((bitset & 1) == 0) continue; | 999 if ((bitset & 1) == 0) continue; |
| 1001 Node* load = graph()->NewNode( | 1000 Node* load = graph()->NewNode( |
| 1002 javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false), | 1001 javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false), |
| 1003 context, context, effect); | 1002 context, context, effect); |
| 1004 Node* check = graph()->NewNode(simplified()->ReferenceEqual(Type::Tagged()), | 1003 Node* check = graph()->NewNode(simplified()->ReferenceEqual(Type::Tagged()), |
| 1005 load, jsgraph()->ZeroConstant()); | 1004 load, jsgraph()->ZeroConstant()); |
| 1006 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), check, | 1005 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), check, |
| 1007 check_true); | 1006 check_true); |
| 1008 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 1007 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 1009 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 1008 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 1010 check_false->set_op(common()->Merge(check_false->InputCount() + 1)); | |
| 1011 check_false->AppendInput(graph()->zone(), if_false); | 1009 check_false->AppendInput(graph()->zone(), if_false); |
| 1010 NodeProperties::ChangeOp(check_false, |
| 1011 common()->Merge(check_false->InputCount())); |
| 1012 check_true = if_true; | 1012 check_true = if_true; |
| 1013 } | 1013 } |
| 1014 | 1014 |
| 1015 // Fast case, because variable is not shadowed. Perform global object load. | 1015 // Fast case, because variable is not shadowed. Perform global object load. |
| 1016 Node* global = graph()->NewNode( | 1016 Node* global = graph()->NewNode( |
| 1017 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true), context, | 1017 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true), context, |
| 1018 context, effect); | 1018 context, effect); |
| 1019 Node* fast = graph()->NewNode( | 1019 Node* fast = graph()->NewNode( |
| 1020 javascript()->LoadGlobal(access.name(), access.feedback(), | 1020 javascript()->LoadGlobal(access.name(), access.feedback(), |
| 1021 access.typeof_mode()), | 1021 access.typeof_mode()), |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 if ((bitset & 1) == 0) continue; | 1059 if ((bitset & 1) == 0) continue; |
| 1060 Node* load = graph()->NewNode( | 1060 Node* load = graph()->NewNode( |
| 1061 javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false), | 1061 javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false), |
| 1062 context, context, effect); | 1062 context, context, effect); |
| 1063 Node* check = graph()->NewNode(simplified()->ReferenceEqual(Type::Tagged()), | 1063 Node* check = graph()->NewNode(simplified()->ReferenceEqual(Type::Tagged()), |
| 1064 load, jsgraph()->ZeroConstant()); | 1064 load, jsgraph()->ZeroConstant()); |
| 1065 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), check, | 1065 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), check, |
| 1066 check_true); | 1066 check_true); |
| 1067 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 1067 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 1068 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 1068 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 1069 check_false->set_op(common()->Merge(check_false->InputCount() + 1)); | |
| 1070 check_false->AppendInput(graph()->zone(), if_false); | 1069 check_false->AppendInput(graph()->zone(), if_false); |
| 1070 NodeProperties::ChangeOp(check_false, |
| 1071 common()->Merge(check_false->InputCount())); |
| 1071 check_true = if_true; | 1072 check_true = if_true; |
| 1072 } | 1073 } |
| 1073 | 1074 |
| 1074 // Fast case, because variable is not shadowed. Perform context slot load. | 1075 // Fast case, because variable is not shadowed. Perform context slot load. |
| 1075 Node* fast = | 1076 Node* fast = |
| 1076 graph()->NewNode(javascript()->LoadContext(context_access.depth(), | 1077 graph()->NewNode(javascript()->LoadContext(context_access.depth(), |
| 1077 context_access.index(), false), | 1078 context_access.index(), false), |
| 1078 context, context, effect); | 1079 context, context, effect); |
| 1079 | 1080 |
| 1080 // Slow case, because variable potentially shadowed. Perform dynamic lookup. | 1081 // Slow case, because variable potentially shadowed. Perform dynamic lookup. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1108 Isolate* isolate = jsgraph()->isolate(); | 1109 Isolate* isolate = jsgraph()->isolate(); |
| 1109 Callable callable = CodeFactory::FastNewClosure( | 1110 Callable callable = CodeFactory::FastNewClosure( |
| 1110 isolate, shared->language_mode(), shared->kind()); | 1111 isolate, shared->language_mode(), shared->kind()); |
| 1111 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 1112 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 1112 isolate, graph()->zone(), callable.descriptor(), 0, | 1113 isolate, graph()->zone(), callable.descriptor(), 0, |
| 1113 CallDescriptor::kNoFlags); | 1114 CallDescriptor::kNoFlags); |
| 1114 const Operator* new_op = common()->Call(desc); | 1115 const Operator* new_op = common()->Call(desc); |
| 1115 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | 1116 Node* stub_code = jsgraph()->HeapConstant(callable.code()); |
| 1116 node->InsertInput(graph()->zone(), 0, stub_code); | 1117 node->InsertInput(graph()->zone(), 0, stub_code); |
| 1117 node->InsertInput(graph()->zone(), 1, jsgraph()->HeapConstant(shared)); | 1118 node->InsertInput(graph()->zone(), 1, jsgraph()->HeapConstant(shared)); |
| 1118 node->set_op(new_op); | 1119 NodeProperties::ChangeOp(node, new_op); |
| 1119 return Changed(node); | 1120 return Changed(node); |
| 1120 } | 1121 } |
| 1121 | 1122 |
| 1122 return NoChange(); | 1123 return NoChange(); |
| 1123 } | 1124 } |
| 1124 | 1125 |
| 1125 | 1126 |
| 1126 Reduction JSTypedLowering::ReduceJSCreateLiteralArray(Node* node) { | 1127 Reduction JSTypedLowering::ReduceJSCreateLiteralArray(Node* node) { |
| 1127 DCHECK_EQ(IrOpcode::kJSCreateLiteralArray, node->opcode()); | 1128 DCHECK_EQ(IrOpcode::kJSCreateLiteralArray, node->opcode()); |
| 1128 HeapObjectMatcher mconst(NodeProperties::GetValueInput(node, 2)); | 1129 HeapObjectMatcher mconst(NodeProperties::GetValueInput(node, 2)); |
| 1129 int length = Handle<FixedArray>::cast(mconst.Value())->length(); | 1130 int length = Handle<FixedArray>::cast(mconst.Value())->length(); |
| 1130 int flags = OpParameter<int>(node->op()); | 1131 int flags = OpParameter<int>(node->op()); |
| 1131 | 1132 |
| 1132 // Use the FastCloneShallowArrayStub only for shallow boilerplates up to the | 1133 // Use the FastCloneShallowArrayStub only for shallow boilerplates up to the |
| 1133 // initial length limit for arrays with "fast" elements kind. | 1134 // initial length limit for arrays with "fast" elements kind. |
| 1134 // TODO(rossberg): Teach strong mode to FastCloneShallowArrayStub. | 1135 // TODO(rossberg): Teach strong mode to FastCloneShallowArrayStub. |
| 1135 if ((flags & ArrayLiteral::kShallowElements) != 0 && | 1136 if ((flags & ArrayLiteral::kShallowElements) != 0 && |
| 1136 (flags & ArrayLiteral::kIsStrong) == 0 && | 1137 (flags & ArrayLiteral::kIsStrong) == 0 && |
| 1137 length < JSObject::kInitialMaxFastElementArray) { | 1138 length < JSObject::kInitialMaxFastElementArray) { |
| 1138 Isolate* isolate = jsgraph()->isolate(); | 1139 Isolate* isolate = jsgraph()->isolate(); |
| 1139 Callable callable = CodeFactory::FastCloneShallowArray(isolate); | 1140 Callable callable = CodeFactory::FastCloneShallowArray(isolate); |
| 1140 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 1141 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 1141 isolate, graph()->zone(), callable.descriptor(), 0, | 1142 isolate, graph()->zone(), callable.descriptor(), 0, |
| 1142 (OperatorProperties::GetFrameStateInputCount(node->op()) != 0) | 1143 (OperatorProperties::GetFrameStateInputCount(node->op()) != 0) |
| 1143 ? CallDescriptor::kNeedsFrameState | 1144 ? CallDescriptor::kNeedsFrameState |
| 1144 : CallDescriptor::kNoFlags); | 1145 : CallDescriptor::kNoFlags); |
| 1145 const Operator* new_op = common()->Call(desc); | 1146 const Operator* new_op = common()->Call(desc); |
| 1146 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | 1147 Node* stub_code = jsgraph()->HeapConstant(callable.code()); |
| 1147 node->InsertInput(graph()->zone(), 0, stub_code); | 1148 node->InsertInput(graph()->zone(), 0, stub_code); |
| 1148 node->set_op(new_op); | 1149 NodeProperties::ChangeOp(node, new_op); |
| 1149 return Changed(node); | 1150 return Changed(node); |
| 1150 } | 1151 } |
| 1151 | 1152 |
| 1152 return NoChange(); | 1153 return NoChange(); |
| 1153 } | 1154 } |
| 1154 | 1155 |
| 1155 | 1156 |
| 1156 Reduction JSTypedLowering::ReduceJSCreateLiteralObject(Node* node) { | 1157 Reduction JSTypedLowering::ReduceJSCreateLiteralObject(Node* node) { |
| 1157 DCHECK_EQ(IrOpcode::kJSCreateLiteralObject, node->opcode()); | 1158 DCHECK_EQ(IrOpcode::kJSCreateLiteralObject, node->opcode()); |
| 1158 HeapObjectMatcher mconst(NodeProperties::GetValueInput(node, 2)); | 1159 HeapObjectMatcher mconst(NodeProperties::GetValueInput(node, 2)); |
| 1159 // Constants are pairs, see ObjectLiteral::properties_count(). | 1160 // Constants are pairs, see ObjectLiteral::properties_count(). |
| 1160 int length = Handle<FixedArray>::cast(mconst.Value())->length() / 2; | 1161 int length = Handle<FixedArray>::cast(mconst.Value())->length() / 2; |
| 1161 int flags = OpParameter<int>(node->op()); | 1162 int flags = OpParameter<int>(node->op()); |
| 1162 | 1163 |
| 1163 // Use the FastCloneShallowObjectStub only for shallow boilerplates without | 1164 // Use the FastCloneShallowObjectStub only for shallow boilerplates without |
| 1164 // elements up to the number of properties that the stubs can handle. | 1165 // elements up to the number of properties that the stubs can handle. |
| 1165 if ((flags & ObjectLiteral::kShallowProperties) != 0 && | 1166 if ((flags & ObjectLiteral::kShallowProperties) != 0 && |
| 1166 length <= FastCloneShallowObjectStub::kMaximumClonedProperties) { | 1167 length <= FastCloneShallowObjectStub::kMaximumClonedProperties) { |
| 1167 Isolate* isolate = jsgraph()->isolate(); | 1168 Isolate* isolate = jsgraph()->isolate(); |
| 1168 Callable callable = CodeFactory::FastCloneShallowObject(isolate, length); | 1169 Callable callable = CodeFactory::FastCloneShallowObject(isolate, length); |
| 1169 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 1170 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 1170 isolate, graph()->zone(), callable.descriptor(), 0, | 1171 isolate, graph()->zone(), callable.descriptor(), 0, |
| 1171 (OperatorProperties::GetFrameStateInputCount(node->op()) != 0) | 1172 (OperatorProperties::GetFrameStateInputCount(node->op()) != 0) |
| 1172 ? CallDescriptor::kNeedsFrameState | 1173 ? CallDescriptor::kNeedsFrameState |
| 1173 : CallDescriptor::kNoFlags); | 1174 : CallDescriptor::kNoFlags); |
| 1174 const Operator* new_op = common()->Call(desc); | 1175 const Operator* new_op = common()->Call(desc); |
| 1175 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | 1176 Node* stub_code = jsgraph()->HeapConstant(callable.code()); |
| 1176 node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(flags)); | 1177 node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(flags)); |
| 1177 node->InsertInput(graph()->zone(), 0, stub_code); | 1178 node->InsertInput(graph()->zone(), 0, stub_code); |
| 1178 node->set_op(new_op); | 1179 NodeProperties::ChangeOp(node, new_op); |
| 1179 return Changed(node); | 1180 return Changed(node); |
| 1180 } | 1181 } |
| 1181 | 1182 |
| 1182 return NoChange(); | 1183 return NoChange(); |
| 1183 } | 1184 } |
| 1184 | 1185 |
| 1185 | 1186 |
| 1186 Reduction JSTypedLowering::ReduceJSCreateWithContext(Node* node) { | 1187 Reduction JSTypedLowering::ReduceJSCreateWithContext(Node* node) { |
| 1187 DCHECK_EQ(IrOpcode::kJSCreateWithContext, node->opcode()); | 1188 DCHECK_EQ(IrOpcode::kJSCreateWithContext, node->opcode()); |
| 1188 Node* const input = NodeProperties::GetValueInput(node, 0); | 1189 Node* const input = NodeProperties::GetValueInput(node, 0); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1202 a.AllocateArray(Context::MIN_CONTEXT_SLOTS, factory()->with_context_map()); | 1203 a.AllocateArray(Context::MIN_CONTEXT_SLOTS, factory()->with_context_map()); |
| 1203 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); | 1204 a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure); |
| 1204 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); | 1205 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context); |
| 1205 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), input); | 1206 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), input); |
| 1206 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); | 1207 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); |
| 1207 // TODO(mstarzinger): We could mutate {node} into the allocation instead. | 1208 // TODO(mstarzinger): We could mutate {node} into the allocation instead. |
| 1208 NodeProperties::SetType(a.allocation(), NodeProperties::GetType(node)); | 1209 NodeProperties::SetType(a.allocation(), NodeProperties::GetType(node)); |
| 1209 ReplaceWithValue(node, node, a.effect()); | 1210 ReplaceWithValue(node, node, a.effect()); |
| 1210 node->ReplaceInput(0, a.allocation()); | 1211 node->ReplaceInput(0, a.allocation()); |
| 1211 node->ReplaceInput(1, a.effect()); | 1212 node->ReplaceInput(1, a.effect()); |
| 1212 node->set_op(common()->Finish(1)); | |
| 1213 node->TrimInputCount(2); | 1213 node->TrimInputCount(2); |
| 1214 NodeProperties::ChangeOp(node, common()->Finish(1)); |
| 1214 return Changed(node); | 1215 return Changed(node); |
| 1215 } | 1216 } |
| 1216 return NoChange(); | 1217 return NoChange(); |
| 1217 } | 1218 } |
| 1218 | 1219 |
| 1219 | 1220 |
| 1220 Reduction JSTypedLowering::ReduceJSCreateBlockContext(Node* node) { | 1221 Reduction JSTypedLowering::ReduceJSCreateBlockContext(Node* node) { |
| 1221 DCHECK_EQ(IrOpcode::kJSCreateBlockContext, node->opcode()); | 1222 DCHECK_EQ(IrOpcode::kJSCreateBlockContext, node->opcode()); |
| 1222 Node* const input = NodeProperties::GetValueInput(node, 0); | 1223 Node* const input = NodeProperties::GetValueInput(node, 0); |
| 1223 HeapObjectMatcher minput(input); | 1224 HeapObjectMatcher minput(input); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1241 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), input); | 1242 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), input); |
| 1242 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); | 1243 a.Store(AccessBuilder::ForContextSlot(Context::GLOBAL_OBJECT_INDEX), load); |
| 1243 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) { | 1244 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) { |
| 1244 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->TheHoleConstant()); | 1245 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->TheHoleConstant()); |
| 1245 } | 1246 } |
| 1246 // TODO(mstarzinger): We could mutate {node} into the allocation instead. | 1247 // TODO(mstarzinger): We could mutate {node} into the allocation instead. |
| 1247 NodeProperties::SetType(a.allocation(), NodeProperties::GetType(node)); | 1248 NodeProperties::SetType(a.allocation(), NodeProperties::GetType(node)); |
| 1248 ReplaceWithValue(node, node, a.effect()); | 1249 ReplaceWithValue(node, node, a.effect()); |
| 1249 node->ReplaceInput(0, a.allocation()); | 1250 node->ReplaceInput(0, a.allocation()); |
| 1250 node->ReplaceInput(1, a.effect()); | 1251 node->ReplaceInput(1, a.effect()); |
| 1251 node->set_op(common()->Finish(1)); | |
| 1252 node->TrimInputCount(2); | 1252 node->TrimInputCount(2); |
| 1253 NodeProperties::ChangeOp(node, common()->Finish(1)); |
| 1253 return Changed(node); | 1254 return Changed(node); |
| 1254 } | 1255 } |
| 1255 return NoChange(); | 1256 return NoChange(); |
| 1256 } | 1257 } |
| 1257 | 1258 |
| 1258 | 1259 |
| 1259 Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) { | 1260 Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) { |
| 1260 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); | 1261 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); |
| 1261 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); | 1262 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); |
| 1262 int const arity = static_cast<int>(p.arity() - 2); | 1263 int const arity = static_cast<int>(p.arity() - 2); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1273 // Check that the {receiver} doesn't need to be wrapped. | 1274 // Check that the {receiver} doesn't need to be wrapped. |
| 1274 if (receiver_type->Is(Type::ReceiverOrUndefined())) { | 1275 if (receiver_type->Is(Type::ReceiverOrUndefined())) { |
| 1275 Node* const context = graph()->NewNode( | 1276 Node* const context = graph()->NewNode( |
| 1276 simplified()->LoadField(AccessBuilder::ForJSFunctionContext()), | 1277 simplified()->LoadField(AccessBuilder::ForJSFunctionContext()), |
| 1277 function, effect, control); | 1278 function, effect, control); |
| 1278 NodeProperties::ReplaceContextInput(node, context); | 1279 NodeProperties::ReplaceContextInput(node, context); |
| 1279 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; | 1280 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; |
| 1280 if (is_strict(p.language_mode())) { | 1281 if (is_strict(p.language_mode())) { |
| 1281 flags |= CallDescriptor::kSupportsTailCalls; | 1282 flags |= CallDescriptor::kSupportsTailCalls; |
| 1282 } | 1283 } |
| 1283 node->set_op(common()->Call(Linkage::GetJSCallDescriptor( | 1284 NodeProperties::ChangeOp(node, |
| 1284 graph()->zone(), false, 1 + arity, flags))); | 1285 common()->Call(Linkage::GetJSCallDescriptor( |
| 1286 graph()->zone(), false, 1 + arity, flags))); |
| 1285 return Changed(node); | 1287 return Changed(node); |
| 1286 } | 1288 } |
| 1287 } | 1289 } |
| 1288 return NoChange(); | 1290 return NoChange(); |
| 1289 } | 1291 } |
| 1290 | 1292 |
| 1291 | 1293 |
| 1292 Reduction JSTypedLowering::ReduceJSForInDone(Node* node) { | 1294 Reduction JSTypedLowering::ReduceJSForInDone(Node* node) { |
| 1293 DCHECK_EQ(IrOpcode::kJSForInDone, node->opcode()); | 1295 DCHECK_EQ(IrOpcode::kJSForInDone, node->opcode()); |
| 1294 node->set_op(machine()->Word32Equal()); | |
| 1295 node->TrimInputCount(2); | 1296 node->TrimInputCount(2); |
| 1297 NodeProperties::ChangeOp(node, machine()->Word32Equal()); |
| 1296 return Changed(node); | 1298 return Changed(node); |
| 1297 } | 1299 } |
| 1298 | 1300 |
| 1299 | 1301 |
| 1300 Reduction JSTypedLowering::ReduceJSForInPrepare(Node* node) { | 1302 Reduction JSTypedLowering::ReduceJSForInPrepare(Node* node) { |
| 1301 DCHECK_EQ(IrOpcode::kJSForInPrepare, node->opcode()); | 1303 DCHECK_EQ(IrOpcode::kJSForInPrepare, node->opcode()); |
| 1302 Node* receiver = NodeProperties::GetValueInput(node, 0); | 1304 Node* receiver = NodeProperties::GetValueInput(node, 0); |
| 1303 Node* context = NodeProperties::GetContextInput(node); | 1305 Node* context = NodeProperties::GetContextInput(node); |
| 1304 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); | 1306 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); |
| 1305 Node* effect = NodeProperties::GetEffectInput(node); | 1307 Node* effect = NodeProperties::GetEffectInput(node); |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1533 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | 1535 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
| 1534 efalse0 = | 1536 efalse0 = |
| 1535 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0); | 1537 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0); |
| 1536 vfalse0 = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), vtrue1, | 1538 vfalse0 = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), vtrue1, |
| 1537 vfalse1, if_false0); | 1539 vfalse1, if_false0); |
| 1538 } | 1540 } |
| 1539 | 1541 |
| 1540 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); | 1542 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
| 1541 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); | 1543 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
| 1542 ReplaceWithValue(node, node, effect, control); | 1544 ReplaceWithValue(node, node, effect, control); |
| 1543 node->set_op(common()->Phi(kMachAnyTagged, 2)); | |
| 1544 node->ReplaceInput(0, vtrue0); | 1545 node->ReplaceInput(0, vtrue0); |
| 1545 node->ReplaceInput(1, vfalse0); | 1546 node->ReplaceInput(1, vfalse0); |
| 1546 node->ReplaceInput(2, control); | 1547 node->ReplaceInput(2, control); |
| 1547 node->TrimInputCount(3); | 1548 node->TrimInputCount(3); |
| 1549 NodeProperties::ChangeOp(node, common()->Phi(kMachAnyTagged, 2)); |
| 1548 return Changed(node); | 1550 return Changed(node); |
| 1549 } | 1551 } |
| 1550 | 1552 |
| 1551 | 1553 |
| 1552 Reduction JSTypedLowering::ReduceJSForInStep(Node* node) { | 1554 Reduction JSTypedLowering::ReduceJSForInStep(Node* node) { |
| 1553 DCHECK_EQ(IrOpcode::kJSForInStep, node->opcode()); | 1555 DCHECK_EQ(IrOpcode::kJSForInStep, node->opcode()); |
| 1554 node->set_op(machine()->Int32Add()); | |
| 1555 node->ReplaceInput(1, jsgraph()->Int32Constant(1)); | 1556 node->ReplaceInput(1, jsgraph()->Int32Constant(1)); |
| 1556 DCHECK_EQ(2, node->InputCount()); | 1557 NodeProperties::ChangeOp(node, machine()->Int32Add()); |
| 1557 return Changed(node); | 1558 return Changed(node); |
| 1558 } | 1559 } |
| 1559 | 1560 |
| 1560 | 1561 |
| 1561 Reduction JSTypedLowering::Reduce(Node* node) { | 1562 Reduction JSTypedLowering::Reduce(Node* node) { |
| 1562 // Check if the output type is a singleton. In that case we already know the | 1563 // Check if the output type is a singleton. In that case we already know the |
| 1563 // result value and can simply replace the node if it's eliminable. | 1564 // result value and can simply replace the node if it's eliminable. |
| 1564 if (!NodeProperties::IsConstant(node) && NodeProperties::IsTyped(node) && | 1565 if (!NodeProperties::IsConstant(node) && NodeProperties::IsTyped(node) && |
| 1565 node->op()->HasProperty(Operator::kEliminatable)) { | 1566 node->op()->HasProperty(Operator::kEliminatable)) { |
| 1566 Type* upper = NodeProperties::GetType(node); | 1567 Type* upper = NodeProperties::GetType(node); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1704 } | 1705 } |
| 1705 | 1706 |
| 1706 | 1707 |
| 1707 MachineOperatorBuilder* JSTypedLowering::machine() const { | 1708 MachineOperatorBuilder* JSTypedLowering::machine() const { |
| 1708 return jsgraph()->machine(); | 1709 return jsgraph()->machine(); |
| 1709 } | 1710 } |
| 1710 | 1711 |
| 1711 } // namespace compiler | 1712 } // namespace compiler |
| 1712 } // namespace internal | 1713 } // namespace internal |
| 1713 } // namespace v8 | 1714 } // namespace v8 |
| OLD | NEW |