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 (CanProduceSignallingNaN(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 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1282 void InstructionSelector::VisitStackSlot(Node* node) { | 1289 void InstructionSelector::VisitStackSlot(Node* node) { |
1283 int size = 1 << ElementSizeLog2Of(StackSlotRepresentationOf(node->op())); | 1290 int size = 1 << ElementSizeLog2Of(StackSlotRepresentationOf(node->op())); |
1284 int slot = frame_->AllocateSpillSlot(size); | 1291 int slot = frame_->AllocateSpillSlot(size); |
1285 OperandGenerator g(this); | 1292 OperandGenerator g(this); |
1286 | 1293 |
1287 Emit(kArchStackSlot, g.DefineAsRegister(node), | 1294 Emit(kArchStackSlot, g.DefineAsRegister(node), |
1288 sequence()->AddImmediate(Constant(slot)), 0, nullptr); | 1295 sequence()->AddImmediate(Constant(slot)), 0, nullptr); |
1289 } | 1296 } |
1290 | 1297 |
1291 void InstructionSelector::VisitBitcastWordToTagged(Node* node) { | 1298 void InstructionSelector::VisitBitcastWordToTagged(Node* node) { |
1292 OperandGenerator g(this); | 1299 EmitIdentity(node); |
1293 Node* value = node->InputAt(0); | |
1294 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); | |
1295 } | 1300 } |
1296 | 1301 |
1297 // 32 bit targets do not implement the following instructions. | 1302 // 32 bit targets do not implement the following instructions. |
1298 #if V8_TARGET_ARCH_32_BIT | 1303 #if V8_TARGET_ARCH_32_BIT |
1299 | 1304 |
1300 void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); } | 1305 void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); } |
1301 | 1306 |
1302 | 1307 |
1303 void InstructionSelector::VisitWord64Or(Node* node) { UNIMPLEMENTED(); } | 1308 void InstructionSelector::VisitWord64Or(Node* node) { UNIMPLEMENTED(); } |
1304 | 1309 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1456 | 1461 |
1457 void InstructionSelector::VisitInt32PairMul(Node* node) { UNIMPLEMENTED(); } | 1462 void InstructionSelector::VisitInt32PairMul(Node* node) { UNIMPLEMENTED(); } |
1458 | 1463 |
1459 void InstructionSelector::VisitWord32PairShl(Node* node) { UNIMPLEMENTED(); } | 1464 void InstructionSelector::VisitWord32PairShl(Node* node) { UNIMPLEMENTED(); } |
1460 | 1465 |
1461 void InstructionSelector::VisitWord32PairShr(Node* node) { UNIMPLEMENTED(); } | 1466 void InstructionSelector::VisitWord32PairShr(Node* node) { UNIMPLEMENTED(); } |
1462 | 1467 |
1463 void InstructionSelector::VisitWord32PairSar(Node* node) { UNIMPLEMENTED(); } | 1468 void InstructionSelector::VisitWord32PairSar(Node* node) { UNIMPLEMENTED(); } |
1464 #endif // V8_TARGET_ARCH_64_BIT | 1469 #endif // V8_TARGET_ARCH_64_BIT |
1465 | 1470 |
1466 void InstructionSelector::VisitFinishRegion(Node* node) { | 1471 void InstructionSelector::VisitFinishRegion(Node* node) { EmitIdentity(node); } |
1467 OperandGenerator g(this); | |
1468 Node* value = node->InputAt(0); | |
1469 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); | |
1470 } | |
1471 | |
1472 | 1472 |
1473 void InstructionSelector::VisitParameter(Node* node) { | 1473 void InstructionSelector::VisitParameter(Node* node) { |
1474 OperandGenerator g(this); | 1474 OperandGenerator g(this); |
1475 int index = ParameterIndexOf(node->op()); | 1475 int index = ParameterIndexOf(node->op()); |
1476 InstructionOperand op = | 1476 InstructionOperand op = |
1477 linkage()->ParameterHasSecondaryLocation(index) | 1477 linkage()->ParameterHasSecondaryLocation(index) |
1478 ? g.DefineAsDualLocation( | 1478 ? g.DefineAsDualLocation( |
1479 node, linkage()->GetParameterLocation(index), | 1479 node, linkage()->GetParameterLocation(index), |
1480 linkage()->GetParameterSecondaryLocation(index)) | 1480 linkage()->GetParameterSecondaryLocation(index)) |
1481 : g.DefineAsLocation( | 1481 : g.DefineAsLocation( |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1787 sequence()->AddFrameStateDescriptor(descriptor); | 1787 sequence()->AddFrameStateDescriptor(descriptor); |
1788 args.push_back(g.TempImmediate(state_id.ToInt())); | 1788 args.push_back(g.TempImmediate(state_id.ToInt())); |
1789 StateObjectDeduplicator deduplicator(instruction_zone()); | 1789 StateObjectDeduplicator deduplicator(instruction_zone()); |
1790 AddInputsToFrameStateDescriptor(descriptor, frame_state, &g, &deduplicator, | 1790 AddInputsToFrameStateDescriptor(descriptor, frame_state, &g, &deduplicator, |
1791 &args, FrameStateInputKind::kAny, | 1791 &args, FrameStateInputKind::kAny, |
1792 instruction_zone()); | 1792 instruction_zone()); |
1793 return Emit(opcode, output_count, outputs, args.size(), &args.front(), 0, | 1793 return Emit(opcode, output_count, outputs, args.size(), &args.front(), 0, |
1794 nullptr); | 1794 nullptr); |
1795 } | 1795 } |
1796 | 1796 |
| 1797 void InstructionSelector::EmitIdentity(Node* node) { |
| 1798 OperandGenerator g(this); |
| 1799 Node* value = node->InputAt(0); |
| 1800 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); |
| 1801 } |
| 1802 |
1797 void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind, Node* value) { | 1803 void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind, Node* value) { |
1798 InstructionCode opcode = kArchDeoptimize; | 1804 InstructionCode opcode = kArchDeoptimize; |
1799 switch (kind) { | 1805 switch (kind) { |
1800 case DeoptimizeKind::kEager: | 1806 case DeoptimizeKind::kEager: |
1801 opcode |= MiscField::encode(Deoptimizer::EAGER); | 1807 opcode |= MiscField::encode(Deoptimizer::EAGER); |
1802 break; | 1808 break; |
1803 case DeoptimizeKind::kSoft: | 1809 case DeoptimizeKind::kSoft: |
1804 opcode |= MiscField::encode(Deoptimizer::SOFT); | 1810 opcode |= MiscField::encode(Deoptimizer::SOFT); |
1805 break; | 1811 break; |
1806 } | 1812 } |
(...skipping 10 matching lines...) Expand all Loading... |
1817 OperandGenerator g(this); | 1823 OperandGenerator g(this); |
1818 Emit(kArchDebugBreak, g.NoOutput()); | 1824 Emit(kArchDebugBreak, g.NoOutput()); |
1819 } | 1825 } |
1820 | 1826 |
1821 void InstructionSelector::VisitComment(Node* node) { | 1827 void InstructionSelector::VisitComment(Node* node) { |
1822 OperandGenerator g(this); | 1828 OperandGenerator g(this); |
1823 InstructionOperand operand(g.UseImmediate(node)); | 1829 InstructionOperand operand(g.UseImmediate(node)); |
1824 Emit(kArchComment, 0, nullptr, 1, &operand); | 1830 Emit(kArchComment, 0, nullptr, 1, &operand); |
1825 } | 1831 } |
1826 | 1832 |
| 1833 bool InstructionSelector::CanProduceSignallingNaN(Node* node) { |
| 1834 // TODO(jarin) Improve the heuristic here. |
| 1835 if (node->opcode() == IrOpcode::kFloat64Add || |
| 1836 node->opcode() == IrOpcode::kFloat64Sub || |
| 1837 node->opcode() == IrOpcode::kFloat64Mul) { |
| 1838 return false; |
| 1839 } |
| 1840 return true; |
| 1841 } |
| 1842 |
1827 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( | 1843 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( |
1828 Node* state) { | 1844 Node* state) { |
1829 DCHECK(state->opcode() == IrOpcode::kFrameState); | 1845 DCHECK(state->opcode() == IrOpcode::kFrameState); |
1830 DCHECK_EQ(kFrameStateInputCount, state->InputCount()); | 1846 DCHECK_EQ(kFrameStateInputCount, state->InputCount()); |
1831 FrameStateInfo state_info = OpParameter<FrameStateInfo>(state); | 1847 FrameStateInfo state_info = OpParameter<FrameStateInfo>(state); |
1832 | 1848 |
1833 int parameters = static_cast<int>( | 1849 int parameters = static_cast<int>( |
1834 StateValuesAccess(state->InputAt(kFrameStateParametersInput)).size()); | 1850 StateValuesAccess(state->InputAt(kFrameStateParametersInput)).size()); |
1835 int locals = static_cast<int>( | 1851 int locals = static_cast<int>( |
1836 StateValuesAccess(state->InputAt(kFrameStateLocalsInput)).size()); | 1852 StateValuesAccess(state->InputAt(kFrameStateLocalsInput)).size()); |
(...skipping 12 matching lines...) Expand all Loading... |
1849 return new (instruction_zone()) FrameStateDescriptor( | 1865 return new (instruction_zone()) FrameStateDescriptor( |
1850 instruction_zone(), state_info.type(), state_info.bailout_id(), | 1866 instruction_zone(), state_info.type(), state_info.bailout_id(), |
1851 state_info.state_combine(), parameters, locals, stack, | 1867 state_info.state_combine(), parameters, locals, stack, |
1852 state_info.shared_info(), outer_state); | 1868 state_info.shared_info(), outer_state); |
1853 } | 1869 } |
1854 | 1870 |
1855 | 1871 |
1856 } // namespace compiler | 1872 } // namespace compiler |
1857 } // namespace internal | 1873 } // namespace internal |
1858 } // namespace v8 | 1874 } // namespace v8 |
OLD | NEW |