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