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/bit-vector.h" | 5 #include "src/bit-vector.h" |
6 #include "src/compiler/instruction.h" | 6 #include "src/compiler/instruction.h" |
7 #include "src/compiler/register-allocator-verifier.h" | 7 #include "src/compiler/register-allocator-verifier.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
11 namespace compiler { | 11 namespace compiler { |
12 | 12 |
13 static size_t OperandCount(const Instruction* instr) { | 13 namespace { |
| 14 |
| 15 size_t OperandCount(const Instruction* instr) { |
14 return instr->InputCount() + instr->OutputCount() + instr->TempCount(); | 16 return instr->InputCount() + instr->OutputCount() + instr->TempCount(); |
15 } | 17 } |
16 | 18 |
17 | 19 |
18 static void VerifyEmptyGaps(const Instruction* instr) { | 20 void VerifyEmptyGaps(const Instruction* instr) { |
19 for (int i = Instruction::FIRST_GAP_POSITION; | 21 for (int i = Instruction::FIRST_GAP_POSITION; |
20 i <= Instruction::LAST_GAP_POSITION; i++) { | 22 i <= Instruction::LAST_GAP_POSITION; i++) { |
21 Instruction::GapPosition inner_pos = | 23 Instruction::GapPosition inner_pos = |
22 static_cast<Instruction::GapPosition>(i); | 24 static_cast<Instruction::GapPosition>(i); |
23 CHECK(instr->GetParallelMove(inner_pos) == nullptr); | 25 CHECK(instr->GetParallelMove(inner_pos) == nullptr); |
24 } | 26 } |
25 } | 27 } |
26 | 28 |
27 | 29 |
| 30 void VerifyAllocatedGaps(const Instruction* instr) { |
| 31 for (int i = Instruction::FIRST_GAP_POSITION; |
| 32 i <= Instruction::LAST_GAP_POSITION; i++) { |
| 33 Instruction::GapPosition inner_pos = |
| 34 static_cast<Instruction::GapPosition>(i); |
| 35 auto moves = instr->GetParallelMove(inner_pos); |
| 36 if (moves == nullptr) continue; |
| 37 for (auto move : *moves) { |
| 38 if (move->IsRedundant()) continue; |
| 39 CHECK(move->source().IsAllocated() || move->source().IsConstant()); |
| 40 CHECK(move->destination().IsAllocated()); |
| 41 } |
| 42 } |
| 43 } |
| 44 |
| 45 } // namespace |
| 46 |
| 47 |
28 void RegisterAllocatorVerifier::VerifyInput( | 48 void RegisterAllocatorVerifier::VerifyInput( |
29 const OperandConstraint& constraint) { | 49 const OperandConstraint& constraint) { |
30 CHECK_NE(kSameAsFirst, constraint.type_); | 50 CHECK_NE(kSameAsFirst, constraint.type_); |
31 if (constraint.type_ != kImmediate) { | 51 if (constraint.type_ != kImmediate) { |
32 CHECK_NE(InstructionOperand::kInvalidVirtualRegister, | 52 CHECK_NE(InstructionOperand::kInvalidVirtualRegister, |
33 constraint.virtual_register_); | 53 constraint.virtual_register_); |
34 } | 54 } |
35 } | 55 } |
36 | 56 |
37 | 57 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 constraints()->push_back(instr_constraint); | 107 constraints()->push_back(instr_constraint); |
88 } | 108 } |
89 } | 109 } |
90 | 110 |
91 | 111 |
92 void RegisterAllocatorVerifier::VerifyAssignment() { | 112 void RegisterAllocatorVerifier::VerifyAssignment() { |
93 CHECK(sequence()->instructions().size() == constraints()->size()); | 113 CHECK(sequence()->instructions().size() == constraints()->size()); |
94 auto instr_it = sequence()->begin(); | 114 auto instr_it = sequence()->begin(); |
95 for (const auto& instr_constraint : *constraints()) { | 115 for (const auto& instr_constraint : *constraints()) { |
96 const auto* instr = instr_constraint.instruction_; | 116 const auto* instr = instr_constraint.instruction_; |
| 117 // All gaps should be totally allocated at this point. |
| 118 VerifyAllocatedGaps(instr); |
97 const size_t operand_count = instr_constraint.operand_constaints_size_; | 119 const size_t operand_count = instr_constraint.operand_constaints_size_; |
98 const auto* op_constraints = instr_constraint.operand_constraints_; | 120 const auto* op_constraints = instr_constraint.operand_constraints_; |
99 CHECK_EQ(instr, *instr_it); | 121 CHECK_EQ(instr, *instr_it); |
100 CHECK(operand_count == OperandCount(instr)); | 122 CHECK(operand_count == OperandCount(instr)); |
101 size_t count = 0; | 123 size_t count = 0; |
102 for (size_t i = 0; i < instr->InputCount(); ++i, ++count) { | 124 for (size_t i = 0; i < instr->InputCount(); ++i, ++count) { |
103 CheckConstraint(instr->InputAt(i), &op_constraints[count]); | 125 CheckConstraint(instr->InputAt(i), &op_constraints[count]); |
104 } | 126 } |
105 for (size_t i = 0; i < instr->TempCount(); ++i, ++count) { | 127 for (size_t i = 0; i < instr->TempCount(); ++i, ++count) { |
106 CheckConstraint(instr->TempAt(i), &op_constraints[count]); | 128 CheckConstraint(instr->TempAt(i), &op_constraints[count]); |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 // Remove all entries with keys not in other. | 313 // Remove all entries with keys not in other. |
292 void Intersect(const Map& other) { | 314 void Intersect(const Map& other) { |
293 if (this->empty()) return; | 315 if (this->empty()) return; |
294 auto it = this->begin(); | 316 auto it = this->begin(); |
295 OperandLess less; | 317 OperandLess less; |
296 for (const auto& o : other) { | 318 for (const auto& o : other) { |
297 while (less(it->first, o.first)) { | 319 while (less(it->first, o.first)) { |
298 this->erase(it++); | 320 this->erase(it++); |
299 if (it == this->end()) return; | 321 if (it == this->end()) return; |
300 } | 322 } |
301 if (it->first->Equals(o.first)) { | 323 if (*it->first == *o.first) { |
302 ++it; | 324 ++it; |
303 if (it == this->end()) return; | 325 if (it == this->end()) return; |
304 } else { | 326 } else { |
305 CHECK(less(o.first, it->first)); | 327 CHECK(less(o.first, it->first)); |
306 } | 328 } |
307 } | 329 } |
308 } | 330 } |
309 }; | 331 }; |
310 | 332 |
311 explicit OperandMap(Zone* zone) : map_(zone) {} | 333 explicit OperandMap(Zone* zone) : map_(zone) {} |
312 | 334 |
313 Map& map() { return map_; } | 335 Map& map() { return map_; } |
314 | 336 |
315 void RunParallelMoves(Zone* zone, const ParallelMove* move) { | 337 void RunParallelMoves(Zone* zone, const ParallelMove* moves) { |
316 // Compute outgoing mappings. | 338 // Compute outgoing mappings. |
317 Map to_insert(zone); | 339 Map to_insert(zone); |
318 auto moves = move->move_operands(); | 340 for (auto move : *moves) { |
319 for (auto i = moves->begin(); i != moves->end(); ++i) { | 341 if (move->IsEliminated()) continue; |
320 if (i->IsEliminated()) continue; | 342 auto cur = map().find(&move->source()); |
321 auto cur = map().find(i->source()); | |
322 CHECK(cur != map().end()); | 343 CHECK(cur != map().end()); |
323 auto res = | 344 auto res = |
324 to_insert.insert(std::make_pair(i->destination(), cur->second)); | 345 to_insert.insert(std::make_pair(&move->destination(), cur->second)); |
325 // Ensure injectivity of moves. | 346 // Ensure injectivity of moves. |
326 CHECK(res.second); | 347 CHECK(res.second); |
327 } | 348 } |
328 // Drop current mappings. | 349 // Drop current mappings. |
329 for (auto i = moves->begin(); i != moves->end(); ++i) { | 350 for (auto move : *moves) { |
330 if (i->IsEliminated()) continue; | 351 if (move->IsEliminated()) continue; |
331 auto cur = map().find(i->destination()); | 352 auto cur = map().find(&move->destination()); |
332 if (cur != map().end()) map().erase(cur); | 353 if (cur != map().end()) map().erase(cur); |
333 } | 354 } |
334 // Insert new values. | 355 // Insert new values. |
335 map().insert(to_insert.begin(), to_insert.end()); | 356 map().insert(to_insert.begin(), to_insert.end()); |
336 } | 357 } |
337 | 358 |
338 void RunGaps(Zone* zone, const Instruction* instr) { | 359 void RunGaps(Zone* zone, const Instruction* instr) { |
339 for (int i = Instruction::FIRST_GAP_POSITION; | 360 for (int i = Instruction::FIRST_GAP_POSITION; |
340 i <= Instruction::LAST_GAP_POSITION; i++) { | 361 i <= Instruction::LAST_GAP_POSITION; i++) { |
341 auto inner_pos = static_cast<Instruction::GapPosition>(i); | 362 auto inner_pos = static_cast<Instruction::GapPosition>(i); |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 int virtual_register = op_constraints[count].virtual_register_; | 699 int virtual_register = op_constraints[count].virtual_register_; |
679 current->Define(zone(), instr->OutputAt(i), virtual_register); | 700 current->Define(zone(), instr->OutputAt(i), virtual_register); |
680 } | 701 } |
681 } | 702 } |
682 } | 703 } |
683 } | 704 } |
684 | 705 |
685 } // namespace compiler | 706 } // namespace compiler |
686 } // namespace internal | 707 } // namespace internal |
687 } // namespace v8 | 708 } // namespace v8 |
OLD | NEW |