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/instruction-selector.h" | 5 #include "src/compiler/instruction-selector.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/adapters.h" | 9 #include "src/base/adapters.h" |
10 #include "src/compiler/instruction-selector-impl.h" | 10 #include "src/compiler/instruction-selector-impl.h" |
(...skipping 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 case IrOpcode::kChangeFloat32ToFloat64: | 1028 case IrOpcode::kChangeFloat32ToFloat64: |
1029 return MarkAsFloat64(node), VisitChangeFloat32ToFloat64(node); | 1029 return MarkAsFloat64(node), VisitChangeFloat32ToFloat64(node); |
1030 case IrOpcode::kChangeInt32ToFloat64: | 1030 case IrOpcode::kChangeInt32ToFloat64: |
1031 return MarkAsFloat64(node), VisitChangeInt32ToFloat64(node); | 1031 return MarkAsFloat64(node), VisitChangeInt32ToFloat64(node); |
1032 case IrOpcode::kChangeUint32ToFloat64: | 1032 case IrOpcode::kChangeUint32ToFloat64: |
1033 return MarkAsFloat64(node), VisitChangeUint32ToFloat64(node); | 1033 return MarkAsFloat64(node), VisitChangeUint32ToFloat64(node); |
1034 case IrOpcode::kChangeFloat64ToInt32: | 1034 case IrOpcode::kChangeFloat64ToInt32: |
1035 return MarkAsWord32(node), VisitChangeFloat64ToInt32(node); | 1035 return MarkAsWord32(node), VisitChangeFloat64ToInt32(node); |
1036 case IrOpcode::kChangeFloat64ToUint32: | 1036 case IrOpcode::kChangeFloat64ToUint32: |
1037 return MarkAsWord32(node), VisitChangeFloat64ToUint32(node); | 1037 return MarkAsWord32(node), VisitChangeFloat64ToUint32(node); |
| 1038 case IrOpcode::kFloat64SilenceNaN: |
| 1039 MarkAsFloat64(node); |
| 1040 if (CanProduceSignalingNaN(node->InputAt(0))) { |
| 1041 return VisitFloat64SilenceNaN(node); |
| 1042 } else { |
| 1043 return EmitIdentity(node); |
| 1044 } |
1038 case IrOpcode::kTruncateFloat64ToUint32: | 1045 case IrOpcode::kTruncateFloat64ToUint32: |
1039 return MarkAsWord32(node), VisitTruncateFloat64ToUint32(node); | 1046 return MarkAsWord32(node), VisitTruncateFloat64ToUint32(node); |
1040 case IrOpcode::kTruncateFloat32ToInt32: | 1047 case IrOpcode::kTruncateFloat32ToInt32: |
1041 return MarkAsWord32(node), VisitTruncateFloat32ToInt32(node); | 1048 return MarkAsWord32(node), VisitTruncateFloat32ToInt32(node); |
1042 case IrOpcode::kTruncateFloat32ToUint32: | 1049 case IrOpcode::kTruncateFloat32ToUint32: |
1043 return MarkAsWord32(node), VisitTruncateFloat32ToUint32(node); | 1050 return MarkAsWord32(node), VisitTruncateFloat32ToUint32(node); |
1044 case IrOpcode::kTryTruncateFloat32ToInt64: | 1051 case IrOpcode::kTryTruncateFloat32ToInt64: |
1045 return MarkAsWord64(node), VisitTryTruncateFloat32ToInt64(node); | 1052 return MarkAsWord64(node), VisitTryTruncateFloat32ToInt64(node); |
1046 case IrOpcode::kTryTruncateFloat64ToInt64: | 1053 case IrOpcode::kTryTruncateFloat64ToInt64: |
1047 return MarkAsWord64(node), VisitTryTruncateFloat64ToInt64(node); | 1054 return MarkAsWord64(node), VisitTryTruncateFloat64ToInt64(node); |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1294 void InstructionSelector::VisitStackSlot(Node* node) { | 1301 void InstructionSelector::VisitStackSlot(Node* node) { |
1295 int size = 1 << ElementSizeLog2Of(StackSlotRepresentationOf(node->op())); | 1302 int size = 1 << ElementSizeLog2Of(StackSlotRepresentationOf(node->op())); |
1296 int slot = frame_->AllocateSpillSlot(size); | 1303 int slot = frame_->AllocateSpillSlot(size); |
1297 OperandGenerator g(this); | 1304 OperandGenerator g(this); |
1298 | 1305 |
1299 Emit(kArchStackSlot, g.DefineAsRegister(node), | 1306 Emit(kArchStackSlot, g.DefineAsRegister(node), |
1300 sequence()->AddImmediate(Constant(slot)), 0, nullptr); | 1307 sequence()->AddImmediate(Constant(slot)), 0, nullptr); |
1301 } | 1308 } |
1302 | 1309 |
1303 void InstructionSelector::VisitBitcastWordToTagged(Node* node) { | 1310 void InstructionSelector::VisitBitcastWordToTagged(Node* node) { |
1304 OperandGenerator g(this); | 1311 EmitIdentity(node); |
1305 Node* value = node->InputAt(0); | |
1306 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); | |
1307 } | 1312 } |
1308 | 1313 |
1309 // 32 bit targets do not implement the following instructions. | 1314 // 32 bit targets do not implement the following instructions. |
1310 #if V8_TARGET_ARCH_32_BIT | 1315 #if V8_TARGET_ARCH_32_BIT |
1311 | 1316 |
1312 void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); } | 1317 void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); } |
1313 | 1318 |
1314 | 1319 |
1315 void InstructionSelector::VisitWord64Or(Node* node) { UNIMPLEMENTED(); } | 1320 void InstructionSelector::VisitWord64Or(Node* node) { UNIMPLEMENTED(); } |
1316 | 1321 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1468 | 1473 |
1469 void InstructionSelector::VisitInt32PairMul(Node* node) { UNIMPLEMENTED(); } | 1474 void InstructionSelector::VisitInt32PairMul(Node* node) { UNIMPLEMENTED(); } |
1470 | 1475 |
1471 void InstructionSelector::VisitWord32PairShl(Node* node) { UNIMPLEMENTED(); } | 1476 void InstructionSelector::VisitWord32PairShl(Node* node) { UNIMPLEMENTED(); } |
1472 | 1477 |
1473 void InstructionSelector::VisitWord32PairShr(Node* node) { UNIMPLEMENTED(); } | 1478 void InstructionSelector::VisitWord32PairShr(Node* node) { UNIMPLEMENTED(); } |
1474 | 1479 |
1475 void InstructionSelector::VisitWord32PairSar(Node* node) { UNIMPLEMENTED(); } | 1480 void InstructionSelector::VisitWord32PairSar(Node* node) { UNIMPLEMENTED(); } |
1476 #endif // V8_TARGET_ARCH_64_BIT | 1481 #endif // V8_TARGET_ARCH_64_BIT |
1477 | 1482 |
1478 void InstructionSelector::VisitFinishRegion(Node* node) { | 1483 void InstructionSelector::VisitFinishRegion(Node* node) { EmitIdentity(node); } |
1479 OperandGenerator g(this); | |
1480 Node* value = node->InputAt(0); | |
1481 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); | |
1482 } | |
1483 | |
1484 | 1484 |
1485 void InstructionSelector::VisitParameter(Node* node) { | 1485 void InstructionSelector::VisitParameter(Node* node) { |
1486 OperandGenerator g(this); | 1486 OperandGenerator g(this); |
1487 int index = ParameterIndexOf(node->op()); | 1487 int index = ParameterIndexOf(node->op()); |
1488 InstructionOperand op = | 1488 InstructionOperand op = |
1489 linkage()->ParameterHasSecondaryLocation(index) | 1489 linkage()->ParameterHasSecondaryLocation(index) |
1490 ? g.DefineAsDualLocation( | 1490 ? g.DefineAsDualLocation( |
1491 node, linkage()->GetParameterLocation(index), | 1491 node, linkage()->GetParameterLocation(index), |
1492 linkage()->GetParameterSecondaryLocation(index)) | 1492 linkage()->GetParameterSecondaryLocation(index)) |
1493 : g.DefineAsLocation( | 1493 : g.DefineAsLocation( |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1799 sequence()->AddFrameStateDescriptor(descriptor); | 1799 sequence()->AddFrameStateDescriptor(descriptor); |
1800 args.push_back(g.TempImmediate(state_id.ToInt())); | 1800 args.push_back(g.TempImmediate(state_id.ToInt())); |
1801 StateObjectDeduplicator deduplicator(instruction_zone()); | 1801 StateObjectDeduplicator deduplicator(instruction_zone()); |
1802 AddInputsToFrameStateDescriptor(descriptor, frame_state, &g, &deduplicator, | 1802 AddInputsToFrameStateDescriptor(descriptor, frame_state, &g, &deduplicator, |
1803 &args, FrameStateInputKind::kAny, | 1803 &args, FrameStateInputKind::kAny, |
1804 instruction_zone()); | 1804 instruction_zone()); |
1805 return Emit(opcode, output_count, outputs, args.size(), &args.front(), 0, | 1805 return Emit(opcode, output_count, outputs, args.size(), &args.front(), 0, |
1806 nullptr); | 1806 nullptr); |
1807 } | 1807 } |
1808 | 1808 |
| 1809 void InstructionSelector::EmitIdentity(Node* node) { |
| 1810 OperandGenerator g(this); |
| 1811 Node* value = node->InputAt(0); |
| 1812 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); |
| 1813 } |
| 1814 |
1809 void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind, Node* value) { | 1815 void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind, Node* value) { |
1810 InstructionCode opcode = kArchDeoptimize; | 1816 InstructionCode opcode = kArchDeoptimize; |
1811 switch (kind) { | 1817 switch (kind) { |
1812 case DeoptimizeKind::kEager: | 1818 case DeoptimizeKind::kEager: |
1813 opcode |= MiscField::encode(Deoptimizer::EAGER); | 1819 opcode |= MiscField::encode(Deoptimizer::EAGER); |
1814 break; | 1820 break; |
1815 case DeoptimizeKind::kSoft: | 1821 case DeoptimizeKind::kSoft: |
1816 opcode |= MiscField::encode(Deoptimizer::SOFT); | 1822 opcode |= MiscField::encode(Deoptimizer::SOFT); |
1817 break; | 1823 break; |
1818 } | 1824 } |
(...skipping 10 matching lines...) Expand all Loading... |
1829 OperandGenerator g(this); | 1835 OperandGenerator g(this); |
1830 Emit(kArchDebugBreak, g.NoOutput()); | 1836 Emit(kArchDebugBreak, g.NoOutput()); |
1831 } | 1837 } |
1832 | 1838 |
1833 void InstructionSelector::VisitComment(Node* node) { | 1839 void InstructionSelector::VisitComment(Node* node) { |
1834 OperandGenerator g(this); | 1840 OperandGenerator g(this); |
1835 InstructionOperand operand(g.UseImmediate(node)); | 1841 InstructionOperand operand(g.UseImmediate(node)); |
1836 Emit(kArchComment, 0, nullptr, 1, &operand); | 1842 Emit(kArchComment, 0, nullptr, 1, &operand); |
1837 } | 1843 } |
1838 | 1844 |
| 1845 bool InstructionSelector::CanProduceSignalingNaN(Node* node) { |
| 1846 // TODO(jarin) Improve the heuristic here. |
| 1847 if (node->opcode() == IrOpcode::kFloat64Add || |
| 1848 node->opcode() == IrOpcode::kFloat64Sub || |
| 1849 node->opcode() == IrOpcode::kFloat64Mul) { |
| 1850 return false; |
| 1851 } |
| 1852 return true; |
| 1853 } |
| 1854 |
1839 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( | 1855 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( |
1840 Node* state) { | 1856 Node* state) { |
1841 DCHECK(state->opcode() == IrOpcode::kFrameState); | 1857 DCHECK(state->opcode() == IrOpcode::kFrameState); |
1842 DCHECK_EQ(kFrameStateInputCount, state->InputCount()); | 1858 DCHECK_EQ(kFrameStateInputCount, state->InputCount()); |
1843 FrameStateInfo state_info = OpParameter<FrameStateInfo>(state); | 1859 FrameStateInfo state_info = OpParameter<FrameStateInfo>(state); |
1844 | 1860 |
1845 int parameters = static_cast<int>( | 1861 int parameters = static_cast<int>( |
1846 StateValuesAccess(state->InputAt(kFrameStateParametersInput)).size()); | 1862 StateValuesAccess(state->InputAt(kFrameStateParametersInput)).size()); |
1847 int locals = static_cast<int>( | 1863 int locals = static_cast<int>( |
1848 StateValuesAccess(state->InputAt(kFrameStateLocalsInput)).size()); | 1864 StateValuesAccess(state->InputAt(kFrameStateLocalsInput)).size()); |
(...skipping 12 matching lines...) Expand all Loading... |
1861 return new (instruction_zone()) FrameStateDescriptor( | 1877 return new (instruction_zone()) FrameStateDescriptor( |
1862 instruction_zone(), state_info.type(), state_info.bailout_id(), | 1878 instruction_zone(), state_info.type(), state_info.bailout_id(), |
1863 state_info.state_combine(), parameters, locals, stack, | 1879 state_info.state_combine(), parameters, locals, stack, |
1864 state_info.shared_info(), outer_state); | 1880 state_info.shared_info(), outer_state); |
1865 } | 1881 } |
1866 | 1882 |
1867 | 1883 |
1868 } // namespace compiler | 1884 } // namespace compiler |
1869 } // namespace internal | 1885 } // namespace internal |
1870 } // namespace v8 | 1886 } // namespace v8 |
OLD | NEW |