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 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 buffer->output_nodes.push_back(call); | 291 buffer->output_nodes.push_back(call); |
292 } else { | 292 } else { |
293 buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), NULL); | 293 buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), NULL); |
294 call->CollectProjections(&buffer->output_nodes); | 294 call->CollectProjections(&buffer->output_nodes); |
295 } | 295 } |
296 | 296 |
297 // Filter out the outputs that aren't live because no projection uses them. | 297 // Filter out the outputs that aren't live because no projection uses them. |
298 for (size_t i = 0; i < buffer->output_nodes.size(); i++) { | 298 for (size_t i = 0; i < buffer->output_nodes.size(); i++) { |
299 if (buffer->output_nodes[i] != NULL) { | 299 if (buffer->output_nodes[i] != NULL) { |
300 Node* output = buffer->output_nodes[i]; | 300 Node* output = buffer->output_nodes[i]; |
| 301 MachineType type = |
| 302 buffer->descriptor->GetReturnType(static_cast<int>(i)); |
301 LinkageLocation location = | 303 LinkageLocation location = |
302 buffer->descriptor->GetReturnLocation(static_cast<int>(i)); | 304 buffer->descriptor->GetReturnLocation(static_cast<int>(i)); |
303 MarkAsRepresentation(location.representation(), output); | 305 MarkAsRepresentation(type, output); |
304 buffer->outputs.push_back(g.DefineAsLocation(output, location)); | 306 buffer->outputs.push_back(g.DefineAsLocation(output, location, type)); |
305 } | 307 } |
306 } | 308 } |
307 } | 309 } |
308 | 310 |
309 // The first argument is always the callee code. | 311 // The first argument is always the callee code. |
310 Node* callee = call->InputAt(0); | 312 Node* callee = call->InputAt(0); |
311 switch (buffer->descriptor->kind()) { | 313 switch (buffer->descriptor->kind()) { |
312 case CallDescriptor::kCallCodeObject: | 314 case CallDescriptor::kCallCodeObject: |
313 buffer->instruction_args.push_back( | 315 buffer->instruction_args.push_back( |
314 (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant) | 316 (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant) |
315 ? g.UseImmediate(callee) | 317 ? g.UseImmediate(callee) |
316 : g.UseRegister(callee)); | 318 : g.UseRegister(callee)); |
317 break; | 319 break; |
318 case CallDescriptor::kCallAddress: | 320 case CallDescriptor::kCallAddress: |
319 buffer->instruction_args.push_back( | 321 buffer->instruction_args.push_back( |
320 (call_address_immediate && | 322 (call_address_immediate && |
321 (callee->opcode() == IrOpcode::kInt32Constant || | 323 (callee->opcode() == IrOpcode::kInt32Constant || |
322 callee->opcode() == IrOpcode::kInt64Constant)) | 324 callee->opcode() == IrOpcode::kInt64Constant)) |
323 ? g.UseImmediate(callee) | 325 ? g.UseImmediate(callee) |
324 : g.UseRegister(callee)); | 326 : g.UseRegister(callee)); |
325 break; | 327 break; |
326 case CallDescriptor::kCallJSFunction: | 328 case CallDescriptor::kCallJSFunction: |
327 buffer->instruction_args.push_back( | 329 buffer->instruction_args.push_back( |
328 g.UseLocation(callee, buffer->descriptor->GetInputLocation(0))); | 330 g.UseLocation(callee, buffer->descriptor->GetInputLocation(0), |
| 331 buffer->descriptor->GetInputType(0))); |
329 break; | 332 break; |
330 } | 333 } |
331 DCHECK_EQ(1, buffer->instruction_args.size()); | 334 DCHECK_EQ(1, buffer->instruction_args.size()); |
332 | 335 |
333 // If the call needs a frame state, we insert the state information as | 336 // If the call needs a frame state, we insert the state information as |
334 // follows (n is the number of value inputs to the frame state): | 337 // follows (n is the number of value inputs to the frame state): |
335 // arg 1 : deoptimization id. | 338 // arg 1 : deoptimization id. |
336 // arg 2 - arg (n + 1) : value inputs to the frame state. | 339 // arg 2 - arg (n + 1) : value inputs to the frame state. |
337 if (buffer->frame_state_descriptor != NULL) { | 340 if (buffer->frame_state_descriptor != NULL) { |
338 InstructionSequence::StateId state_id = | 341 InstructionSequence::StateId state_id = |
(...skipping 14 matching lines...) Expand all Loading... |
353 // not appear as arguments to the call. Everything else ends up | 356 // not appear as arguments to the call. Everything else ends up |
354 // as an InstructionOperand argument to the call. | 357 // as an InstructionOperand argument to the call. |
355 InputIter iter(call->inputs().begin()); | 358 InputIter iter(call->inputs().begin()); |
356 int pushed_count = 0; | 359 int pushed_count = 0; |
357 for (int index = 0; index < input_count; ++iter, ++index) { | 360 for (int index = 0; index < input_count; ++iter, ++index) { |
358 DCHECK(iter != call->inputs().end()); | 361 DCHECK(iter != call->inputs().end()); |
359 DCHECK(index == iter.index()); | 362 DCHECK(index == iter.index()); |
360 DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState); | 363 DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState); |
361 if (index == 0) continue; // The first argument (callee) is already done. | 364 if (index == 0) continue; // The first argument (callee) is already done. |
362 InstructionOperand* op = | 365 InstructionOperand* op = |
363 g.UseLocation(*iter, buffer->descriptor->GetInputLocation(index)); | 366 g.UseLocation(*iter, buffer->descriptor->GetInputLocation(index), |
| 367 buffer->descriptor->GetInputType(index)); |
364 if (UnallocatedOperand::cast(op)->HasFixedSlotPolicy()) { | 368 if (UnallocatedOperand::cast(op)->HasFixedSlotPolicy()) { |
365 int stack_index = -UnallocatedOperand::cast(op)->fixed_slot_index() - 1; | 369 int stack_index = -UnallocatedOperand::cast(op)->fixed_slot_index() - 1; |
366 if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) { | 370 if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) { |
367 buffer->pushed_nodes.resize(stack_index + 1, NULL); | 371 buffer->pushed_nodes.resize(stack_index + 1, NULL); |
368 } | 372 } |
369 DCHECK_EQ(NULL, buffer->pushed_nodes[stack_index]); | 373 DCHECK_EQ(NULL, buffer->pushed_nodes[stack_index]); |
370 buffer->pushed_nodes[stack_index] = *iter; | 374 buffer->pushed_nodes[stack_index] = *iter; |
371 pushed_count++; | 375 pushed_count++; |
372 } else { | 376 } else { |
373 buffer->instruction_args.push_back(op); | 377 buffer->instruction_args.push_back(op); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 case IrOpcode::kBranch: | 481 case IrOpcode::kBranch: |
478 case IrOpcode::kIfTrue: | 482 case IrOpcode::kIfTrue: |
479 case IrOpcode::kIfFalse: | 483 case IrOpcode::kIfFalse: |
480 case IrOpcode::kEffectPhi: | 484 case IrOpcode::kEffectPhi: |
481 case IrOpcode::kMerge: | 485 case IrOpcode::kMerge: |
482 // No code needed for these graph artifacts. | 486 // No code needed for these graph artifacts. |
483 return; | 487 return; |
484 case IrOpcode::kFinish: | 488 case IrOpcode::kFinish: |
485 return VisitFinish(node); | 489 return VisitFinish(node); |
486 case IrOpcode::kParameter: { | 490 case IrOpcode::kParameter: { |
487 LinkageLocation location = | 491 MachineType type = linkage()->GetParameterType(OpParameter<int>(node)); |
488 linkage()->GetParameterLocation(OpParameter<int>(node)); | 492 MarkAsRepresentation(type, node); |
489 MarkAsRepresentation(location.representation(), node); | |
490 return VisitParameter(node); | 493 return VisitParameter(node); |
491 } | 494 } |
492 case IrOpcode::kPhi: | 495 case IrOpcode::kPhi: |
493 return VisitPhi(node); | 496 return VisitPhi(node); |
494 case IrOpcode::kProjection: | 497 case IrOpcode::kProjection: |
495 return VisitProjection(node); | 498 return VisitProjection(node); |
496 case IrOpcode::kInt32Constant: | 499 case IrOpcode::kInt32Constant: |
497 case IrOpcode::kInt64Constant: | 500 case IrOpcode::kInt64Constant: |
498 case IrOpcode::kExternalConstant: | 501 case IrOpcode::kExternalConstant: |
499 return VisitConstant(node); | 502 return VisitConstant(node); |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 | 818 |
816 void InstructionSelector::VisitFinish(Node* node) { | 819 void InstructionSelector::VisitFinish(Node* node) { |
817 OperandGenerator g(this); | 820 OperandGenerator g(this); |
818 Node* value = node->InputAt(0); | 821 Node* value = node->InputAt(0); |
819 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); | 822 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); |
820 } | 823 } |
821 | 824 |
822 | 825 |
823 void InstructionSelector::VisitParameter(Node* node) { | 826 void InstructionSelector::VisitParameter(Node* node) { |
824 OperandGenerator g(this); | 827 OperandGenerator g(this); |
825 Emit(kArchNop, g.DefineAsLocation(node, linkage()->GetParameterLocation( | 828 int index = OpParameter<int>(node); |
826 OpParameter<int>(node)))); | 829 Emit(kArchNop, |
| 830 g.DefineAsLocation(node, linkage()->GetParameterLocation(index), |
| 831 linkage()->GetParameterType(index))); |
827 } | 832 } |
828 | 833 |
829 | 834 |
830 void InstructionSelector::VisitPhi(Node* node) { | 835 void InstructionSelector::VisitPhi(Node* node) { |
831 // TODO(bmeurer): Emit a PhiInstruction here. | 836 // TODO(bmeurer): Emit a PhiInstruction here. |
832 for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) { | 837 for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) { |
833 MarkAsUsed(*i); | 838 MarkAsUsed(*i); |
834 } | 839 } |
835 } | 840 } |
836 | 841 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 } | 985 } |
981 | 986 |
982 // Branch could not be combined with a compare, emit compare against 0. | 987 // Branch could not be combined with a compare, emit compare against 0. |
983 VisitWord32Test(value, &cont); | 988 VisitWord32Test(value, &cont); |
984 } | 989 } |
985 | 990 |
986 | 991 |
987 void InstructionSelector::VisitReturn(Node* value) { | 992 void InstructionSelector::VisitReturn(Node* value) { |
988 OperandGenerator g(this); | 993 OperandGenerator g(this); |
989 if (value != NULL) { | 994 if (value != NULL) { |
990 Emit(kArchRet, NULL, g.UseLocation(value, linkage()->GetReturnLocation())); | 995 Emit(kArchRet, NULL, g.UseLocation(value, linkage()->GetReturnLocation(), |
| 996 linkage()->GetReturnType())); |
991 } else { | 997 } else { |
992 Emit(kArchRet, NULL); | 998 Emit(kArchRet, NULL); |
993 } | 999 } |
994 } | 1000 } |
995 | 1001 |
996 | 1002 |
997 void InstructionSelector::VisitThrow(Node* value) { | 1003 void InstructionSelector::VisitThrow(Node* value) { |
998 UNIMPLEMENTED(); // TODO(titzer) | 1004 UNIMPLEMENTED(); // TODO(titzer) |
999 } | 1005 } |
1000 | 1006 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1096 | 1102 |
1097 | 1103 |
1098 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, | 1104 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, |
1099 BasicBlock* deoptimization) {} | 1105 BasicBlock* deoptimization) {} |
1100 | 1106 |
1101 #endif // !V8_TURBOFAN_BACKEND | 1107 #endif // !V8_TURBOFAN_BACKEND |
1102 | 1108 |
1103 } // namespace compiler | 1109 } // namespace compiler |
1104 } // namespace internal | 1110 } // namespace internal |
1105 } // namespace v8 | 1111 } // namespace v8 |
OLD | NEW |