| 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.h" | 9 #include "src/compiler/node-properties.h" |
| 10 #include "src/compiler/pipeline.h" | 10 #include "src/compiler/pipeline.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 UnallocatedOperand::kInvalidVirtualRegister, zone) { | 33 UnallocatedOperand::kInvalidVirtualRegister, zone) { |
| 34 instructions_.reserve(node_count); | 34 instructions_.reserve(node_count); |
| 35 } | 35 } |
| 36 | 36 |
| 37 | 37 |
| 38 void InstructionSelector::SelectInstructions() { | 38 void InstructionSelector::SelectInstructions() { |
| 39 // Mark the inputs of all phis in loop headers as used. | 39 // Mark the inputs of all phis in loop headers as used. |
| 40 BasicBlockVector* blocks = schedule()->rpo_order(); | 40 BasicBlockVector* blocks = schedule()->rpo_order(); |
| 41 for (auto const block : *blocks) { | 41 for (auto const block : *blocks) { |
| 42 if (!block->IsLoopHeader()) continue; | 42 if (!block->IsLoopHeader()) continue; |
| 43 DCHECK_LE(2, block->PredecessorCount()); | 43 DCHECK_LE(2u, block->PredecessorCount()); |
| 44 for (Node* const phi : *block) { | 44 for (Node* const phi : *block) { |
| 45 if (phi->opcode() != IrOpcode::kPhi) continue; | 45 if (phi->opcode() != IrOpcode::kPhi) continue; |
| 46 | 46 |
| 47 // Mark all inputs as used. | 47 // Mark all inputs as used. |
| 48 for (Node* const input : phi->inputs()) { | 48 for (Node* const input : phi->inputs()) { |
| 49 MarkAsUsed(input); | 49 MarkAsUsed(input); |
| 50 } | 50 } |
| 51 } | 51 } |
| 52 } | 52 } |
| 53 | 53 |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 if (buffer->descriptor->ReturnCount() > 0) { | 335 if (buffer->descriptor->ReturnCount() > 0) { |
| 336 // Collect the projections that represent multiple outputs from this call. | 336 // Collect the projections that represent multiple outputs from this call. |
| 337 if (buffer->descriptor->ReturnCount() == 1) { | 337 if (buffer->descriptor->ReturnCount() == 1) { |
| 338 buffer->output_nodes.push_back(call); | 338 buffer->output_nodes.push_back(call); |
| 339 } else { | 339 } else { |
| 340 buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), nullptr); | 340 buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), nullptr); |
| 341 for (auto use : call->uses()) { | 341 for (auto use : call->uses()) { |
| 342 if (use->opcode() != IrOpcode::kProjection) continue; | 342 if (use->opcode() != IrOpcode::kProjection) continue; |
| 343 size_t const index = ProjectionIndexOf(use->op()); | 343 size_t const index = ProjectionIndexOf(use->op()); |
| 344 DCHECK_LT(index, buffer->output_nodes.size()); | 344 DCHECK_LT(index, buffer->output_nodes.size()); |
| 345 DCHECK_EQ(nullptr, buffer->output_nodes[index]); | 345 DCHECK(!buffer->output_nodes[index]); |
| 346 buffer->output_nodes[index] = use; | 346 buffer->output_nodes[index] = use; |
| 347 } | 347 } |
| 348 } | 348 } |
| 349 | 349 |
| 350 // Filter out the outputs that aren't live because no projection uses them. | 350 // Filter out the outputs that aren't live because no projection uses them. |
| 351 size_t outputs_needed_by_framestate = | 351 size_t outputs_needed_by_framestate = |
| 352 buffer->frame_state_descriptor == NULL | 352 buffer->frame_state_descriptor == NULL |
| 353 ? 0 | 353 ? 0 |
| 354 : buffer->frame_state_descriptor->state_combine() | 354 : buffer->frame_state_descriptor->state_combine() |
| 355 .ConsumedOutputCount(); | 355 .ConsumedOutputCount(); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState); | 428 DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState); |
| 429 if (index == 0) continue; // The first argument (callee) is already done. | 429 if (index == 0) continue; // The first argument (callee) is already done. |
| 430 InstructionOperand* op = | 430 InstructionOperand* op = |
| 431 g.UseLocation(*iter, buffer->descriptor->GetInputLocation(index), | 431 g.UseLocation(*iter, buffer->descriptor->GetInputLocation(index), |
| 432 buffer->descriptor->GetInputType(index)); | 432 buffer->descriptor->GetInputType(index)); |
| 433 if (UnallocatedOperand::cast(op)->HasFixedSlotPolicy()) { | 433 if (UnallocatedOperand::cast(op)->HasFixedSlotPolicy()) { |
| 434 int stack_index = -UnallocatedOperand::cast(op)->fixed_slot_index() - 1; | 434 int stack_index = -UnallocatedOperand::cast(op)->fixed_slot_index() - 1; |
| 435 if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) { | 435 if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) { |
| 436 buffer->pushed_nodes.resize(stack_index + 1, NULL); | 436 buffer->pushed_nodes.resize(stack_index + 1, NULL); |
| 437 } | 437 } |
| 438 DCHECK_EQ(NULL, buffer->pushed_nodes[stack_index]); | 438 DCHECK(!buffer->pushed_nodes[stack_index]); |
| 439 buffer->pushed_nodes[stack_index] = *iter; | 439 buffer->pushed_nodes[stack_index] = *iter; |
| 440 pushed_count++; | 440 pushed_count++; |
| 441 } else { | 441 } else { |
| 442 buffer->instruction_args.push_back(op); | 442 buffer->instruction_args.push_back(op); |
| 443 } | 443 } |
| 444 } | 444 } |
| 445 CHECK_EQ(pushed_count, static_cast<int>(buffer->pushed_nodes.size())); | 445 CHECK_EQ(pushed_count, static_cast<int>(buffer->pushed_nodes.size())); |
| 446 DCHECK(static_cast<size_t>(input_count) == | 446 DCHECK(static_cast<size_t>(input_count) == |
| 447 (buffer->instruction_args.size() + buffer->pushed_nodes.size() - | 447 (buffer->instruction_args.size() + buffer->pushed_nodes.size() - |
| 448 buffer->frame_state_value_count())); | 448 buffer->frame_state_value_count())); |
| 449 } | 449 } |
| 450 | 450 |
| 451 | 451 |
| 452 void InstructionSelector::VisitBlock(BasicBlock* block) { | 452 void InstructionSelector::VisitBlock(BasicBlock* block) { |
| 453 DCHECK_EQ(NULL, current_block_); | 453 DCHECK(!current_block_); |
| 454 current_block_ = block; | 454 current_block_ = block; |
| 455 int current_block_end = static_cast<int>(instructions_.size()); | 455 int current_block_end = static_cast<int>(instructions_.size()); |
| 456 | 456 |
| 457 // Generate code for the block control "top down", but schedule the code | 457 // Generate code for the block control "top down", but schedule the code |
| 458 // "bottom up". | 458 // "bottom up". |
| 459 VisitControl(block); | 459 VisitControl(block); |
| 460 std::reverse(instructions_.begin() + current_block_end, instructions_.end()); | 460 std::reverse(instructions_.begin() + current_block_end, instructions_.end()); |
| 461 | 461 |
| 462 // Visit code in reverse control flow order, because architecture-specific | 462 // Visit code in reverse control flow order, because architecture-specific |
| 463 // matching may cover more than one node at a time. | 463 // matching may cover more than one node at a time. |
| (...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1173 MachineOperatorBuilder::Flags | 1173 MachineOperatorBuilder::Flags |
| 1174 InstructionSelector::SupportedMachineOperatorFlags() { | 1174 InstructionSelector::SupportedMachineOperatorFlags() { |
| 1175 return MachineOperatorBuilder::Flag::kNoFlags; | 1175 return MachineOperatorBuilder::Flag::kNoFlags; |
| 1176 } | 1176 } |
| 1177 | 1177 |
| 1178 #endif // !V8_TURBOFAN_BACKEND | 1178 #endif // !V8_TURBOFAN_BACKEND |
| 1179 | 1179 |
| 1180 } // namespace compiler | 1180 } // namespace compiler |
| 1181 } // namespace internal | 1181 } // namespace internal |
| 1182 } // namespace v8 | 1182 } // namespace v8 |
| OLD | NEW |