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