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