OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
6 | 6 |
| 7 #include <limits> |
| 8 |
7 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
8 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
9 #include "src/compiler/common-operator.h" | 11 #include "src/compiler/common-operator.h" |
10 #include "src/compiler/graph-inl.h" | 12 #include "src/compiler/graph-inl.h" |
11 #include "src/compiler/node-matchers.h" | 13 #include "src/compiler/node-matchers.h" |
12 #include "src/compiler/node-properties-inl.h" | 14 #include "src/compiler/node-properties-inl.h" |
13 #include "src/compiler/representation-change.h" | 15 #include "src/compiler/representation-change.h" |
14 #include "src/compiler/simplified-lowering.h" | 16 #include "src/compiler/simplified-lowering.h" |
15 #include "src/compiler/simplified-operator.h" | 17 #include "src/compiler/simplified-operator.h" |
16 #include "src/objects.h" | 18 #include "src/objects.h" |
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 SetOutput(node, 0); | 660 SetOutput(node, 0); |
659 if (lower()) lowering->DoStoreField(node); | 661 if (lower()) lowering->DoStoreField(node); |
660 break; | 662 break; |
661 } | 663 } |
662 case IrOpcode::kLoadElement: { | 664 case IrOpcode::kLoadElement: { |
663 ElementAccess access = ElementAccessOf(node->op()); | 665 ElementAccess access = ElementAccessOf(node->op()); |
664 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); | 666 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); |
665 ProcessInput(node, 1, kMachInt32); // element index | 667 ProcessInput(node, 1, kMachInt32); // element index |
666 ProcessInput(node, 2, kMachInt32); // length | 668 ProcessInput(node, 2, kMachInt32); // length |
667 ProcessRemainingInputs(node, 3); | 669 ProcessRemainingInputs(node, 3); |
668 SetOutput(node, access.machine_type); | 670 // Tagged overrides everything if we have to do a typed array bounds |
669 if (lower()) lowering->DoLoadElement(node); | 671 // check, because we may need to return undefined then. |
| 672 MachineType output_type = |
| 673 (access.bounds_check == kTypedArrayBoundsCheck && |
| 674 (use & kRepTagged)) |
| 675 ? kMachAnyTagged |
| 676 : access.machine_type; |
| 677 SetOutput(node, output_type); |
| 678 if (lower()) lowering->DoLoadElement(node, output_type); |
670 break; | 679 break; |
671 } | 680 } |
672 case IrOpcode::kStoreElement: { | 681 case IrOpcode::kStoreElement: { |
673 ElementAccess access = ElementAccessOf(node->op()); | 682 ElementAccess access = ElementAccessOf(node->op()); |
674 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); | 683 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); |
675 ProcessInput(node, 1, kMachInt32); // element index | 684 ProcessInput(node, 1, kMachInt32); // element index |
676 ProcessInput(node, 2, kMachInt32); // length | 685 ProcessInput(node, 2, kMachInt32); // length |
677 ProcessInput(node, 3, access.machine_type); | 686 ProcessInput(node, 3, access.machine_type); |
678 ProcessRemainingInputs(node, 4); | 687 ProcessRemainingInputs(node, 4); |
679 SetOutput(node, 0); | 688 SetOutput(node, 0); |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
950 index = graph()->NewNode(machine()->Int32Mul(), | 959 index = graph()->NewNode(machine()->Int32Mul(), |
951 jsgraph()->Int32Constant(element_size), index); | 960 jsgraph()->Int32Constant(element_size), index); |
952 } | 961 } |
953 int fixed_offset = access.header_size - access.tag(); | 962 int fixed_offset = access.header_size - access.tag(); |
954 if (fixed_offset == 0) return index; | 963 if (fixed_offset == 0) return index; |
955 return graph()->NewNode(machine()->Int32Add(), index, | 964 return graph()->NewNode(machine()->Int32Add(), index, |
956 jsgraph()->Int32Constant(fixed_offset)); | 965 jsgraph()->Int32Constant(fixed_offset)); |
957 } | 966 } |
958 | 967 |
959 | 968 |
960 void SimplifiedLowering::DoLoadElement(Node* node) { | 969 void SimplifiedLowering::DoLoadElement(Node* node, MachineType output_type) { |
961 const ElementAccess& access = ElementAccessOf(node->op()); | 970 const ElementAccess& access = ElementAccessOf(node->op()); |
962 node->set_op(machine()->Load(access.machine_type)); | 971 const Operator* op = machine()->Load(access.machine_type); |
963 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); | 972 Node* key = node->InputAt(1); |
964 node->RemoveInput(2); | 973 Node* index = ComputeIndex(access, key); |
| 974 if (access.bounds_check == kNoBoundsCheck) { |
| 975 DCHECK_EQ(access.machine_type, output_type); |
| 976 node->set_op(op); |
| 977 node->ReplaceInput(1, index); |
| 978 node->RemoveInput(2); |
| 979 } else { |
| 980 DCHECK_EQ(kTypedArrayBoundsCheck, access.bounds_check); |
| 981 |
| 982 Node* base = node->InputAt(0); |
| 983 Node* length = node->InputAt(2); |
| 984 Node* effect = node->InputAt(3); |
| 985 Node* control = node->InputAt(4); |
| 986 |
| 987 Node* check = graph()->NewNode(machine()->Uint32LessThan(), key, length); |
| 988 Node* branch = graph()->NewNode(common()->Branch(), check, control); |
| 989 |
| 990 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 991 Node* load = graph()->NewNode(op, base, index, effect, if_true); |
| 992 Node* result = load; |
| 993 if (output_type & kRepTagged) { |
| 994 // TODO(turbofan): This is ugly as hell! |
| 995 SimplifiedOperatorBuilder simplified(graph()->zone()); |
| 996 RepresentationChanger changer(jsgraph(), &simplified, |
| 997 graph()->zone()->isolate()); |
| 998 result = changer.GetTaggedRepresentationFor(result, access.machine_type); |
| 999 } |
| 1000 |
| 1001 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 1002 Node* undefined; |
| 1003 if (output_type & kRepTagged) { |
| 1004 DCHECK(!(access.machine_type & kRepTagged)); |
| 1005 undefined = jsgraph()->UndefinedConstant(); |
| 1006 } else if (output_type & kRepFloat32) { |
| 1007 undefined = |
| 1008 jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN()); |
| 1009 } else if (output_type & kRepFloat64) { |
| 1010 undefined = |
| 1011 jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN()); |
| 1012 } else { |
| 1013 undefined = jsgraph()->Int32Constant(0); |
| 1014 } |
| 1015 |
| 1016 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 1017 Node* phi = graph()->NewNode(common()->EffectPhi(2), load, effect, merge); |
| 1018 |
| 1019 // Replace effect uses of node with the effect phi. |
| 1020 for (UseIter i = node->uses().begin(); i != node->uses().end();) { |
| 1021 if (NodeProperties::IsEffectEdge(i.edge())) { |
| 1022 i = i.UpdateToAndIncrement(phi); |
| 1023 } else { |
| 1024 ++i; |
| 1025 } |
| 1026 } |
| 1027 |
| 1028 node->set_op(common()->Phi(output_type, 2)); |
| 1029 node->ReplaceInput(0, result); |
| 1030 node->ReplaceInput(1, undefined); |
| 1031 node->ReplaceInput(2, merge); |
| 1032 node->TrimInputCount(3); |
| 1033 } |
965 } | 1034 } |
966 | 1035 |
967 | 1036 |
968 void SimplifiedLowering::DoStoreElement(Node* node) { | 1037 void SimplifiedLowering::DoStoreElement(Node* node) { |
969 const ElementAccess& access = ElementAccessOf(node->op()); | 1038 const ElementAccess& access = ElementAccessOf(node->op()); |
970 const Operator* op = machine()->Store(StoreRepresentation( | 1039 const Operator* op = machine()->Store(StoreRepresentation( |
971 access.machine_type, | 1040 access.machine_type, |
972 ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type, | 1041 ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type, |
973 access.type))); | 1042 access.type))); |
974 Node* key = node->InputAt(1); | 1043 Node* key = node->InputAt(1); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1055 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { | 1124 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { |
1056 node->set_op(machine()->IntLessThanOrEqual()); | 1125 node->set_op(machine()->IntLessThanOrEqual()); |
1057 node->ReplaceInput(0, StringComparison(node, true)); | 1126 node->ReplaceInput(0, StringComparison(node, true)); |
1058 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1127 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
1059 } | 1128 } |
1060 | 1129 |
1061 | 1130 |
1062 } // namespace compiler | 1131 } // namespace compiler |
1063 } // namespace internal | 1132 } // namespace internal |
1064 } // namespace v8 | 1133 } // namespace v8 |
OLD | NEW |