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 "src/compiler/instruction-selector-impl.h" | 7 #include "src/compiler/instruction-selector-impl.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" |
10 #include "src/compiler/pipeline.h" | 10 #include "src/compiler/pipeline.h" |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 bool InstructionSelector::IsDouble(const Node* node) const { | 191 bool InstructionSelector::IsDouble(const Node* node) const { |
192 DCHECK_NOT_NULL(node); | 192 DCHECK_NOT_NULL(node); |
193 return sequence()->IsDouble(node->id()); | 193 return sequence()->IsDouble(node->id()); |
194 } | 194 } |
195 | 195 |
196 | 196 |
197 void InstructionSelector::MarkAsDouble(Node* node) { | 197 void InstructionSelector::MarkAsDouble(Node* node) { |
198 DCHECK_NOT_NULL(node); | 198 DCHECK_NOT_NULL(node); |
199 DCHECK(!IsReference(node)); | 199 DCHECK(!IsReference(node)); |
200 sequence()->MarkAsDouble(node->id()); | 200 sequence()->MarkAsDouble(node->id()); |
201 | |
202 // Propagate "doubleness" throughout Phi nodes. | |
203 for (UseIter i = node->uses().begin(); i != node->uses().end(); ++i) { | |
204 Node* user = *i; | |
205 switch (user->opcode()) { | |
206 case IrOpcode::kPhi: | |
207 if (IsDouble(user)) continue; | |
208 MarkAsDouble(user); | |
209 break; | |
210 default: | |
211 break; | |
212 } | |
213 } | |
214 } | 201 } |
215 | 202 |
216 | 203 |
217 bool InstructionSelector::IsReference(const Node* node) const { | 204 bool InstructionSelector::IsReference(const Node* node) const { |
218 DCHECK_NOT_NULL(node); | 205 DCHECK_NOT_NULL(node); |
219 return sequence()->IsReference(node->id()); | 206 return sequence()->IsReference(node->id()); |
220 } | 207 } |
221 | 208 |
222 | 209 |
223 void InstructionSelector::MarkAsReference(Node* node) { | 210 void InstructionSelector::MarkAsReference(Node* node) { |
224 DCHECK_NOT_NULL(node); | 211 DCHECK_NOT_NULL(node); |
225 DCHECK(!IsDouble(node)); | 212 DCHECK(!IsDouble(node)); |
226 sequence()->MarkAsReference(node->id()); | 213 sequence()->MarkAsReference(node->id()); |
227 | |
228 // Propagate "referenceness" throughout Phi nodes. | |
229 for (UseIter i = node->uses().begin(); i != node->uses().end(); ++i) { | |
230 Node* user = *i; | |
231 switch (user->opcode()) { | |
232 case IrOpcode::kPhi: | |
233 if (IsReference(user)) continue; | |
234 MarkAsReference(user); | |
235 break; | |
236 default: | |
237 break; | |
238 } | |
239 } | |
240 } | 214 } |
241 | 215 |
242 | 216 |
243 void InstructionSelector::MarkAsRepresentation(MachineType rep, Node* node) { | 217 void InstructionSelector::MarkAsRepresentation(MachineType rep, Node* node) { |
244 DCHECK_NOT_NULL(node); | 218 DCHECK_NOT_NULL(node); |
245 switch (RepresentationOf(rep)) { | 219 switch (RepresentationOf(rep)) { |
246 case kRepFloat32: | 220 case kRepFloat32: |
247 case kRepFloat64: | 221 case kRepFloat64: |
248 MarkAsDouble(node); | 222 MarkAsDouble(node); |
249 break; | 223 break; |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 case IrOpcode::kMerge: | 458 case IrOpcode::kMerge: |
485 // No code needed for these graph artifacts. | 459 // No code needed for these graph artifacts. |
486 return; | 460 return; |
487 case IrOpcode::kFinish: | 461 case IrOpcode::kFinish: |
488 return MarkAsReference(node), VisitFinish(node); | 462 return MarkAsReference(node), VisitFinish(node); |
489 case IrOpcode::kParameter: { | 463 case IrOpcode::kParameter: { |
490 MachineType type = linkage()->GetParameterType(OpParameter<int>(node)); | 464 MachineType type = linkage()->GetParameterType(OpParameter<int>(node)); |
491 MarkAsRepresentation(type, node); | 465 MarkAsRepresentation(type, node); |
492 return VisitParameter(node); | 466 return VisitParameter(node); |
493 } | 467 } |
494 case IrOpcode::kPhi: | 468 case IrOpcode::kPhi: { |
| 469 MachineType type = OpParameter<MachineType>(node); |
| 470 MarkAsRepresentation(type, node); |
495 return VisitPhi(node); | 471 return VisitPhi(node); |
| 472 } |
496 case IrOpcode::kProjection: | 473 case IrOpcode::kProjection: |
497 return VisitProjection(node); | 474 return VisitProjection(node); |
498 case IrOpcode::kInt32Constant: | 475 case IrOpcode::kInt32Constant: |
499 case IrOpcode::kInt64Constant: | 476 case IrOpcode::kInt64Constant: |
500 case IrOpcode::kExternalConstant: | 477 case IrOpcode::kExternalConstant: |
501 return VisitConstant(node); | 478 return VisitConstant(node); |
502 case IrOpcode::kFloat64Constant: | 479 case IrOpcode::kFloat64Constant: |
503 return MarkAsDouble(node), VisitConstant(node); | 480 return MarkAsDouble(node), VisitConstant(node); |
504 case IrOpcode::kHeapConstant: | 481 case IrOpcode::kHeapConstant: |
505 case IrOpcode::kNumberConstant: | 482 case IrOpcode::kNumberConstant: |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
838 } | 815 } |
839 } | 816 } |
840 | 817 |
841 | 818 |
842 void InstructionSelector::VisitProjection(Node* node) { | 819 void InstructionSelector::VisitProjection(Node* node) { |
843 OperandGenerator g(this); | 820 OperandGenerator g(this); |
844 Node* value = node->InputAt(0); | 821 Node* value = node->InputAt(0); |
845 switch (value->opcode()) { | 822 switch (value->opcode()) { |
846 case IrOpcode::kInt32AddWithOverflow: | 823 case IrOpcode::kInt32AddWithOverflow: |
847 case IrOpcode::kInt32SubWithOverflow: | 824 case IrOpcode::kInt32SubWithOverflow: |
848 if (OpParameter<int32_t>(node) == 0) { | 825 if (OpParameter<int>(node) == 0) { |
849 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); | 826 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); |
850 } else { | 827 } else { |
851 DCHECK_EQ(1, OpParameter<int32_t>(node)); | 828 DCHECK_EQ(1, OpParameter<int>(node)); |
852 MarkAsUsed(value); | 829 MarkAsUsed(value); |
853 } | 830 } |
854 break; | 831 break; |
855 default: | 832 default: |
856 break; | 833 break; |
857 } | 834 } |
858 } | 835 } |
859 | 836 |
860 | 837 |
861 void InstructionSelector::VisitConstant(Node* node) { | 838 void InstructionSelector::VisitConstant(Node* node) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 return VisitFloat64Compare(value, &cont); | 926 return VisitFloat64Compare(value, &cont); |
950 case IrOpcode::kFloat64LessThan: | 927 case IrOpcode::kFloat64LessThan: |
951 cont.OverwriteAndNegateIfEqual(kUnorderedLessThan); | 928 cont.OverwriteAndNegateIfEqual(kUnorderedLessThan); |
952 return VisitFloat64Compare(value, &cont); | 929 return VisitFloat64Compare(value, &cont); |
953 case IrOpcode::kFloat64LessThanOrEqual: | 930 case IrOpcode::kFloat64LessThanOrEqual: |
954 cont.OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual); | 931 cont.OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual); |
955 return VisitFloat64Compare(value, &cont); | 932 return VisitFloat64Compare(value, &cont); |
956 case IrOpcode::kProjection: | 933 case IrOpcode::kProjection: |
957 // Check if this is the overflow output projection of an | 934 // Check if this is the overflow output projection of an |
958 // <Operation>WithOverflow node. | 935 // <Operation>WithOverflow node. |
959 if (OpParameter<int32_t>(value) == 1) { | 936 if (OpParameter<int>(value) == 1) { |
960 // We cannot combine the <Operation>WithOverflow with this branch | 937 // We cannot combine the <Operation>WithOverflow with this branch |
961 // unless the 0th projection (the use of the actual value of the | 938 // unless the 0th projection (the use of the actual value of the |
962 // <Operation> is either NULL, which means there's no use of the | 939 // <Operation> is either NULL, which means there's no use of the |
963 // actual value, or was already defined, which means it is scheduled | 940 // actual value, or was already defined, which means it is scheduled |
964 // *AFTER* this branch). | 941 // *AFTER* this branch). |
965 Node* node = value->InputAt(0); | 942 Node* node = value->InputAt(0); |
966 Node* result = node->FindProjection(0); | 943 Node* result = node->FindProjection(0); |
967 if (result == NULL || IsDefined(result)) { | 944 if (result == NULL || IsDefined(result)) { |
968 switch (node->opcode()) { | 945 switch (node->opcode()) { |
969 case IrOpcode::kInt32AddWithOverflow: | 946 case IrOpcode::kInt32AddWithOverflow: |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 | 1088 |
1112 | 1089 |
1113 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, | 1090 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, |
1114 BasicBlock* deoptimization) {} | 1091 BasicBlock* deoptimization) {} |
1115 | 1092 |
1116 #endif // !V8_TURBOFAN_BACKEND | 1093 #endif // !V8_TURBOFAN_BACKEND |
1117 | 1094 |
1118 } // namespace compiler | 1095 } // namespace compiler |
1119 } // namespace internal | 1096 } // namespace internal |
1120 } // namespace v8 | 1097 } // namespace v8 |
OLD | NEW |