Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(854)

Side by Side Diff: test/unittests/compiler/register-allocator-unittest.cc

Issue 704193007: [turbofan] add gap move verifier (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebase Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/base/utils/random-number-generator.h" 5 #include "src/base/utils/random-number-generator.h"
6 #include "src/compiler/register-allocator.h" 6 #include "src/compiler/register-allocator.h"
7 #include "src/compiler/register-allocator-verifier.h"
7 #include "test/unittests/test-utils.h" 8 #include "test/unittests/test-utils.h"
8 #include "testing/gmock/include/gmock/gmock.h" 9 #include "testing/gmock/include/gmock/gmock.h"
9 10
10 namespace v8 { 11 namespace v8 {
11 namespace internal { 12 namespace internal {
12 namespace compiler { 13 namespace compiler {
13 14
14 typedef BasicBlock::RpoNumber Rpo; 15 typedef BasicBlock::RpoNumber Rpo;
15 16
16 namespace { 17 namespace {
(...skipping 13 matching lines...) Expand all
30 loc += base::OS::SNPrintF(loc, 100, "gp_%d", i); 31 loc += base::OS::SNPrintF(loc, 100, "gp_%d", i);
31 *loc++ = 0; 32 *loc++ = 0;
32 } 33 }
33 for (int i = 0; i < RegisterConfiguration::kMaxDoubleRegisters; ++i) { 34 for (int i = 0; i < RegisterConfiguration::kMaxDoubleRegisters; ++i) {
34 double_register_names_[i] = loc; 35 double_register_names_[i] = loc;
35 loc += base::OS::SNPrintF(loc, 100, "fp_%d", i) + 1; 36 loc += base::OS::SNPrintF(loc, 100, "fp_%d", i) + 1;
36 *loc++ = 0; 37 *loc++ = 0;
37 } 38 }
38 } 39 }
39 40
40 enum BlockCompletionType { kFallThrough, kBranch, kJump }; 41 enum BlockCompletionType { kBlockEnd, kFallThrough, kBranch, kJump };
41 42
42 struct BlockCompletion { 43 struct BlockCompletion {
43 BlockCompletionType type_; 44 BlockCompletionType type_;
44 int vreg_; 45 int vreg_;
45 int offset_0_; 46 int offset_0_;
46 int offset_1_; 47 int offset_1_;
47 }; 48 };
48 49
49 static const int kInvalidJumpOffset = kMinInt; 50 static const int kInvalidJumpOffset = kMinInt;
50 51
(...skipping 19 matching lines...) Expand all
70 71
71 class RegisterAllocatorTest : public TestWithZone { 72 class RegisterAllocatorTest : public TestWithZone {
72 public: 73 public:
73 static const int kDefaultNRegs = 4; 74 static const int kDefaultNRegs = 4;
74 75
75 RegisterAllocatorTest() 76 RegisterAllocatorTest()
76 : num_general_registers_(kDefaultNRegs), 77 : num_general_registers_(kDefaultNRegs),
77 num_double_registers_(kDefaultNRegs), 78 num_double_registers_(kDefaultNRegs),
78 instruction_blocks_(zone()), 79 instruction_blocks_(zone()),
79 current_block_(nullptr), 80 current_block_(nullptr),
80 is_last_block_(false) { 81 is_last_block_(false),
82 block_returns_(false) {
81 InitializeRegisterNames(); 83 InitializeRegisterNames();
82 } 84 }
83 85
84 void SetNumRegs(int num_general_registers, int num_double_registers) { 86 void SetNumRegs(int num_general_registers, int num_double_registers) {
85 CHECK(instruction_blocks_.empty()); 87 CHECK(instruction_blocks_.empty());
86 num_general_registers_ = num_general_registers; 88 num_general_registers_ = num_general_registers;
87 num_double_registers_ = num_double_registers; 89 num_double_registers_ = num_double_registers;
88 } 90 }
89 91
90 RegisterConfiguration* config() { 92 RegisterConfiguration* config() {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 } 137 }
136 138
137 void StartLastBlock() { 139 void StartLastBlock() {
138 CHECK(!is_last_block_); 140 CHECK(!is_last_block_);
139 is_last_block_ = true; 141 is_last_block_ = true;
140 NewBlock(); 142 NewBlock();
141 } 143 }
142 144
143 void StartBlock() { 145 void StartBlock() {
144 CHECK(!is_last_block_); 146 CHECK(!is_last_block_);
147 block_returns_ = false;
145 NewBlock(); 148 NewBlock();
146 } 149 }
147 150
148 void EndBlock(BlockCompletion completion = FallThrough()) { 151 void EndBlock(BlockCompletion completion = FallThrough()) {
149 completions_.push_back(completion); 152 completions_.push_back(completion);
150 switch (completion.type_) { 153 switch (completion.type_) {
154 case kBlockEnd:
155 CHECK(false); // unreachable;
156 break;
151 case kFallThrough: 157 case kFallThrough:
152 if (is_last_block_) break; 158 if (is_last_block_ || block_returns_) {
153 // TODO(dcarney): we don't emit this after returns. 159 completions_.back().type_ = kBlockEnd;
160 break;
161 }
154 EmitFallThrough(); 162 EmitFallThrough();
155 break; 163 break;
156 case kJump: 164 case kJump:
165 CHECK(!block_returns_);
157 EmitJump(); 166 EmitJump();
158 break; 167 break;
159 case kBranch: 168 case kBranch:
169 CHECK(!block_returns_);
160 EmitBranch(completion.vreg_); 170 EmitBranch(completion.vreg_);
161 break; 171 break;
162 } 172 }
163 CHECK(current_block_ != nullptr); 173 CHECK(current_block_ != nullptr);
164 sequence()->EndBlock(current_block_->rpo_number()); 174 sequence()->EndBlock(current_block_->rpo_number());
165 current_block_ = nullptr; 175 current_block_ = nullptr;
166 } 176 }
167 177
168 void Allocate() { 178 void Allocate() {
169 CHECK_EQ(nullptr, current_block_); 179 CHECK_EQ(nullptr, current_block_);
170 CHECK(is_last_block_); 180 CHECK(is_last_block_);
171 WireBlocks(); 181 WireBlocks();
182 RegisterAllocatorVerifier verifier(zone(), config(), sequence());
172 if (FLAG_trace_alloc || FLAG_trace_turbo) { 183 if (FLAG_trace_alloc || FLAG_trace_turbo) {
173 OFStream os(stdout); 184 OFStream os(stdout);
174 PrintableInstructionSequence printable = {config(), sequence()}; 185 PrintableInstructionSequence printable = {config(), sequence()};
175 os << "Before: " << std::endl << printable << std::endl; 186 os << "Before: " << std::endl << printable << std::endl;
176 } 187 }
177 allocator()->Allocate(); 188 allocator()->Allocate();
178 if (FLAG_trace_alloc || FLAG_trace_turbo) { 189 if (FLAG_trace_alloc || FLAG_trace_turbo) {
179 OFStream os(stdout); 190 OFStream os(stdout);
180 PrintableInstructionSequence printable = {config(), sequence()}; 191 PrintableInstructionSequence printable = {config(), sequence()};
181 os << "After: " << std::endl << printable << std::endl; 192 os << "After: " << std::endl << printable << std::endl;
182 } 193 }
194 verifier.VerifyAssignment();
195 verifier.VerifyGapMoves();
183 } 196 }
184 197
185 int NewReg() { return sequence()->NextVirtualRegister(); } 198 int NewReg() { return sequence()->NextVirtualRegister(); }
186 199
187 int Parameter() { 200 int Parameter() {
188 int vreg = NewReg(); 201 int vreg = NewReg();
189 InstructionOperand* outputs[1]{UseRegister(vreg)}; 202 InstructionOperand* outputs[1]{UseRegister(vreg)};
190 Emit(kArchNop, 1, outputs); 203 Emit(kArchNop, 1, outputs);
191 return vreg; 204 return vreg;
192 } 205 }
193 206
194 Instruction* Return(int vreg) { 207 Instruction* Return(int vreg) {
208 block_returns_ = true;
195 InstructionOperand* inputs[1]{UseRegister(vreg)}; 209 InstructionOperand* inputs[1]{UseRegister(vreg)};
196 return Emit(kArchRet, 0, nullptr, 1, inputs); 210 return Emit(kArchRet, 0, nullptr, 1, inputs);
197 } 211 }
198 212
199 PhiInstruction* Phi(int vreg) { 213 PhiInstruction* Phi(int vreg) {
200 PhiInstruction* phi = new (zone()) PhiInstruction(zone(), NewReg()); 214 PhiInstruction* phi = new (zone()) PhiInstruction(zone(), NewReg());
201 phi->operands().push_back(vreg); 215 phi->operands().push_back(vreg);
202 current_block_->AddPhi(phi); 216 current_block_->AddPhi(phi);
203 return phi; 217 return phi;
204 } 218 }
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 zone(), block_id, rpo, rpo, loop_header, loop_end, false); 351 zone(), block_id, rpo, rpo, loop_header, loop_end, false);
338 instruction_blocks_.push_back(instruction_block); 352 instruction_blocks_.push_back(instruction_block);
339 current_block_ = instruction_block; 353 current_block_ = instruction_block;
340 sequence()->StartBlock(rpo); 354 sequence()->StartBlock(rpo);
341 return instruction_block; 355 return instruction_block;
342 } 356 }
343 357
344 void WireBlocks() { 358 void WireBlocks() {
345 CHECK(instruction_blocks_.size() == completions_.size()); 359 CHECK(instruction_blocks_.size() == completions_.size());
346 size_t offset = 0; 360 size_t offset = 0;
347 size_t size = instruction_blocks_.size();
348 for (const auto& completion : completions_) { 361 for (const auto& completion : completions_) {
349 switch (completion.type_) { 362 switch (completion.type_) {
350 case kFallThrough: 363 case kBlockEnd:
351 if (offset == size - 1) break; 364 break;
352 // Fallthrough. 365 case kFallThrough: // Fallthrough.
353 case kJump: 366 case kJump:
354 WireBlock(offset, completion.offset_0_); 367 WireBlock(offset, completion.offset_0_);
355 break; 368 break;
356 case kBranch: 369 case kBranch:
357 WireBlock(offset, completion.offset_0_); 370 WireBlock(offset, completion.offset_0_);
358 WireBlock(offset, completion.offset_1_); 371 WireBlock(offset, completion.offset_1_);
359 break; 372 break;
360 } 373 }
361 ++offset; 374 ++offset;
362 } 375 }
(...skipping 23 matching lines...) Expand all
386 SmartPointer<InstructionSequence> sequence_; 399 SmartPointer<InstructionSequence> sequence_;
387 int num_general_registers_; 400 int num_general_registers_;
388 int num_double_registers_; 401 int num_double_registers_;
389 402
390 // Block building state. 403 // Block building state.
391 InstructionBlocks instruction_blocks_; 404 InstructionBlocks instruction_blocks_;
392 Completions completions_; 405 Completions completions_;
393 LoopBlocks loop_blocks_; 406 LoopBlocks loop_blocks_;
394 InstructionBlock* current_block_; 407 InstructionBlock* current_block_;
395 bool is_last_block_; 408 bool is_last_block_;
409 bool block_returns_;
396 }; 410 };
397 411
398 412
399 TEST_F(RegisterAllocatorTest, CanAllocateThreeRegisters) { 413 TEST_F(RegisterAllocatorTest, CanAllocateThreeRegisters) {
400 StartLastBlock(); 414 StartLastBlock();
401 int a_reg = Parameter(); 415 int a_reg = Parameter();
402 int b_reg = Parameter(); 416 int b_reg = Parameter();
403 int c_reg = NewReg(); 417 int c_reg = NewReg();
404 Instruction* res = EmitRRR(c_reg, a_reg, b_reg); 418 Instruction* res = EmitRRR(c_reg, a_reg, b_reg);
405 Return(c_reg); 419 Return(c_reg);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 // Return sum. 518 // Return sum.
505 Return(DefineConstant()); 519 Return(DefineConstant());
506 EndBlock(); 520 EndBlock();
507 521
508 Allocate(); 522 Allocate();
509 } 523 }
510 524
511 } // namespace compiler 525 } // namespace compiler
512 } // namespace internal 526 } // namespace internal
513 } // namespace v8 527 } // namespace v8
OLDNEW
« src/compiler/register-allocator-verifier.cc ('K') | « test/cctest/compiler/test-run-machops.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698