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 |