diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/locations.h | 3 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 7 | ||||
-rw-r--r-- | compiler/optimizing/register_allocator.cc | 16 | ||||
-rw-r--r-- | compiler/optimizing/register_allocator.h | 10 | ||||
-rw-r--r-- | compiler/optimizing/register_allocator_test.cc | 110 |
5 files changed, 33 insertions, 113 deletions
diff --git a/compiler/optimizing/locations.h b/compiler/optimizing/locations.h index 20099ebbc2..2209f05c0b 100644 --- a/compiler/optimizing/locations.h +++ b/compiler/optimizing/locations.h @@ -737,7 +737,8 @@ class LocationSummary : public ArenaObject<kArenaAllocLocationSummary> { // Custom slow path caller saves. Valid only if indicated by slow_path_calling_convention_. RegisterSet custom_slow_path_caller_saves_; - friend class RegisterAllocatorTest; + ART_FRIEND_TEST(RegisterAllocatorTest, ExpectedInRegisterHint); + ART_FRIEND_TEST(RegisterAllocatorTest, SameAsFirstInputHint); DISALLOW_COPY_AND_ASSIGN(LocationSummary); }; diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 763dc88e8a..45d534a9ec 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -590,7 +590,6 @@ NO_INLINE // Avoid increasing caller's frame size by large stack-allocated obje static void AllocateRegisters(HGraph* graph, CodeGenerator* codegen, PassObserver* pass_observer, - RegisterAllocator::Strategy strategy, OptimizingCompilerStats* stats) { { PassScope scope(PrepareForRegisterAllocation::kPrepareForRegisterAllocationPassName, @@ -608,7 +607,7 @@ static void AllocateRegisters(HGraph* graph, { PassScope scope(RegisterAllocator::kRegisterAllocatorPassName, pass_observer); std::unique_ptr<RegisterAllocator> register_allocator = - RegisterAllocator::Create(&local_allocator, codegen, liveness, strategy); + RegisterAllocator::Create(&local_allocator, codegen, liveness); register_allocator->AllocateRegisters(); } } @@ -933,12 +932,9 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* allocator, } } - RegisterAllocator::Strategy regalloc_strategy = - compiler_options.GetRegisterAllocationStrategy(); AllocateRegisters(graph, codegen.get(), &pass_observer, - regalloc_strategy, compilation_stats_.get()); if (UNLIKELY(codegen->GetFrameSize() > codegen->GetMaximumFrameSize())) { @@ -1039,7 +1035,6 @@ CodeGenerator* OptimizingCompiler::TryCompileIntrinsic( AllocateRegisters(graph, codegen.get(), &pass_observer, - compiler_options.GetRegisterAllocationStrategy(), compilation_stats_.get()); if (!codegen->IsLeafMethod()) { VLOG(compiler) << "Intrinsic method is not leaf: " << method->GetIntrinsic() diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc index 1b3a9a6285..a318d43412 100644 --- a/compiler/optimizing/register_allocator.cc +++ b/compiler/optimizing/register_allocator.cc @@ -65,19 +65,9 @@ RegisterAllocator::RegisterAllocator(ScopedArenaAllocator* allocator, std::unique_ptr<RegisterAllocator> RegisterAllocator::Create(ScopedArenaAllocator* allocator, CodeGenerator* codegen, - const SsaLivenessAnalysis& analysis, - Strategy strategy) { - switch (strategy) { - case kRegisterAllocatorLinearScan: - return std::unique_ptr<RegisterAllocator>( - new (allocator) RegisterAllocatorLinearScan(allocator, codegen, analysis)); - case kRegisterAllocatorGraphColor: - LOG(FATAL) << "Graph coloring register allocator has been removed."; - UNREACHABLE(); - default: - LOG(FATAL) << "Invalid register allocation strategy: " << strategy; - UNREACHABLE(); - } + const SsaLivenessAnalysis& analysis) { + return std::unique_ptr<RegisterAllocator>( + new (allocator) RegisterAllocatorLinearScan(allocator, codegen, analysis)); } RegisterAllocator::~RegisterAllocator() { diff --git a/compiler/optimizing/register_allocator.h b/compiler/optimizing/register_allocator.h index bc192f29d7..6d59b1686c 100644 --- a/compiler/optimizing/register_allocator.h +++ b/compiler/optimizing/register_allocator.h @@ -38,22 +38,14 @@ class SsaLivenessAnalysis; */ class RegisterAllocator : public DeletableArenaObject<kArenaAllocRegisterAllocator> { public: - enum Strategy { - kRegisterAllocatorLinearScan, - kRegisterAllocatorGraphColor - }; - enum class RegisterType { kCoreRegister, kFpRegister }; - static constexpr Strategy kRegisterAllocatorDefault = kRegisterAllocatorLinearScan; - static std::unique_ptr<RegisterAllocator> Create(ScopedArenaAllocator* allocator, CodeGenerator* codegen, - const SsaLivenessAnalysis& analysis, - Strategy strategy = kRegisterAllocatorDefault); + const SsaLivenessAnalysis& analysis); virtual ~RegisterAllocator(); diff --git a/compiler/optimizing/register_allocator_test.cc b/compiler/optimizing/register_allocator_test.cc index ab5e5de859..8f1e724569 100644 --- a/compiler/optimizing/register_allocator_test.cc +++ b/compiler/optimizing/register_allocator_test.cc @@ -34,8 +34,6 @@ namespace art HIDDEN { -using Strategy = RegisterAllocator::Strategy; - // Note: the register allocator tests rely on the fact that constants have live // intervals and registers get allocated to them. @@ -47,24 +45,12 @@ class RegisterAllocatorTest : public CommonCompilerTest, public OptimizingUnitTe compiler_options_ = CommonCompilerTest::CreateCompilerOptions(InstructionSet::kX86, "default"); } - // These functions need to access private variables of LocationSummary, so we declare it - // as a member of RegisterAllocatorTest, which we make a friend class. - void SameAsFirstInputHint(Strategy strategy); - void ExpectedInRegisterHint(Strategy strategy); - // Helper functions that make use of the OptimizingUnitTest's members. - bool Check(const std::vector<uint16_t>& data, Strategy strategy); - void CFG1(Strategy strategy); - void Loop1(Strategy strategy); - void Loop2(Strategy strategy); - void Loop3(Strategy strategy); - void DeadPhi(Strategy strategy); + bool Check(const std::vector<uint16_t>& data); HGraph* BuildIfElseWithPhi(HPhi** phi, HInstruction** input1, HInstruction** input2); - void PhiHint(Strategy strategy); HGraph* BuildFieldReturn(HInstruction** field, HInstruction** ret); HGraph* BuildTwoSubs(HInstruction** first_sub, HInstruction** second_sub); HGraph* BuildDiv(HInstruction** div); - void ExpectedExactInRegisterAndSameOutputHint(Strategy strategy); bool ValidateIntervals(const ScopedArenaVector<LiveInterval*>& intervals, const CodeGenerator& codegen) { @@ -80,23 +66,13 @@ class RegisterAllocatorTest : public CommonCompilerTest, public OptimizingUnitTe std::unique_ptr<CompilerOptions> compiler_options_; }; -// This macro should include all register allocation strategies that should be tested. -#define TEST_ALL_STRATEGIES(test_name)\ -TEST_F(RegisterAllocatorTest, test_name##_LinearScan) {\ - test_name(Strategy::kRegisterAllocatorLinearScan);\ -}\ -/* Note: Graph coloring register allocator has been removed, so the test is DISABLED. */ \ -TEST_F(RegisterAllocatorTest, DISABLED_##test_name##_GraphColor) {\ - test_name(Strategy::kRegisterAllocatorGraphColor);\ -} - -bool RegisterAllocatorTest::Check(const std::vector<uint16_t>& data, Strategy strategy) { +bool RegisterAllocatorTest::Check(const std::vector<uint16_t>& data) { HGraph* graph = CreateCFG(data); x86::CodeGeneratorX86 codegen(graph, *compiler_options_); SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); liveness.Analyze(); std::unique_ptr<RegisterAllocator> register_allocator = - RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness, strategy); + RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness); register_allocator->AllocateRegisters(); return register_allocator->Validate(false); } @@ -179,7 +155,7 @@ TEST_F(RegisterAllocatorTest, ValidateIntervals) { } } -void RegisterAllocatorTest::CFG1(Strategy strategy) { +TEST_F(RegisterAllocatorTest, CFG1) { /* * Test the following snippet: * return 0; @@ -196,12 +172,10 @@ void RegisterAllocatorTest::CFG1(Strategy strategy) { Instruction::CONST_4 | 0 | 0, Instruction::RETURN); - ASSERT_TRUE(Check(data, strategy)); + ASSERT_TRUE(Check(data)); } -TEST_ALL_STRATEGIES(CFG1); - -void RegisterAllocatorTest::Loop1(Strategy strategy) { +TEST_F(RegisterAllocatorTest, Loop1) { /* * Test the following snippet: * int a = 0; @@ -237,12 +211,10 @@ void RegisterAllocatorTest::Loop1(Strategy strategy) { Instruction::CONST_4 | 5 << 12 | 1 << 8, Instruction::RETURN | 1 << 8); - ASSERT_TRUE(Check(data, strategy)); + ASSERT_TRUE(Check(data)); } -TEST_ALL_STRATEGIES(Loop1); - -void RegisterAllocatorTest::Loop2(Strategy strategy) { +TEST_F(RegisterAllocatorTest, Loop2) { /* * Test the following snippet: * int a = 0; @@ -288,12 +260,10 @@ void RegisterAllocatorTest::Loop2(Strategy strategy) { Instruction::ADD_INT, 1 << 8 | 0, Instruction::RETURN | 1 << 8); - ASSERT_TRUE(Check(data, strategy)); + ASSERT_TRUE(Check(data)); } -TEST_ALL_STRATEGIES(Loop2); - -void RegisterAllocatorTest::Loop3(Strategy strategy) { +TEST_F(RegisterAllocatorTest, Loop3) { /* * Test the following snippet: * int a = 0 @@ -335,7 +305,7 @@ void RegisterAllocatorTest::Loop3(Strategy strategy) { SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); liveness.Analyze(); std::unique_ptr<RegisterAllocator> register_allocator = - RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness, strategy); + RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness); register_allocator->AllocateRegisters(); ASSERT_TRUE(register_allocator->Validate(false)); @@ -353,8 +323,6 @@ void RegisterAllocatorTest::Loop3(Strategy strategy) { ASSERT_EQ(phi_interval->GetRegister(), ret->InputAt(0)->GetLiveInterval()->GetRegister()); } -TEST_ALL_STRATEGIES(Loop3); - TEST_F(RegisterAllocatorTest, FirstRegisterUse) { const std::vector<uint16_t> data = THREE_REGISTERS_CODE_ITEM( Instruction::CONST_4 | 0 | 0, @@ -391,7 +359,7 @@ TEST_F(RegisterAllocatorTest, FirstRegisterUse) { ASSERT_EQ(new_interval->FirstRegisterUse(), last_xor->GetLifetimePosition()); } -void RegisterAllocatorTest::DeadPhi(Strategy strategy) { +TEST_F(RegisterAllocatorTest, DeadPhi) { /* Test for a dead loop phi taking as back-edge input a phi that also has * this loop phi as input. Walking backwards in SsaDeadPhiElimination * does not solve the problem because the loop phi will be visited last. @@ -419,13 +387,11 @@ void RegisterAllocatorTest::DeadPhi(Strategy strategy) { SsaLivenessAnalysis liveness(graph, &codegen, GetScopedAllocator()); liveness.Analyze(); std::unique_ptr<RegisterAllocator> register_allocator = - RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness, strategy); + RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness); register_allocator->AllocateRegisters(); ASSERT_TRUE(register_allocator->Validate(false)); } -TEST_ALL_STRATEGIES(DeadPhi); - /** * Test that the TryAllocateFreeReg method works in the presence of inactive intervals * that share the same register. It should split the interval it is currently @@ -559,7 +525,7 @@ HGraph* RegisterAllocatorTest::BuildIfElseWithPhi(HPhi** phi, return graph; } -void RegisterAllocatorTest::PhiHint(Strategy strategy) { +TEST_F(RegisterAllocatorTest, PhiHint) { HPhi *phi; HInstruction *input1, *input2; @@ -571,7 +537,7 @@ void RegisterAllocatorTest::PhiHint(Strategy strategy) { // Check that the register allocator is deterministic. std::unique_ptr<RegisterAllocator> register_allocator = - RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness, strategy); + RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness); register_allocator->AllocateRegisters(); ASSERT_EQ(input1->GetLiveInterval()->GetRegister(), 0); @@ -589,7 +555,7 @@ void RegisterAllocatorTest::PhiHint(Strategy strategy) { // the same register. phi->GetLocations()->UpdateOut(Location::RegisterLocation(2)); std::unique_ptr<RegisterAllocator> register_allocator = - RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness, strategy); + RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness); register_allocator->AllocateRegisters(); ASSERT_EQ(input1->GetLiveInterval()->GetRegister(), 2); @@ -607,7 +573,7 @@ void RegisterAllocatorTest::PhiHint(Strategy strategy) { // the same register. input1->GetLocations()->UpdateOut(Location::RegisterLocation(2)); std::unique_ptr<RegisterAllocator> register_allocator = - RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness, strategy); + RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness); register_allocator->AllocateRegisters(); ASSERT_EQ(input1->GetLiveInterval()->GetRegister(), 2); @@ -625,7 +591,7 @@ void RegisterAllocatorTest::PhiHint(Strategy strategy) { // the same register. input2->GetLocations()->UpdateOut(Location::RegisterLocation(2)); std::unique_ptr<RegisterAllocator> register_allocator = - RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness, strategy); + RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness); register_allocator->AllocateRegisters(); ASSERT_EQ(input1->GetLiveInterval()->GetRegister(), 2); @@ -634,12 +600,6 @@ void RegisterAllocatorTest::PhiHint(Strategy strategy) { } } -// TODO: Enable this test for graph coloring register allocation when iterative move -// coalescing is merged. -TEST_F(RegisterAllocatorTest, PhiHint_LinearScan) { - PhiHint(Strategy::kRegisterAllocatorLinearScan); -} - HGraph* RegisterAllocatorTest::BuildFieldReturn(HInstruction** field, HInstruction** ret) { HGraph* graph = CreateGraph(); HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); @@ -675,7 +635,7 @@ HGraph* RegisterAllocatorTest::BuildFieldReturn(HInstruction** field, HInstructi return graph; } -void RegisterAllocatorTest::ExpectedInRegisterHint(Strategy strategy) { +TEST_F(RegisterAllocatorTest, ExpectedInRegisterHint) { HInstruction *field, *ret; { @@ -685,7 +645,7 @@ void RegisterAllocatorTest::ExpectedInRegisterHint(Strategy strategy) { liveness.Analyze(); std::unique_ptr<RegisterAllocator> register_allocator = - RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness, strategy); + RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness); register_allocator->AllocateRegisters(); // Check the validity that in normal conditions, the register should be hinted to 0 (EAX). @@ -703,19 +663,13 @@ void RegisterAllocatorTest::ExpectedInRegisterHint(Strategy strategy) { ret->GetLocations()->inputs_[0] = Location::RegisterLocation(2); std::unique_ptr<RegisterAllocator> register_allocator = - RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness, strategy); + RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness); register_allocator->AllocateRegisters(); ASSERT_EQ(field->GetLiveInterval()->GetRegister(), 2); } } -// TODO: Enable this test for graph coloring register allocation when iterative move -// coalescing is merged. -TEST_F(RegisterAllocatorTest, ExpectedInRegisterHint_LinearScan) { - ExpectedInRegisterHint(Strategy::kRegisterAllocatorLinearScan); -} - HGraph* RegisterAllocatorTest::BuildTwoSubs(HInstruction** first_sub, HInstruction** second_sub) { HGraph* graph = CreateGraph(); HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); @@ -743,7 +697,7 @@ HGraph* RegisterAllocatorTest::BuildTwoSubs(HInstruction** first_sub, HInstructi return graph; } -void RegisterAllocatorTest::SameAsFirstInputHint(Strategy strategy) { +TEST_F(RegisterAllocatorTest, SameAsFirstInputHint) { HInstruction *first_sub, *second_sub; { @@ -753,7 +707,7 @@ void RegisterAllocatorTest::SameAsFirstInputHint(Strategy strategy) { liveness.Analyze(); std::unique_ptr<RegisterAllocator> register_allocator = - RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness, strategy); + RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness); register_allocator->AllocateRegisters(); // Check the validity that in normal conditions, the registers are the same. @@ -774,7 +728,7 @@ void RegisterAllocatorTest::SameAsFirstInputHint(Strategy strategy) { ASSERT_EQ(second_sub->GetLocations()->Out().GetPolicy(), Location::kSameAsFirstInput); std::unique_ptr<RegisterAllocator> register_allocator = - RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness, strategy); + RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness); register_allocator->AllocateRegisters(); ASSERT_EQ(first_sub->GetLiveInterval()->GetRegister(), 2); @@ -782,12 +736,6 @@ void RegisterAllocatorTest::SameAsFirstInputHint(Strategy strategy) { } } -// TODO: Enable this test for graph coloring register allocation when iterative move -// coalescing is merged. -TEST_F(RegisterAllocatorTest, SameAsFirstInputHint_LinearScan) { - SameAsFirstInputHint(Strategy::kRegisterAllocatorLinearScan); -} - HGraph* RegisterAllocatorTest::BuildDiv(HInstruction** div) { HGraph* graph = CreateGraph(); HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); @@ -814,7 +762,7 @@ HGraph* RegisterAllocatorTest::BuildDiv(HInstruction** div) { return graph; } -void RegisterAllocatorTest::ExpectedExactInRegisterAndSameOutputHint(Strategy strategy) { +TEST_F(RegisterAllocatorTest, ExpectedExactInRegisterAndSameOutputHint) { HInstruction *div; HGraph* graph = BuildDiv(&div); x86::CodeGeneratorX86 codegen(graph, *compiler_options_); @@ -822,19 +770,13 @@ void RegisterAllocatorTest::ExpectedExactInRegisterAndSameOutputHint(Strategy st liveness.Analyze(); std::unique_ptr<RegisterAllocator> register_allocator = - RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness, strategy); + RegisterAllocator::Create(GetScopedAllocator(), &codegen, liveness); register_allocator->AllocateRegisters(); // div on x86 requires its first input in eax and the output be the same as the first input. ASSERT_EQ(div->GetLiveInterval()->GetRegister(), 0); } -// TODO: Enable this test for graph coloring register allocation when iterative move -// coalescing is merged. -TEST_F(RegisterAllocatorTest, ExpectedExactInRegisterAndSameOutputHint_LinearScan) { - ExpectedExactInRegisterAndSameOutputHint(Strategy::kRegisterAllocatorLinearScan); -} - // Test a bug in the register allocator, where allocating a blocked // register would lead to spilling an inactive interval at the wrong // position. |