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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 AddInstruction(instructions_[start]); | 79 AddInstruction(instructions_[start]); |
80 } | 80 } |
81 EndBlock(RpoNumber::FromInt(block->rpo_number())); | 81 EndBlock(RpoNumber::FromInt(block->rpo_number())); |
82 } | 82 } |
83 } | 83 } |
84 | 84 |
85 | 85 |
86 void InstructionSelector::StartBlock(RpoNumber rpo) { | 86 void InstructionSelector::StartBlock(RpoNumber rpo) { |
87 if (FLAG_turbo_instruction_scheduling && | 87 if (FLAG_turbo_instruction_scheduling && |
88 InstructionScheduler::SchedulerSupported()) { | 88 InstructionScheduler::SchedulerSupported()) { |
89 DCHECK(scheduler_ != nullptr); | 89 DCHECK_NOT_NULL(scheduler_); |
90 scheduler_->StartBlock(rpo); | 90 scheduler_->StartBlock(rpo); |
91 } else { | 91 } else { |
92 sequence()->StartBlock(rpo); | 92 sequence()->StartBlock(rpo); |
93 } | 93 } |
94 } | 94 } |
95 | 95 |
96 | 96 |
97 void InstructionSelector::EndBlock(RpoNumber rpo) { | 97 void InstructionSelector::EndBlock(RpoNumber rpo) { |
98 if (FLAG_turbo_instruction_scheduling && | 98 if (FLAG_turbo_instruction_scheduling && |
99 InstructionScheduler::SchedulerSupported()) { | 99 InstructionScheduler::SchedulerSupported()) { |
100 DCHECK(scheduler_ != nullptr); | 100 DCHECK_NOT_NULL(scheduler_); |
101 scheduler_->EndBlock(rpo); | 101 scheduler_->EndBlock(rpo); |
102 } else { | 102 } else { |
103 sequence()->EndBlock(rpo); | 103 sequence()->EndBlock(rpo); |
104 } | 104 } |
105 } | 105 } |
106 | 106 |
107 | 107 |
108 void InstructionSelector::AddInstruction(Instruction* instr) { | 108 void InstructionSelector::AddInstruction(Instruction* instr) { |
109 if (FLAG_turbo_instruction_scheduling && | 109 if (FLAG_turbo_instruction_scheduling && |
110 InstructionScheduler::SchedulerSupported()) { | 110 InstructionScheduler::SchedulerSupported()) { |
111 DCHECK(scheduler_ != nullptr); | 111 DCHECK_NOT_NULL(scheduler_); |
112 scheduler_->AddInstruction(instr); | 112 scheduler_->AddInstruction(instr); |
113 } else { | 113 } else { |
114 sequence()->AddInstruction(instr); | 114 sequence()->AddInstruction(instr); |
115 } | 115 } |
116 } | 116 } |
117 | 117 |
118 | 118 |
119 Instruction* InstructionSelector::Emit(InstructionCode opcode, | 119 Instruction* InstructionSelector::Emit(InstructionCode opcode, |
120 InstructionOperand output, | 120 InstructionOperand output, |
121 size_t temp_count, | 121 size_t temp_count, |
122 InstructionOperand* temps) { | 122 InstructionOperand* temps) { |
123 size_t output_count = output.IsInvalid() ? 0 : 1; | 123 size_t output_count = output.IsInvalid() ? 0 : 1; |
124 return Emit(opcode, output_count, &output, 0, NULL, temp_count, temps); | 124 return Emit(opcode, output_count, &output, 0, nullptr, temp_count, temps); |
125 } | 125 } |
126 | 126 |
127 | 127 |
128 Instruction* InstructionSelector::Emit(InstructionCode opcode, | 128 Instruction* InstructionSelector::Emit(InstructionCode opcode, |
129 InstructionOperand output, | 129 InstructionOperand output, |
130 InstructionOperand a, size_t temp_count, | 130 InstructionOperand a, size_t temp_count, |
131 InstructionOperand* temps) { | 131 InstructionOperand* temps) { |
132 size_t output_count = output.IsInvalid() ? 0 : 1; | 132 size_t output_count = output.IsInvalid() ? 0 : 1; |
133 return Emit(opcode, output_count, &output, 1, &a, temp_count, temps); | 133 return Emit(opcode, output_count, &output, 1, &a, temp_count, temps); |
134 } | 134 } |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 NodeVector output_nodes; | 475 NodeVector output_nodes; |
476 InstructionOperandVector outputs; | 476 InstructionOperandVector outputs; |
477 InstructionOperandVector instruction_args; | 477 InstructionOperandVector instruction_args; |
478 ZoneVector<PushParameter> pushed_nodes; | 478 ZoneVector<PushParameter> pushed_nodes; |
479 | 479 |
480 size_t input_count() const { return descriptor->InputCount(); } | 480 size_t input_count() const { return descriptor->InputCount(); } |
481 | 481 |
482 size_t frame_state_count() const { return descriptor->FrameStateCount(); } | 482 size_t frame_state_count() const { return descriptor->FrameStateCount(); } |
483 | 483 |
484 size_t frame_state_value_count() const { | 484 size_t frame_state_value_count() const { |
485 return (frame_state_descriptor == NULL) | 485 return (frame_state_descriptor == nullptr) |
486 ? 0 | 486 ? 0 |
487 : (frame_state_descriptor->GetTotalSize() + | 487 : (frame_state_descriptor->GetTotalSize() + |
488 1); // Include deopt id. | 488 1); // Include deopt id. |
489 } | 489 } |
490 }; | 490 }; |
491 | 491 |
492 | 492 |
493 // TODO(bmeurer): Get rid of the CallBuffer business and make | 493 // TODO(bmeurer): Get rid of the CallBuffer business and make |
494 // InstructionSelector::VisitCall platform independent instead. | 494 // InstructionSelector::VisitCall platform independent instead. |
495 void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer, | 495 void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer, |
(...skipping 16 matching lines...) Expand all Loading... |
512 if (use->opcode() != IrOpcode::kProjection) continue; | 512 if (use->opcode() != IrOpcode::kProjection) continue; |
513 size_t const index = ProjectionIndexOf(use->op()); | 513 size_t const index = ProjectionIndexOf(use->op()); |
514 DCHECK_LT(index, buffer->output_nodes.size()); | 514 DCHECK_LT(index, buffer->output_nodes.size()); |
515 DCHECK(!buffer->output_nodes[index]); | 515 DCHECK(!buffer->output_nodes[index]); |
516 buffer->output_nodes[index] = use; | 516 buffer->output_nodes[index] = use; |
517 } | 517 } |
518 } | 518 } |
519 | 519 |
520 // Filter out the outputs that aren't live because no projection uses them. | 520 // Filter out the outputs that aren't live because no projection uses them. |
521 size_t outputs_needed_by_framestate = | 521 size_t outputs_needed_by_framestate = |
522 buffer->frame_state_descriptor == NULL | 522 buffer->frame_state_descriptor == nullptr |
523 ? 0 | 523 ? 0 |
524 : buffer->frame_state_descriptor->state_combine() | 524 : buffer->frame_state_descriptor->state_combine() |
525 .ConsumedOutputCount(); | 525 .ConsumedOutputCount(); |
526 for (size_t i = 0; i < buffer->output_nodes.size(); i++) { | 526 for (size_t i = 0; i < buffer->output_nodes.size(); i++) { |
527 bool output_is_live = | 527 bool output_is_live = buffer->output_nodes[i] != nullptr || |
528 buffer->output_nodes[i] != NULL || i < outputs_needed_by_framestate; | 528 i < outputs_needed_by_framestate; |
529 if (output_is_live) { | 529 if (output_is_live) { |
530 MachineType type = | 530 MachineType type = |
531 buffer->descriptor->GetReturnType(static_cast<int>(i)); | 531 buffer->descriptor->GetReturnType(static_cast<int>(i)); |
532 LinkageLocation location = | 532 LinkageLocation location = |
533 buffer->descriptor->GetReturnLocation(static_cast<int>(i)); | 533 buffer->descriptor->GetReturnLocation(static_cast<int>(i)); |
534 | 534 |
535 Node* output = buffer->output_nodes[i]; | 535 Node* output = buffer->output_nodes[i]; |
536 InstructionOperand op = | 536 InstructionOperand op = |
537 output == NULL | 537 output == nullptr |
538 ? g.TempLocation(location, type.representation()) | 538 ? g.TempLocation(location, type.representation()) |
539 : g.DefineAsLocation(output, location, type.representation()); | 539 : g.DefineAsLocation(output, location, type.representation()); |
540 MarkAsRepresentation(type.representation(), op); | 540 MarkAsRepresentation(type.representation(), op); |
541 | 541 |
542 buffer->outputs.push_back(op); | 542 buffer->outputs.push_back(op); |
543 } | 543 } |
544 } | 544 } |
545 } | 545 } |
546 | 546 |
547 // The first argument is always the callee code. | 547 // The first argument is always the callee code. |
(...skipping 25 matching lines...) Expand all Loading... |
573 break; | 573 break; |
574 } | 574 } |
575 DCHECK_EQ(1u, buffer->instruction_args.size()); | 575 DCHECK_EQ(1u, buffer->instruction_args.size()); |
576 | 576 |
577 // If the call needs a frame state, we insert the state information as | 577 // If the call needs a frame state, we insert the state information as |
578 // follows (n is the number of value inputs to the frame state): | 578 // follows (n is the number of value inputs to the frame state): |
579 // arg 1 : deoptimization id. | 579 // arg 1 : deoptimization id. |
580 // arg 2 - arg (n + 1) : value inputs to the frame state. | 580 // arg 2 - arg (n + 1) : value inputs to the frame state. |
581 size_t frame_state_entries = 0; | 581 size_t frame_state_entries = 0; |
582 USE(frame_state_entries); // frame_state_entries is only used for debug. | 582 USE(frame_state_entries); // frame_state_entries is only used for debug. |
583 if (buffer->frame_state_descriptor != NULL) { | 583 if (buffer->frame_state_descriptor != nullptr) { |
584 InstructionSequence::StateId state_id = | 584 InstructionSequence::StateId state_id = |
585 sequence()->AddFrameStateDescriptor(buffer->frame_state_descriptor); | 585 sequence()->AddFrameStateDescriptor(buffer->frame_state_descriptor); |
586 buffer->instruction_args.push_back(g.TempImmediate(state_id.ToInt())); | 586 buffer->instruction_args.push_back(g.TempImmediate(state_id.ToInt())); |
587 | 587 |
588 Node* frame_state = | 588 Node* frame_state = |
589 call->InputAt(static_cast<int>(buffer->descriptor->InputCount())); | 589 call->InputAt(static_cast<int>(buffer->descriptor->InputCount())); |
590 | 590 |
591 StateObjectDeduplicator deduplicator(instruction_zone()); | 591 StateObjectDeduplicator deduplicator(instruction_zone()); |
592 | 592 |
593 frame_state_entries = | 593 frame_state_entries = |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 source_position); | 681 source_position); |
682 } | 682 } |
683 } | 683 } |
684 | 684 |
685 // We're done with the block. | 685 // We're done with the block. |
686 InstructionBlock* instruction_block = | 686 InstructionBlock* instruction_block = |
687 sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number())); | 687 sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number())); |
688 instruction_block->set_code_start(static_cast<int>(instructions_.size())); | 688 instruction_block->set_code_start(static_cast<int>(instructions_.size())); |
689 instruction_block->set_code_end(current_block_end); | 689 instruction_block->set_code_end(current_block_end); |
690 | 690 |
691 current_block_ = NULL; | 691 current_block_ = nullptr; |
692 } | 692 } |
693 | 693 |
694 | 694 |
695 void InstructionSelector::VisitControl(BasicBlock* block) { | 695 void InstructionSelector::VisitControl(BasicBlock* block) { |
696 #ifdef DEBUG | 696 #ifdef DEBUG |
697 // SSA deconstruction requires targets of branches not to have phis. | 697 // SSA deconstruction requires targets of branches not to have phis. |
698 // Edge split form guarantees this property, but is more strict. | 698 // Edge split form guarantees this property, but is more strict. |
699 if (block->SuccessorCount() > 1) { | 699 if (block->SuccessorCount() > 1) { |
700 for (BasicBlock* const successor : block->successors()) { | 700 for (BasicBlock* const successor : block->successors()) { |
701 for (Node* const node : *successor) { | 701 for (Node* const node : *successor) { |
(...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1598 int parameters = static_cast<int>( | 1598 int parameters = static_cast<int>( |
1599 StateValuesAccess(state->InputAt(kFrameStateParametersInput)).size()); | 1599 StateValuesAccess(state->InputAt(kFrameStateParametersInput)).size()); |
1600 int locals = static_cast<int>( | 1600 int locals = static_cast<int>( |
1601 StateValuesAccess(state->InputAt(kFrameStateLocalsInput)).size()); | 1601 StateValuesAccess(state->InputAt(kFrameStateLocalsInput)).size()); |
1602 int stack = static_cast<int>( | 1602 int stack = static_cast<int>( |
1603 StateValuesAccess(state->InputAt(kFrameStateStackInput)).size()); | 1603 StateValuesAccess(state->InputAt(kFrameStateStackInput)).size()); |
1604 | 1604 |
1605 DCHECK_EQ(parameters, state_info.parameter_count()); | 1605 DCHECK_EQ(parameters, state_info.parameter_count()); |
1606 DCHECK_EQ(locals, state_info.local_count()); | 1606 DCHECK_EQ(locals, state_info.local_count()); |
1607 | 1607 |
1608 FrameStateDescriptor* outer_state = NULL; | 1608 FrameStateDescriptor* outer_state = nullptr; |
1609 Node* outer_node = state->InputAt(kFrameStateOuterStateInput); | 1609 Node* outer_node = state->InputAt(kFrameStateOuterStateInput); |
1610 if (outer_node->opcode() == IrOpcode::kFrameState) { | 1610 if (outer_node->opcode() == IrOpcode::kFrameState) { |
1611 outer_state = GetFrameStateDescriptor(outer_node); | 1611 outer_state = GetFrameStateDescriptor(outer_node); |
1612 } | 1612 } |
1613 | 1613 |
1614 return new (instruction_zone()) FrameStateDescriptor( | 1614 return new (instruction_zone()) FrameStateDescriptor( |
1615 instruction_zone(), state_info.type(), state_info.bailout_id(), | 1615 instruction_zone(), state_info.type(), state_info.bailout_id(), |
1616 state_info.state_combine(), parameters, locals, stack, | 1616 state_info.state_combine(), parameters, locals, stack, |
1617 state_info.shared_info(), outer_state); | 1617 state_info.shared_info(), outer_state); |
1618 } | 1618 } |
1619 | 1619 |
1620 | 1620 |
1621 } // namespace compiler | 1621 } // namespace compiler |
1622 } // namespace internal | 1622 } // namespace internal |
1623 } // namespace v8 | 1623 } // namespace v8 |
OLD | NEW |