| 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 873b4ecd2aca2a240c83266058f15c65e7965e41..ed1cb32971736faba269db42c8e9a13571a7ae18 100644
|
| --- a/test/unittests/compiler/register-allocator-unittest.cc
|
| +++ b/test/unittests/compiler/register-allocator-unittest.cc
|
| @@ -9,6 +9,22 @@ namespace v8 {
|
| namespace internal {
|
| namespace compiler {
|
|
|
| +
|
| +namespace {
|
| +
|
| +// We can't just use the size of the moves collection, because of
|
| +// redundant moves which need to be discounted.
|
| +int GetMoveCount(const ParallelMove& moves) {
|
| + int move_count = 0;
|
| + for (auto move : moves) {
|
| + if (move->IsEliminated() || move->IsRedundant()) continue;
|
| + ++move_count;
|
| + }
|
| + return move_count;
|
| +}
|
| +}
|
| +
|
| +
|
| class RegisterAllocatorTest : public InstructionSequenceTest {
|
| public:
|
| void Allocate() {
|
| @@ -492,6 +508,54 @@ TEST_F(RegisterAllocatorTest, RegressionLoadConstantBeforeSpill) {
|
| }
|
|
|
|
|
| +TEST_F(RegisterAllocatorTest, DeferredBlockSpill) {
|
| + StartBlock(); // B0
|
| + auto var = EmitOI(Reg(0));
|
| + EndBlock(Branch(Reg(var), 1, 2));
|
| +
|
| + StartBlock(); // B1
|
| + EndBlock(Jump(3));
|
| +
|
| + StartBlock(true); // B2
|
| + EmitCall(Slot(-1), Slot(var));
|
| + EndBlock();
|
| +
|
| + StartBlock(); // B3
|
| + EmitNop();
|
| + EndBlock();
|
| +
|
| + StartBlock(); // B4
|
| + Return(Reg(var, 0));
|
| + EndBlock();
|
| +
|
| + Allocate();
|
| +
|
| + const int var_def_index = 1;
|
| + const int call_index = 3;
|
| + int expect_no_moves = FLAG_turbo_greedy_regalloc ? var_def_index : call_index;
|
| + int expect_spill_move =
|
| + FLAG_turbo_greedy_regalloc ? call_index : var_def_index;
|
| +
|
| + const ParallelMove* moves =
|
| + sequence()
|
| + ->InstructionAt(expect_no_moves)
|
| + ->GetOrCreateParallelMove(Instruction::START, zone());
|
| +
|
| + // We should have no parallel moves at the "expect_no_moves" position.
|
| + EXPECT_EQ(0, GetMoveCount(*moves));
|
| +
|
| + moves = sequence()
|
| + ->InstructionAt(expect_spill_move)
|
| + ->GetOrCreateParallelMove(Instruction::START, zone());
|
| + EXPECT_EQ(1, GetMoveCount(*moves));
|
| + for (auto move : *moves) {
|
| + if (move->IsEliminated() || move->IsRedundant()) continue;
|
| + EXPECT_TRUE(move->source().IsRegister());
|
| + EXPECT_TRUE(move->destination().IsStackSlot());
|
| + }
|
| +}
|
| +
|
| +
|
| namespace {
|
|
|
| enum class ParameterType { kFixedSlot, kSlot, kRegister, kFixedRegister };
|
|
|