| 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 |