| Index: test/unittests/compiler/register-allocator-unittest.cc
|
| diff --git a/test/unittests/compiler/register-allocator-unittest.cc b/test/unittests/compiler/register-allocator-unittest.cc
|
| index dbcdedb7981072f86c18715ee6eaa6e506bd7b34..db457c0d65a19cc00eb9837cf3ae1ae54bd12bf6 100644
|
| --- a/test/unittests/compiler/register-allocator-unittest.cc
|
| +++ b/test/unittests/compiler/register-allocator-unittest.cc
|
| @@ -4,6 +4,7 @@
|
|
|
| #include "src/base/utils/random-number-generator.h"
|
| #include "src/compiler/register-allocator.h"
|
| +#include "src/compiler/register-allocator-verifier.h"
|
| #include "test/unittests/test-utils.h"
|
| #include "testing/gmock/include/gmock/gmock.h"
|
|
|
| @@ -37,7 +38,7 @@ static void InitializeRegisterNames() {
|
| }
|
| }
|
|
|
| -enum BlockCompletionType { kFallThrough, kBranch, kJump };
|
| +enum BlockCompletionType { kBlockEnd, kFallThrough, kBranch, kJump };
|
|
|
| struct BlockCompletion {
|
| BlockCompletionType type_;
|
| @@ -77,7 +78,8 @@ class RegisterAllocatorTest : public TestWithZone {
|
| num_double_registers_(kDefaultNRegs),
|
| instruction_blocks_(zone()),
|
| current_block_(nullptr),
|
| - is_last_block_(false) {
|
| + is_last_block_(false),
|
| + block_returns_(false) {
|
| InitializeRegisterNames();
|
| }
|
|
|
| @@ -142,21 +144,29 @@ class RegisterAllocatorTest : public TestWithZone {
|
|
|
| void StartBlock() {
|
| CHECK(!is_last_block_);
|
| + block_returns_ = false;
|
| NewBlock();
|
| }
|
|
|
| void EndBlock(BlockCompletion completion = FallThrough()) {
|
| completions_.push_back(completion);
|
| switch (completion.type_) {
|
| + case kBlockEnd:
|
| + CHECK(false); // unreachable;
|
| + break;
|
| case kFallThrough:
|
| - if (is_last_block_) break;
|
| - // TODO(dcarney): we don't emit this after returns.
|
| + if (is_last_block_ || block_returns_) {
|
| + completions_.back().type_ = kBlockEnd;
|
| + break;
|
| + }
|
| EmitFallThrough();
|
| break;
|
| case kJump:
|
| + CHECK(!block_returns_);
|
| EmitJump();
|
| break;
|
| case kBranch:
|
| + CHECK(!block_returns_);
|
| EmitBranch(completion.vreg_);
|
| break;
|
| }
|
| @@ -169,6 +179,7 @@ class RegisterAllocatorTest : public TestWithZone {
|
| CHECK_EQ(nullptr, current_block_);
|
| CHECK(is_last_block_);
|
| WireBlocks();
|
| + RegisterAllocatorVerifier verifier(zone(), config(), sequence());
|
| if (FLAG_trace_alloc || FLAG_trace_turbo) {
|
| OFStream os(stdout);
|
| PrintableInstructionSequence printable = {config(), sequence()};
|
| @@ -180,6 +191,8 @@ class RegisterAllocatorTest : public TestWithZone {
|
| PrintableInstructionSequence printable = {config(), sequence()};
|
| os << "After: " << std::endl << printable << std::endl;
|
| }
|
| + verifier.VerifyAssignment();
|
| + verifier.VerifyGapMoves();
|
| }
|
|
|
| int NewReg() { return sequence()->NextVirtualRegister(); }
|
| @@ -192,6 +205,7 @@ class RegisterAllocatorTest : public TestWithZone {
|
| }
|
|
|
| Instruction* Return(int vreg) {
|
| + block_returns_ = true;
|
| InstructionOperand* inputs[1]{UseRegister(vreg)};
|
| return Emit(kArchRet, 0, nullptr, 1, inputs);
|
| }
|
| @@ -344,12 +358,11 @@ class RegisterAllocatorTest : public TestWithZone {
|
| void WireBlocks() {
|
| CHECK(instruction_blocks_.size() == completions_.size());
|
| size_t offset = 0;
|
| - size_t size = instruction_blocks_.size();
|
| for (const auto& completion : completions_) {
|
| switch (completion.type_) {
|
| - case kFallThrough:
|
| - if (offset == size - 1) break;
|
| - // Fallthrough.
|
| + case kBlockEnd:
|
| + break;
|
| + case kFallThrough: // Fallthrough.
|
| case kJump:
|
| WireBlock(offset, completion.offset_0_);
|
| break;
|
| @@ -393,6 +406,7 @@ class RegisterAllocatorTest : public TestWithZone {
|
| LoopBlocks loop_blocks_;
|
| InstructionBlock* current_block_;
|
| bool is_last_block_;
|
| + bool block_returns_;
|
| };
|
|
|
|
|
|
|