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 |
deleted file mode 100644 |
index ed3558dc609606daaf366e83e02cbb704147a6ec..0000000000000000000000000000000000000000 |
--- a/test/unittests/compiler/register-allocator-unittest.cc |
+++ /dev/null |
@@ -1,798 +0,0 @@ |
-// Copyright 2014 the V8 project authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "src/compiler/pipeline.h" |
-#include "test/unittests/compiler/instruction-sequence-unittest.h" |
- |
-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; |
-} |
- |
- |
-bool AreOperandsOfSameType( |
- const AllocatedOperand& op, |
- const InstructionSequenceTest::TestOperand& test_op) { |
- bool test_op_is_reg = |
- (test_op.type_ == |
- InstructionSequenceTest::TestOperandType::kFixedRegister || |
- test_op.type_ == InstructionSequenceTest::TestOperandType::kRegister); |
- |
- return (op.IsRegister() && test_op_is_reg) || |
- (op.IsStackSlot() && !test_op_is_reg); |
-} |
- |
- |
-bool AllocatedOperandMatches( |
- const AllocatedOperand& op, |
- const InstructionSequenceTest::TestOperand& test_op) { |
- return AreOperandsOfSameType(op, test_op) && |
- ((op.IsRegister() ? op.GetRegister().code() : op.index()) == |
- test_op.value_ || |
- test_op.value_ == InstructionSequenceTest::kNoValue); |
-} |
- |
- |
-int GetParallelMoveCount(int instr_index, Instruction::GapPosition gap_pos, |
- const InstructionSequence* sequence) { |
- const ParallelMove* moves = |
- sequence->InstructionAt(instr_index)->GetParallelMove(gap_pos); |
- if (moves == nullptr) return 0; |
- return GetMoveCount(*moves); |
-} |
- |
- |
-bool IsParallelMovePresent(int instr_index, Instruction::GapPosition gap_pos, |
- const InstructionSequence* sequence, |
- const InstructionSequenceTest::TestOperand& src, |
- const InstructionSequenceTest::TestOperand& dest) { |
- const ParallelMove* moves = |
- sequence->InstructionAt(instr_index)->GetParallelMove(gap_pos); |
- EXPECT_NE(nullptr, moves); |
- |
- bool found_match = false; |
- for (auto move : *moves) { |
- if (move->IsEliminated() || move->IsRedundant()) continue; |
- if (AllocatedOperandMatches(AllocatedOperand::cast(move->source()), src) && |
- AllocatedOperandMatches(AllocatedOperand::cast(move->destination()), |
- dest)) { |
- found_match = true; |
- break; |
- } |
- } |
- return found_match; |
-} |
- |
-} // namespace |
- |
- |
-class RegisterAllocatorTest : public InstructionSequenceTest { |
- public: |
- void Allocate() { |
- WireBlocks(); |
- Pipeline::AllocateRegistersForTesting(config(), sequence(), true); |
- } |
-}; |
- |
- |
-TEST_F(RegisterAllocatorTest, CanAllocateThreeRegisters) { |
- // return p0 + p1; |
- StartBlock(); |
- auto a_reg = Parameter(); |
- auto b_reg = Parameter(); |
- auto c_reg = EmitOI(Reg(1), Reg(a_reg, 1), Reg(b_reg, 0)); |
- Return(c_reg); |
- EndBlock(Last()); |
- |
- Allocate(); |
-} |
- |
-TEST_F(RegisterAllocatorTest, CanAllocateFPRegisters) { |
- StartBlock(); |
- TestOperand inputs[] = { |
- Reg(FPParameter(kFloat64)), Reg(FPParameter(kFloat64)), |
- Reg(FPParameter(kFloat32)), Reg(FPParameter(kFloat32)), |
- Reg(FPParameter(kSimd128)), Reg(FPParameter(kSimd128))}; |
- VReg out1 = EmitOI(FPReg(1, kFloat64), arraysize(inputs), inputs); |
- Return(out1); |
- EndBlock(Last()); |
- |
- Allocate(); |
-} |
- |
-TEST_F(RegisterAllocatorTest, SimpleLoop) { |
- // i = K; |
- // while(true) { i++ } |
- StartBlock(); |
- auto i_reg = DefineConstant(); |
- EndBlock(); |
- |
- { |
- StartLoop(1); |
- |
- StartBlock(); |
- auto phi = Phi(i_reg, 2); |
- auto ipp = EmitOI(Same(), Reg(phi), Use(DefineConstant())); |
- SetInput(phi, 1, ipp); |
- EndBlock(Jump(0)); |
- |
- EndLoop(); |
- } |
- |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, SimpleBranch) { |
- // return i ? K1 : K2 |
- StartBlock(); |
- auto i = DefineConstant(); |
- EndBlock(Branch(Reg(i), 1, 2)); |
- |
- StartBlock(); |
- Return(DefineConstant()); |
- EndBlock(Last()); |
- |
- StartBlock(); |
- Return(DefineConstant()); |
- EndBlock(Last()); |
- |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, SimpleDiamond) { |
- // return p0 ? p0 : p0 |
- StartBlock(); |
- auto param = Parameter(); |
- EndBlock(Branch(Reg(param), 1, 2)); |
- |
- StartBlock(); |
- EndBlock(Jump(2)); |
- |
- StartBlock(); |
- EndBlock(Jump(1)); |
- |
- StartBlock(); |
- Return(param); |
- EndBlock(); |
- |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, SimpleDiamondPhi) { |
- // return i ? K1 : K2 |
- StartBlock(); |
- EndBlock(Branch(Reg(DefineConstant()), 1, 2)); |
- |
- StartBlock(); |
- auto t_val = DefineConstant(); |
- EndBlock(Jump(2)); |
- |
- StartBlock(); |
- auto f_val = DefineConstant(); |
- EndBlock(Jump(1)); |
- |
- StartBlock(); |
- Return(Reg(Phi(t_val, f_val))); |
- EndBlock(); |
- |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, DiamondManyPhis) { |
- const int kPhis = kDefaultNRegs * 2; |
- |
- StartBlock(); |
- EndBlock(Branch(Reg(DefineConstant()), 1, 2)); |
- |
- StartBlock(); |
- VReg t_vals[kPhis]; |
- for (int i = 0; i < kPhis; ++i) { |
- t_vals[i] = DefineConstant(); |
- } |
- EndBlock(Jump(2)); |
- |
- StartBlock(); |
- VReg f_vals[kPhis]; |
- for (int i = 0; i < kPhis; ++i) { |
- f_vals[i] = DefineConstant(); |
- } |
- EndBlock(Jump(1)); |
- |
- StartBlock(); |
- TestOperand merged[kPhis]; |
- for (int i = 0; i < kPhis; ++i) { |
- merged[i] = Use(Phi(t_vals[i], f_vals[i])); |
- } |
- Return(EmitCall(Slot(-1), kPhis, merged)); |
- EndBlock(); |
- |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, DoubleDiamondManyRedundantPhis) { |
- const int kPhis = kDefaultNRegs * 2; |
- |
- // First diamond. |
- StartBlock(); |
- VReg vals[kPhis]; |
- for (int i = 0; i < kPhis; ++i) { |
- vals[i] = Parameter(Slot(-1 - i)); |
- } |
- EndBlock(Branch(Reg(DefineConstant()), 1, 2)); |
- |
- StartBlock(); |
- EndBlock(Jump(2)); |
- |
- StartBlock(); |
- EndBlock(Jump(1)); |
- |
- // Second diamond. |
- StartBlock(); |
- EndBlock(Branch(Reg(DefineConstant()), 1, 2)); |
- |
- StartBlock(); |
- EndBlock(Jump(2)); |
- |
- StartBlock(); |
- EndBlock(Jump(1)); |
- |
- StartBlock(); |
- TestOperand merged[kPhis]; |
- for (int i = 0; i < kPhis; ++i) { |
- merged[i] = Use(Phi(vals[i], vals[i])); |
- } |
- Return(EmitCall(Reg(0), kPhis, merged)); |
- EndBlock(); |
- |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, RegressionPhisNeedTooManyRegisters) { |
- const size_t kNumRegs = 3; |
- const size_t kParams = kNumRegs + 1; |
- // Override number of registers. |
- SetNumRegs(kNumRegs, kNumRegs); |
- |
- StartBlock(); |
- auto constant = DefineConstant(); |
- VReg parameters[kParams]; |
- for (size_t i = 0; i < arraysize(parameters); ++i) { |
- parameters[i] = DefineConstant(); |
- } |
- EndBlock(); |
- |
- PhiInstruction* phis[kParams]; |
- { |
- StartLoop(2); |
- |
- // Loop header. |
- StartBlock(); |
- |
- for (size_t i = 0; i < arraysize(parameters); ++i) { |
- phis[i] = Phi(parameters[i], 2); |
- } |
- |
- // Perform some computations. |
- // something like phi[i] += const |
- for (size_t i = 0; i < arraysize(parameters); ++i) { |
- auto result = EmitOI(Same(), Reg(phis[i]), Use(constant)); |
- SetInput(phis[i], 1, result); |
- } |
- |
- EndBlock(Branch(Reg(DefineConstant()), 1, 2)); |
- |
- // Jump back to loop header. |
- StartBlock(); |
- EndBlock(Jump(-1)); |
- |
- EndLoop(); |
- } |
- |
- StartBlock(); |
- Return(DefineConstant()); |
- EndBlock(); |
- |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, SpillPhi) { |
- StartBlock(); |
- EndBlock(Branch(Imm(), 1, 2)); |
- |
- StartBlock(); |
- auto left = Define(Reg(0)); |
- EndBlock(Jump(2)); |
- |
- StartBlock(); |
- auto right = Define(Reg(0)); |
- EndBlock(); |
- |
- StartBlock(); |
- auto phi = Phi(left, right); |
- EmitCall(Slot(-1)); |
- Return(Reg(phi)); |
- EndBlock(); |
- |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, MoveLotsOfConstants) { |
- StartBlock(); |
- VReg constants[kDefaultNRegs]; |
- for (size_t i = 0; i < arraysize(constants); ++i) { |
- constants[i] = DefineConstant(); |
- } |
- TestOperand call_ops[kDefaultNRegs * 2]; |
- for (int i = 0; i < kDefaultNRegs; ++i) { |
- call_ops[i] = Reg(constants[i], i); |
- } |
- for (int i = 0; i < kDefaultNRegs; ++i) { |
- call_ops[i + kDefaultNRegs] = Slot(constants[i], i); |
- } |
- EmitCall(Slot(-1), arraysize(call_ops), call_ops); |
- EndBlock(Last()); |
- |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, SplitBeforeInstruction) { |
- const int kNumRegs = 6; |
- SetNumRegs(kNumRegs, kNumRegs); |
- |
- StartBlock(); |
- |
- // Stack parameters/spilled values. |
- auto p_0 = Define(Slot(-1)); |
- auto p_1 = Define(Slot(-2)); |
- |
- // Fill registers. |
- VReg values[kNumRegs]; |
- for (size_t i = 0; i < arraysize(values); ++i) { |
- values[i] = Define(Reg(static_cast<int>(i))); |
- } |
- |
- // values[0] will be split in the second half of this instruction. |
- // Models Intel mod instructions. |
- EmitOI(Reg(0), Reg(p_0, 1), UniqueReg(p_1)); |
- EmitI(Reg(values[0], 0)); |
- EndBlock(Last()); |
- |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, SplitBeforeInstruction2) { |
- const int kNumRegs = 6; |
- SetNumRegs(kNumRegs, kNumRegs); |
- |
- StartBlock(); |
- |
- // Stack parameters/spilled values. |
- auto p_0 = Define(Slot(-1)); |
- auto p_1 = Define(Slot(-2)); |
- |
- // Fill registers. |
- VReg values[kNumRegs]; |
- for (size_t i = 0; i < arraysize(values); ++i) { |
- values[i] = Define(Reg(static_cast<int>(i))); |
- } |
- |
- // values[0] and [1] will be split in the second half of this instruction. |
- EmitOOI(Reg(0), Reg(1), Reg(p_0, 0), Reg(p_1, 1)); |
- EmitI(Reg(values[0]), Reg(values[1])); |
- EndBlock(Last()); |
- |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, NestedDiamondPhiMerge) { |
- // Outer diamond. |
- StartBlock(); |
- EndBlock(Branch(Imm(), 1, 5)); |
- |
- // Diamond 1 |
- StartBlock(); |
- EndBlock(Branch(Imm(), 1, 2)); |
- |
- StartBlock(); |
- auto ll = Define(Reg()); |
- EndBlock(Jump(2)); |
- |
- StartBlock(); |
- auto lr = Define(Reg()); |
- EndBlock(); |
- |
- StartBlock(); |
- auto l_phi = Phi(ll, lr); |
- EndBlock(Jump(5)); |
- |
- // Diamond 2 |
- StartBlock(); |
- EndBlock(Branch(Imm(), 1, 2)); |
- |
- StartBlock(); |
- auto rl = Define(Reg()); |
- EndBlock(Jump(2)); |
- |
- StartBlock(); |
- auto rr = Define(Reg()); |
- EndBlock(); |
- |
- StartBlock(); |
- auto r_phi = Phi(rl, rr); |
- EndBlock(); |
- |
- // Outer diamond merge. |
- StartBlock(); |
- auto phi = Phi(l_phi, r_phi); |
- Return(Reg(phi)); |
- EndBlock(); |
- |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, NestedDiamondPhiMergeDifferent) { |
- // Outer diamond. |
- StartBlock(); |
- EndBlock(Branch(Imm(), 1, 5)); |
- |
- // Diamond 1 |
- StartBlock(); |
- EndBlock(Branch(Imm(), 1, 2)); |
- |
- StartBlock(); |
- auto ll = Define(Reg(0)); |
- EndBlock(Jump(2)); |
- |
- StartBlock(); |
- auto lr = Define(Reg(1)); |
- EndBlock(); |
- |
- StartBlock(); |
- auto l_phi = Phi(ll, lr); |
- EndBlock(Jump(5)); |
- |
- // Diamond 2 |
- StartBlock(); |
- EndBlock(Branch(Imm(), 1, 2)); |
- |
- StartBlock(); |
- auto rl = Define(Reg(2)); |
- EndBlock(Jump(2)); |
- |
- StartBlock(); |
- auto rr = Define(Reg(3)); |
- EndBlock(); |
- |
- StartBlock(); |
- auto r_phi = Phi(rl, rr); |
- EndBlock(); |
- |
- // Outer diamond merge. |
- StartBlock(); |
- auto phi = Phi(l_phi, r_phi); |
- Return(Reg(phi)); |
- EndBlock(); |
- |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, RegressionSplitBeforeAndMove) { |
- StartBlock(); |
- |
- // Fill registers. |
- VReg values[kDefaultNRegs]; |
- for (size_t i = 0; i < arraysize(values); ++i) { |
- if (i == 0 || i == 1) continue; // Leave a hole for c_1 to take. |
- values[i] = Define(Reg(static_cast<int>(i))); |
- } |
- |
- auto c_0 = DefineConstant(); |
- auto c_1 = DefineConstant(); |
- |
- EmitOI(Reg(1), Reg(c_0, 0), UniqueReg(c_1)); |
- |
- // Use previous values to force c_1 to split before the previous instruction. |
- for (size_t i = 0; i < arraysize(values); ++i) { |
- if (i == 0 || i == 1) continue; |
- EmitI(Reg(values[i], static_cast<int>(i))); |
- } |
- |
- EndBlock(Last()); |
- |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, RegressionSpillTwice) { |
- StartBlock(); |
- auto p_0 = Parameter(Reg(1)); |
- EmitCall(Slot(-2), Unique(p_0), Reg(p_0, 1)); |
- EndBlock(Last()); |
- |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, RegressionLoadConstantBeforeSpill) { |
- StartBlock(); |
- // Fill registers. |
- VReg values[kDefaultNRegs]; |
- for (size_t i = arraysize(values); i > 0; --i) { |
- values[i - 1] = Define(Reg(static_cast<int>(i - 1))); |
- } |
- auto c = DefineConstant(); |
- auto to_spill = Define(Reg()); |
- EndBlock(Jump(1)); |
- |
- { |
- StartLoop(1); |
- |
- StartBlock(); |
- // Create a use for c in second half of prev block's last gap |
- Phi(c); |
- for (size_t i = arraysize(values); i > 0; --i) { |
- Phi(values[i - 1]); |
- } |
- EndBlock(Jump(1)); |
- |
- EndLoop(); |
- } |
- |
- StartBlock(); |
- // Force c to split within to_spill's definition. |
- EmitI(Reg(c)); |
- EmitI(Reg(to_spill)); |
- EndBlock(Last()); |
- |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, DiamondWithCallFirstBlock) { |
- StartBlock(); |
- auto x = EmitOI(Reg(0)); |
- EndBlock(Branch(Reg(x), 1, 2)); |
- |
- StartBlock(); |
- EmitCall(Slot(-1)); |
- auto occupy = EmitOI(Reg(0)); |
- EndBlock(Jump(2)); |
- |
- StartBlock(); |
- EndBlock(FallThrough()); |
- |
- StartBlock(); |
- Use(occupy); |
- Return(Reg(x)); |
- EndBlock(); |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, DiamondWithCallSecondBlock) { |
- StartBlock(); |
- auto x = EmitOI(Reg(0)); |
- EndBlock(Branch(Reg(x), 1, 2)); |
- |
- StartBlock(); |
- EndBlock(Jump(2)); |
- |
- StartBlock(); |
- EmitCall(Slot(-1)); |
- auto occupy = EmitOI(Reg(0)); |
- EndBlock(FallThrough()); |
- |
- StartBlock(); |
- Use(occupy); |
- Return(Reg(x)); |
- EndBlock(); |
- Allocate(); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, SingleDeferredBlockSpill) { |
- StartBlock(); // B0 |
- auto var = EmitOI(Reg(0)); |
- EndBlock(Branch(Reg(var), 1, 2)); |
- |
- StartBlock(); // B1 |
- EndBlock(Jump(2)); |
- |
- 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_preprocess_ranges ? var_def_index : call_index; |
- int expect_spill_move = |
- FLAG_turbo_preprocess_ranges ? call_index : var_def_index; |
- |
- // We should have no parallel moves at the "expect_no_moves" position. |
- EXPECT_EQ( |
- 0, GetParallelMoveCount(expect_no_moves, Instruction::START, sequence())); |
- |
- // The spill should be performed at the position expect_spill_move. |
- EXPECT_TRUE(IsParallelMovePresent(expect_spill_move, Instruction::START, |
- sequence(), Reg(0), Slot(0))); |
-} |
- |
- |
-TEST_F(RegisterAllocatorTest, MultipleDeferredBlockSpills) { |
- if (!FLAG_turbo_preprocess_ranges) return; |
- |
- StartBlock(); // B0 |
- auto var1 = EmitOI(Reg(0)); |
- auto var2 = EmitOI(Reg(1)); |
- auto var3 = EmitOI(Reg(2)); |
- EndBlock(Branch(Reg(var1, 0), 1, 2)); |
- |
- StartBlock(true); // B1 |
- EmitCall(Slot(-2), Slot(var1)); |
- EndBlock(Jump(2)); |
- |
- StartBlock(true); // B2 |
- EmitCall(Slot(-1), Slot(var2)); |
- EndBlock(); |
- |
- StartBlock(); // B3 |
- EmitNop(); |
- EndBlock(); |
- |
- StartBlock(); // B4 |
- Return(Reg(var3, 2)); |
- EndBlock(); |
- |
- const int def_of_v2 = 3; |
- const int call_in_b1 = 4; |
- const int call_in_b2 = 6; |
- const int end_of_b1 = 5; |
- const int end_of_b2 = 7; |
- const int start_of_b3 = 8; |
- |
- Allocate(); |
- // TODO(mtrofin): at the moment, the linear allocator spills var1 and var2, |
- // so only var3 is spilled in deferred blocks. |
- const int var3_reg = 2; |
- const int var3_slot = 2; |
- |
- EXPECT_FALSE(IsParallelMovePresent(def_of_v2, Instruction::START, sequence(), |
- Reg(var3_reg), Slot())); |
- EXPECT_TRUE(IsParallelMovePresent(call_in_b1, Instruction::START, sequence(), |
- Reg(var3_reg), Slot(var3_slot))); |
- EXPECT_TRUE(IsParallelMovePresent(end_of_b1, Instruction::START, sequence(), |
- Slot(var3_slot), Reg())); |
- |
- EXPECT_TRUE(IsParallelMovePresent(call_in_b2, Instruction::START, sequence(), |
- Reg(var3_reg), Slot(var3_slot))); |
- EXPECT_TRUE(IsParallelMovePresent(end_of_b2, Instruction::START, sequence(), |
- Slot(var3_slot), Reg())); |
- |
- |
- EXPECT_EQ(0, |
- GetParallelMoveCount(start_of_b3, Instruction::START, sequence())); |
-} |
- |
- |
-namespace { |
- |
-enum class ParameterType { kFixedSlot, kSlot, kRegister, kFixedRegister }; |
- |
-const ParameterType kParameterTypes[] = { |
- ParameterType::kFixedSlot, ParameterType::kSlot, ParameterType::kRegister, |
- ParameterType::kFixedRegister}; |
- |
-class SlotConstraintTest : public RegisterAllocatorTest, |
- public ::testing::WithParamInterface< |
- ::testing::tuple<ParameterType, int>> { |
- public: |
- static const int kMaxVariant = 5; |
- |
- protected: |
- ParameterType parameter_type() const { |
- return ::testing::get<0>(B::GetParam()); |
- } |
- int variant() const { return ::testing::get<1>(B::GetParam()); } |
- |
- private: |
- typedef ::testing::WithParamInterface<::testing::tuple<ParameterType, int>> B; |
-}; |
- |
-} // namespace |
- |
- |
-#if GTEST_HAS_COMBINE |
- |
-TEST_P(SlotConstraintTest, SlotConstraint) { |
- StartBlock(); |
- VReg p_0; |
- switch (parameter_type()) { |
- case ParameterType::kFixedSlot: |
- p_0 = Parameter(Slot(-1)); |
- break; |
- case ParameterType::kSlot: |
- p_0 = Parameter(Slot(-1)); |
- break; |
- case ParameterType::kRegister: |
- p_0 = Parameter(Reg()); |
- break; |
- case ParameterType::kFixedRegister: |
- p_0 = Parameter(Reg(1)); |
- break; |
- } |
- switch (variant()) { |
- case 0: |
- EmitI(Slot(p_0), Reg(p_0)); |
- break; |
- case 1: |
- EmitI(Slot(p_0)); |
- break; |
- case 2: |
- EmitI(Reg(p_0)); |
- EmitI(Slot(p_0)); |
- break; |
- case 3: |
- EmitI(Slot(p_0)); |
- EmitI(Reg(p_0)); |
- break; |
- case 4: |
- EmitI(Slot(p_0, -1), Slot(p_0), Reg(p_0), Reg(p_0, 1)); |
- break; |
- default: |
- UNREACHABLE(); |
- break; |
- } |
- EndBlock(Last()); |
- |
- Allocate(); |
-} |
- |
- |
-INSTANTIATE_TEST_CASE_P( |
- RegisterAllocatorTest, SlotConstraintTest, |
- ::testing::Combine(::testing::ValuesIn(kParameterTypes), |
- ::testing::Range(0, SlotConstraintTest::kMaxVariant))); |
- |
-#endif // GTEST_HAS_COMBINE |
- |
-} // namespace compiler |
-} // namespace internal |
-} // namespace v8 |