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 12 matching lines...) Expand all Loading... |
23 InstructionSequence* sequence, Schedule* schedule, | 23 InstructionSequence* sequence, Schedule* schedule, |
24 SourcePositionTable* source_positions, | 24 SourcePositionTable* source_positions, |
25 SourcePositionMode source_position_mode, Features features) | 25 SourcePositionMode source_position_mode, Features features) |
26 : zone_(zone), | 26 : zone_(zone), |
27 linkage_(linkage), | 27 linkage_(linkage), |
28 sequence_(sequence), | 28 sequence_(sequence), |
29 source_positions_(source_positions), | 29 source_positions_(source_positions), |
30 source_position_mode_(source_position_mode), | 30 source_position_mode_(source_position_mode), |
31 features_(features), | 31 features_(features), |
32 schedule_(schedule), | 32 schedule_(schedule), |
33 current_block_(NULL), | 33 current_block_(nullptr), |
34 instructions_(zone), | 34 instructions_(zone), |
35 defined_(node_count, false, zone), | 35 defined_(node_count, false, zone), |
36 used_(node_count, false, zone), | 36 used_(node_count, false, zone), |
37 virtual_registers_(node_count, | 37 virtual_registers_(node_count, |
38 InstructionOperand::kInvalidVirtualRegister, zone) { | 38 InstructionOperand::kInvalidVirtualRegister, zone), |
| 39 scheduler_(nullptr) { |
39 instructions_.reserve(node_count); | 40 instructions_.reserve(node_count); |
40 } | 41 } |
41 | 42 |
42 | 43 |
43 void InstructionSelector::SelectInstructions() { | 44 void InstructionSelector::SelectInstructions() { |
44 // Mark the inputs of all phis in loop headers as used. | 45 // Mark the inputs of all phis in loop headers as used. |
45 BasicBlockVector* blocks = schedule()->rpo_order(); | 46 BasicBlockVector* blocks = schedule()->rpo_order(); |
46 for (auto const block : *blocks) { | 47 for (auto const block : *blocks) { |
47 if (!block->IsLoopHeader()) continue; | 48 if (!block->IsLoopHeader()) continue; |
48 DCHECK_LE(2u, block->PredecessorCount()); | 49 DCHECK_LE(2u, block->PredecessorCount()); |
49 for (Node* const phi : *block) { | 50 for (Node* const phi : *block) { |
50 if (phi->opcode() != IrOpcode::kPhi) continue; | 51 if (phi->opcode() != IrOpcode::kPhi) continue; |
51 | 52 |
52 // Mark all inputs as used. | 53 // Mark all inputs as used. |
53 for (Node* const input : phi->inputs()) { | 54 for (Node* const input : phi->inputs()) { |
54 MarkAsUsed(input); | 55 MarkAsUsed(input); |
55 } | 56 } |
56 } | 57 } |
57 } | 58 } |
58 | 59 |
59 // Visit each basic block in post order. | 60 // Visit each basic block in post order. |
60 for (auto i = blocks->rbegin(); i != blocks->rend(); ++i) { | 61 for (auto i = blocks->rbegin(); i != blocks->rend(); ++i) { |
61 VisitBlock(*i); | 62 VisitBlock(*i); |
62 } | 63 } |
63 | 64 |
64 // Schedule the selected instructions. | 65 // Schedule the selected instructions. |
| 66 if (FLAG_turbo_instruction_scheduling && |
| 67 InstructionScheduler::SchedulerSupported()) { |
| 68 scheduler_ = new (zone()) InstructionScheduler(zone(), sequence()); |
| 69 } |
| 70 |
65 for (auto const block : *blocks) { | 71 for (auto const block : *blocks) { |
66 InstructionBlock* instruction_block = | 72 InstructionBlock* instruction_block = |
67 sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number())); | 73 sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number())); |
68 size_t end = instruction_block->code_end(); | 74 size_t end = instruction_block->code_end(); |
69 size_t start = instruction_block->code_start(); | 75 size_t start = instruction_block->code_start(); |
70 DCHECK_LE(end, start); | 76 DCHECK_LE(end, start); |
71 sequence()->StartBlock(RpoNumber::FromInt(block->rpo_number())); | 77 StartBlock(RpoNumber::FromInt(block->rpo_number())); |
72 while (start-- > end) { | 78 while (start-- > end) { |
73 sequence()->AddInstruction(instructions_[start]); | 79 AddInstruction(instructions_[start]); |
74 } | 80 } |
75 sequence()->EndBlock(RpoNumber::FromInt(block->rpo_number())); | 81 EndBlock(RpoNumber::FromInt(block->rpo_number())); |
76 } | 82 } |
77 } | 83 } |
78 | 84 |
| 85 |
| 86 void InstructionSelector::StartBlock(RpoNumber rpo) { |
| 87 if (FLAG_turbo_instruction_scheduling && |
| 88 InstructionScheduler::SchedulerSupported()) { |
| 89 DCHECK(scheduler_ != nullptr); |
| 90 scheduler_->StartBlock(rpo); |
| 91 } else { |
| 92 sequence()->StartBlock(rpo); |
| 93 } |
| 94 } |
| 95 |
| 96 |
| 97 void InstructionSelector::EndBlock(RpoNumber rpo) { |
| 98 if (FLAG_turbo_instruction_scheduling && |
| 99 InstructionScheduler::SchedulerSupported()) { |
| 100 DCHECK(scheduler_ != nullptr); |
| 101 scheduler_->EndBlock(rpo); |
| 102 } else { |
| 103 sequence()->EndBlock(rpo); |
| 104 } |
| 105 } |
| 106 |
| 107 |
| 108 void InstructionSelector::AddInstruction(Instruction* instr) { |
| 109 if (FLAG_turbo_instruction_scheduling && |
| 110 InstructionScheduler::SchedulerSupported()) { |
| 111 DCHECK(scheduler_ != nullptr); |
| 112 scheduler_->AddInstruction(instr); |
| 113 } else { |
| 114 sequence()->AddInstruction(instr); |
| 115 } |
| 116 } |
| 117 |
79 | 118 |
80 Instruction* InstructionSelector::Emit(InstructionCode opcode, | 119 Instruction* InstructionSelector::Emit(InstructionCode opcode, |
81 InstructionOperand output, | 120 InstructionOperand output, |
82 size_t temp_count, | 121 size_t temp_count, |
83 InstructionOperand* temps) { | 122 InstructionOperand* temps) { |
84 size_t output_count = output.IsInvalid() ? 0 : 1; | 123 size_t output_count = output.IsInvalid() ? 0 : 1; |
85 return Emit(opcode, output_count, &output, 0, NULL, temp_count, temps); | 124 return Emit(opcode, output_count, &output, 0, NULL, temp_count, temps); |
86 } | 125 } |
87 | 126 |
88 | 127 |
(...skipping 1348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1437 case DeoptimizeKind::kSoft: | 1476 case DeoptimizeKind::kSoft: |
1438 opcode |= MiscField::encode(Deoptimizer::SOFT); | 1477 opcode |= MiscField::encode(Deoptimizer::SOFT); |
1439 break; | 1478 break; |
1440 } | 1479 } |
1441 Emit(opcode, 0, nullptr, arg_count, &args.front(), 0, nullptr); | 1480 Emit(opcode, 0, nullptr, arg_count, &args.front(), 0, nullptr); |
1442 } | 1481 } |
1443 | 1482 |
1444 | 1483 |
1445 void InstructionSelector::VisitThrow(Node* value) { | 1484 void InstructionSelector::VisitThrow(Node* value) { |
1446 OperandGenerator g(this); | 1485 OperandGenerator g(this); |
1447 Emit(kArchNop, g.NoOutput()); // TODO(titzer) | 1486 Emit(kArchThrowTerminator, g.NoOutput()); // TODO(titzer) |
1448 } | 1487 } |
1449 | 1488 |
1450 | 1489 |
1451 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( | 1490 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( |
1452 Node* state) { | 1491 Node* state) { |
1453 DCHECK(state->opcode() == IrOpcode::kFrameState); | 1492 DCHECK(state->opcode() == IrOpcode::kFrameState); |
1454 DCHECK_EQ(kFrameStateInputCount, state->InputCount()); | 1493 DCHECK_EQ(kFrameStateInputCount, state->InputCount()); |
1455 FrameStateInfo state_info = OpParameter<FrameStateInfo>(state); | 1494 FrameStateInfo state_info = OpParameter<FrameStateInfo>(state); |
1456 | 1495 |
1457 int parameters = static_cast<int>( | 1496 int parameters = static_cast<int>( |
(...skipping 15 matching lines...) Expand all Loading... |
1473 return new (instruction_zone()) FrameStateDescriptor( | 1512 return new (instruction_zone()) FrameStateDescriptor( |
1474 instruction_zone(), state_info.type(), state_info.bailout_id(), | 1513 instruction_zone(), state_info.type(), state_info.bailout_id(), |
1475 state_info.state_combine(), parameters, locals, stack, | 1514 state_info.state_combine(), parameters, locals, stack, |
1476 state_info.shared_info(), outer_state); | 1515 state_info.shared_info(), outer_state); |
1477 } | 1516 } |
1478 | 1517 |
1479 | 1518 |
1480 } // namespace compiler | 1519 } // namespace compiler |
1481 } // namespace internal | 1520 } // namespace internal |
1482 } // namespace v8 | 1521 } // namespace v8 |
OLD | NEW |