| 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> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 if (lower()) DeferReplacement(node, node->InputAt(0)); | 732 if (lower()) DeferReplacement(node, node->InputAt(0)); |
| 733 } else { | 733 } else { |
| 734 // Require the input in float64 format and perform truncation. | 734 // Require the input in float64 format and perform truncation. |
| 735 // TODO(turbofan): avoid a truncation with a smi check. | 735 // TODO(turbofan): avoid a truncation with a smi check. |
| 736 VisitUnop(node, kTypeUint32 | kRepFloat64, kTypeUint32 | kRepWord32); | 736 VisitUnop(node, kTypeUint32 | kRepFloat64, kTypeUint32 | kRepWord32); |
| 737 if (lower()) | 737 if (lower()) |
| 738 node->set_op(lowering->machine()->TruncateFloat64ToInt32()); | 738 node->set_op(lowering->machine()->TruncateFloat64ToInt32()); |
| 739 } | 739 } |
| 740 break; | 740 break; |
| 741 } | 741 } |
| 742 case IrOpcode::kPlainPrimitiveToNumber: { | |
| 743 VisitUnop(node, kMachAnyTagged, kTypeNumber | kRepTagged); | |
| 744 if (lower()) { | |
| 745 // PlainPrimitiveToNumber(x) => Call(ToNumberStub, x, no-context) | |
| 746 Operator::Properties properties = node->op()->properties(); | |
| 747 Callable callable = CodeFactory::ToNumber(jsgraph_->isolate()); | |
| 748 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | |
| 749 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | |
| 750 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, | |
| 751 flags, properties); | |
| 752 node->set_op(jsgraph_->common()->Call(desc)); | |
| 753 node->InsertInput(jsgraph_->zone(), 0, | |
| 754 jsgraph_->HeapConstant(callable.code())); | |
| 755 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); | |
| 756 } | |
| 757 break; | |
| 758 } | |
| 759 case IrOpcode::kReferenceEqual: { | 742 case IrOpcode::kReferenceEqual: { |
| 760 VisitBinop(node, kMachAnyTagged, kRepBit); | 743 VisitBinop(node, kMachAnyTagged, kRepBit); |
| 761 if (lower()) node->set_op(lowering->machine()->WordEqual()); | 744 if (lower()) node->set_op(lowering->machine()->WordEqual()); |
| 762 break; | 745 break; |
| 763 } | 746 } |
| 764 case IrOpcode::kStringEqual: { | 747 case IrOpcode::kStringEqual: { |
| 765 VisitBinop(node, kMachAnyTagged, kRepBit); | 748 VisitBinop(node, kMachAnyTagged, kRepBit); |
| 766 if (lower()) lowering->DoStringEqual(node); | 749 if (lower()) lowering->DoStringEqual(node); |
| 767 break; | 750 break; |
| 768 } | 751 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 SetOutput(node, 0); | 787 SetOutput(node, 0); |
| 805 if (lower()) lowering->DoStoreField(node); | 788 if (lower()) lowering->DoStoreField(node); |
| 806 break; | 789 break; |
| 807 } | 790 } |
| 808 case IrOpcode::kLoadBuffer: { | 791 case IrOpcode::kLoadBuffer: { |
| 809 BufferAccess access = BufferAccessOf(node->op()); | 792 BufferAccess access = BufferAccessOf(node->op()); |
| 810 ProcessInput(node, 0, kMachPtr); // buffer | 793 ProcessInput(node, 0, kMachPtr); // buffer |
| 811 ProcessInput(node, 1, kMachInt32); // offset | 794 ProcessInput(node, 1, kMachInt32); // offset |
| 812 ProcessInput(node, 2, kMachInt32); // length | 795 ProcessInput(node, 2, kMachInt32); // length |
| 813 ProcessRemainingInputs(node, 3); | 796 ProcessRemainingInputs(node, 3); |
| 814 // Tagged overrides everything if we have to do a typed array bounds | 797 SetOutput(node, access.machine_type()); |
| 815 // check, because we may need to return undefined then. | 798 if (lower()) lowering->DoLoadBuffer(node); |
| 816 MachineType output_type; | |
| 817 if (use & kRepTagged) { | |
| 818 output_type = kMachAnyTagged; | |
| 819 } else if (use & kRepFloat64) { | |
| 820 if (access.machine_type() & kRepFloat32) { | |
| 821 output_type = access.machine_type(); | |
| 822 } else { | |
| 823 output_type = kMachFloat64; | |
| 824 } | |
| 825 } else if (use & kRepFloat32) { | |
| 826 output_type = kMachFloat32; | |
| 827 } else { | |
| 828 output_type = access.machine_type(); | |
| 829 } | |
| 830 SetOutput(node, output_type); | |
| 831 if (lower()) lowering->DoLoadBuffer(node, output_type, changer_); | |
| 832 break; | 799 break; |
| 833 } | 800 } |
| 834 case IrOpcode::kStoreBuffer: { | 801 case IrOpcode::kStoreBuffer: { |
| 835 BufferAccess access = BufferAccessOf(node->op()); | 802 BufferAccess access = BufferAccessOf(node->op()); |
| 836 ProcessInput(node, 0, kMachPtr); // buffer | 803 ProcessInput(node, 0, kMachPtr); // buffer |
| 837 ProcessInput(node, 1, kMachInt32); // offset | 804 ProcessInput(node, 1, kMachInt32); // offset |
| 838 ProcessInput(node, 2, kMachInt32); // length | 805 ProcessInput(node, 2, kMachInt32); // length |
| 839 ProcessInput(node, 3, access.machine_type()); // value | 806 ProcessInput(node, 3, access.machine_type()); // value |
| 840 ProcessRemainingInputs(node, 4); | 807 ProcessRemainingInputs(node, 4); |
| 841 SetOutput(node, 0); | 808 SetOutput(node, 0); |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1217 if (machine()->Is64()) { | 1184 if (machine()->Is64()) { |
| 1218 // TODO(turbofan): This is probably only correct for typed arrays, and only | 1185 // TODO(turbofan): This is probably only correct for typed arrays, and only |
| 1219 // if the typed arrays are at most 2GiB in size, which happens to match | 1186 // if the typed arrays are at most 2GiB in size, which happens to match |
| 1220 // exactly our current situation. | 1187 // exactly our current situation. |
| 1221 index = graph()->NewNode(machine()->ChangeUint32ToUint64(), index); | 1188 index = graph()->NewNode(machine()->ChangeUint32ToUint64(), index); |
| 1222 } | 1189 } |
| 1223 return index; | 1190 return index; |
| 1224 } | 1191 } |
| 1225 | 1192 |
| 1226 | 1193 |
| 1227 void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type, | 1194 void SimplifiedLowering::DoLoadBuffer(Node* node) { |
| 1228 RepresentationChanger* changer) { | |
| 1229 DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode()); | 1195 DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode()); |
| 1230 DCHECK_NE(kMachNone, RepresentationOf(output_type)); | |
| 1231 MachineType const type = BufferAccessOf(node->op()).machine_type(); | 1196 MachineType const type = BufferAccessOf(node->op()).machine_type(); |
| 1232 if (output_type != type) { | 1197 node->set_op(machine()->CheckedLoad(type)); |
| 1233 Node* const buffer = node->InputAt(0); | |
| 1234 Node* const offset = node->InputAt(1); | |
| 1235 Node* const length = node->InputAt(2); | |
| 1236 Node* const effect = node->InputAt(3); | |
| 1237 Node* const control = node->InputAt(4); | |
| 1238 Node* const index = | |
| 1239 machine()->Is64() | |
| 1240 ? graph()->NewNode(machine()->ChangeUint32ToUint64(), offset) | |
| 1241 : offset; | |
| 1242 | |
| 1243 Node* check = graph()->NewNode(machine()->Uint32LessThan(), offset, length); | |
| 1244 Node* branch = | |
| 1245 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | |
| 1246 | |
| 1247 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | |
| 1248 Node* etrue = | |
| 1249 graph()->NewNode(machine()->Load(type), buffer, index, effect, if_true); | |
| 1250 Node* vtrue = changer->GetRepresentationFor(etrue, type, output_type); | |
| 1251 | |
| 1252 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
| 1253 Node* efalse = effect; | |
| 1254 Node* vfalse; | |
| 1255 if (output_type & kRepTagged) { | |
| 1256 vfalse = jsgraph()->UndefinedConstant(); | |
| 1257 } else if (output_type & kRepFloat64) { | |
| 1258 vfalse = | |
| 1259 jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN()); | |
| 1260 } else if (output_type & kRepFloat32) { | |
| 1261 vfalse = | |
| 1262 jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN()); | |
| 1263 } else { | |
| 1264 vfalse = jsgraph()->Int32Constant(0); | |
| 1265 } | |
| 1266 | |
| 1267 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); | |
| 1268 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge); | |
| 1269 | |
| 1270 // Replace effect uses of {node} with the {ephi}. | |
| 1271 NodeProperties::ReplaceWithValue(node, node, ephi); | |
| 1272 | |
| 1273 // Turn the {node} into a Phi. | |
| 1274 node->set_op(common()->Phi(output_type, 2)); | |
| 1275 node->ReplaceInput(0, vtrue); | |
| 1276 node->ReplaceInput(1, vfalse); | |
| 1277 node->ReplaceInput(2, merge); | |
| 1278 node->TrimInputCount(3); | |
| 1279 } else { | |
| 1280 node->set_op(machine()->CheckedLoad(type)); | |
| 1281 } | |
| 1282 } | 1198 } |
| 1283 | 1199 |
| 1284 | 1200 |
| 1285 void SimplifiedLowering::DoStoreBuffer(Node* node) { | 1201 void SimplifiedLowering::DoStoreBuffer(Node* node) { |
| 1286 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); | 1202 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); |
| 1287 MachineType const type = BufferAccessOf(node->op()).machine_type(); | 1203 MachineType const type = BufferAccessOf(node->op()).machine_type(); |
| 1288 node->set_op(machine()->CheckedStore(type)); | 1204 node->set_op(machine()->CheckedStore(type)); |
| 1289 } | 1205 } |
| 1290 | 1206 |
| 1291 | 1207 |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1607 | 1523 |
| 1608 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { | 1524 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { |
| 1609 node->set_op(machine()->IntLessThanOrEqual()); | 1525 node->set_op(machine()->IntLessThanOrEqual()); |
| 1610 node->ReplaceInput(0, StringComparison(node, true)); | 1526 node->ReplaceInput(0, StringComparison(node, true)); |
| 1611 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1527 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
| 1612 } | 1528 } |
| 1613 | 1529 |
| 1614 } // namespace compiler | 1530 } // namespace compiler |
| 1615 } // namespace internal | 1531 } // namespace internal |
| 1616 } // namespace v8 | 1532 } // namespace v8 |
| OLD | NEW |