diff options
author | 2024-08-15 07:40:38 +0000 | |
---|---|---|
committer | 2024-08-21 09:12:50 +0000 | |
commit | c08fb725b561ead05dc120f2e92ea5228d14eec0 (patch) | |
tree | c306cd68d8f26a33b3c45e2f07db695dccc00e6e /compiler/optimizing/gvn_test.cc | |
parent | 1ea8807afeea6cd48127449cbd10458cc32cf4ce (diff) |
Change `MakeCondition()` to take `IfCondition`...
... instead of the instruction type argument.
And continue with loop construction cleanup in gtests.
Test: m test-art-host-gtest
Change-Id: I8cb83ae0c6d3cdb2a2ee4da0608cfeb69df722eb
Diffstat (limited to 'compiler/optimizing/gvn_test.cc')
-rw-r--r-- | compiler/optimizing/gvn_test.cc | 155 |
1 files changed, 40 insertions, 115 deletions
diff --git a/compiler/optimizing/gvn_test.cc b/compiler/optimizing/gvn_test.cc index 27121fc55a..fba53ee157 100644 --- a/compiler/optimizing/gvn_test.cc +++ b/compiler/optimizing/gvn_test.cc @@ -28,15 +28,9 @@ namespace art HIDDEN { class GVNTest : public OptimizingUnitTest {}; TEST_F(GVNTest, LocalFieldElimination) { - HGraph* graph = CreateGraph(); - HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); - graph->AddBlock(entry); - graph->SetEntryBlock(entry); - HInstruction* parameter = MakeParam(DataType::Type::kReference); + HBasicBlock* block = InitEntryMainExitGraphWithReturnVoid(); - HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph); - graph->AddBlock(block); - entry->AddSuccessor(block); + HInstruction* parameter = MakeParam(DataType::Type::kReference); MakeIFieldGet(block, parameter, DataType::Type::kReference, MemberOffset(42)); HInstruction* to_remove = @@ -47,16 +41,15 @@ TEST_F(GVNTest, LocalFieldElimination) { MakeIFieldSet(block, parameter, parameter, MemberOffset(42)); HInstruction* use_after_kill = MakeIFieldGet(block, parameter, DataType::Type::kReference, MemberOffset(42)); - MakeExit(block); ASSERT_EQ(to_remove->GetBlock(), block); ASSERT_EQ(different_offset->GetBlock(), block); ASSERT_EQ(use_after_kill->GetBlock(), block); - graph->BuildDominatorTree(); - SideEffectsAnalysis side_effects(graph); + graph_->BuildDominatorTree(); + SideEffectsAnalysis side_effects(graph_); side_effects.Run(); - GVNOptimization(graph, side_effects).Run(); + GVNOptimization(graph_, side_effects).Run(); ASSERT_TRUE(to_remove->GetBlock() == nullptr); ASSERT_EQ(different_offset->GetBlock(), block); @@ -64,77 +57,38 @@ TEST_F(GVNTest, LocalFieldElimination) { } TEST_F(GVNTest, GlobalFieldElimination) { - HGraph* graph = CreateGraph(); - HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); - graph->AddBlock(entry); - graph->SetEntryBlock(entry); - HInstruction* parameter = MakeParam(DataType::Type::kReference); + HBasicBlock* join = InitEntryMainExitGraphWithReturnVoid(); + auto [block, then, else_] = CreateDiamondPattern(join); - HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph); - graph->AddBlock(block); - entry->AddSuccessor(block); + HInstruction* parameter = MakeParam(DataType::Type::kReference); HInstruction* field_get = MakeIFieldGet(block, parameter, DataType::Type::kBool, MemberOffset(42)); MakeIf(block, field_get); - HBasicBlock* then = new (GetAllocator()) HBasicBlock(graph); - HBasicBlock* else_ = new (GetAllocator()) HBasicBlock(graph); - HBasicBlock* join = new (GetAllocator()) HBasicBlock(graph); - graph->AddBlock(then); - graph->AddBlock(else_); - graph->AddBlock(join); - - block->AddSuccessor(then); - block->AddSuccessor(else_); - then->AddSuccessor(join); - else_->AddSuccessor(join); - MakeIFieldGet(then, parameter, DataType::Type::kBool, MemberOffset(42)); - MakeGoto(then); - MakeIFieldGet(else_, parameter, DataType::Type::kBool, MemberOffset(42)); - MakeGoto(else_); - MakeIFieldGet(join, parameter, DataType::Type::kBool, MemberOffset(42)); - MakeExit(join); - graph->BuildDominatorTree(); - SideEffectsAnalysis side_effects(graph); + graph_->BuildDominatorTree(); + SideEffectsAnalysis side_effects(graph_); side_effects.Run(); - GVNOptimization(graph, side_effects).Run(); + GVNOptimization(graph_, side_effects).Run(); // Check that all field get instructions have been GVN'ed. ASSERT_TRUE(then->GetFirstInstruction()->IsGoto()); ASSERT_TRUE(else_->GetFirstInstruction()->IsGoto()); - ASSERT_TRUE(join->GetFirstInstruction()->IsExit()); + ASSERT_TRUE(join->GetFirstInstruction()->IsReturnVoid()); } TEST_F(GVNTest, LoopFieldElimination) { - HGraph* graph = CreateGraph(); - HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); - graph->AddBlock(entry); - graph->SetEntryBlock(entry); + HBasicBlock* return_block = InitEntryMainExitGraphWithReturnVoid(); + auto [pre_header, loop_header, loop_body] = CreateWhileLoop(return_block); + loop_header->SwapSuccessors(); // Move the loop exit to the "else" successor. HInstruction* parameter = MakeParam(DataType::Type::kReference); - HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph); - graph->AddBlock(block); - entry->AddSuccessor(block); - MakeIFieldGet(block, parameter, DataType::Type::kBool, MemberOffset(42)); - MakeGoto(block); - - HBasicBlock* loop_header = new (GetAllocator()) HBasicBlock(graph); - HBasicBlock* loop_body = new (GetAllocator()) HBasicBlock(graph); - HBasicBlock* exit = new (GetAllocator()) HBasicBlock(graph); - - graph->AddBlock(loop_header); - graph->AddBlock(loop_body); - graph->AddBlock(exit); - block->AddSuccessor(loop_header); - loop_header->AddSuccessor(loop_body); - loop_header->AddSuccessor(exit); - loop_body->AddSuccessor(loop_header); + MakeIFieldGet(pre_header, parameter, DataType::Type::kBool, MemberOffset(42)); HInstruction* field_get_in_loop_header = MakeIFieldGet(loop_header, parameter, DataType::Type::kBool, MemberOffset(42)); @@ -146,87 +100,58 @@ TEST_F(GVNTest, LoopFieldElimination) { MakeIFieldSet(loop_body, parameter, parameter, DataType::Type::kBool, MemberOffset(42)); HInstruction* field_get_in_loop_body = MakeIFieldGet(loop_body, parameter, DataType::Type::kBool, MemberOffset(42)); - MakeGoto(loop_body); - HInstruction* field_get_in_exit = - MakeIFieldGet(exit, parameter, DataType::Type::kBool, MemberOffset(42)); - MakeExit(exit); + HInstruction* field_get_in_return_block = + MakeIFieldGet(return_block, parameter, DataType::Type::kBool, MemberOffset(42)); ASSERT_EQ(field_get_in_loop_header->GetBlock(), loop_header); ASSERT_EQ(field_get_in_loop_body->GetBlock(), loop_body); - ASSERT_EQ(field_get_in_exit->GetBlock(), exit); + ASSERT_EQ(field_get_in_return_block->GetBlock(), return_block); - graph->BuildDominatorTree(); + graph_->BuildDominatorTree(); { - SideEffectsAnalysis side_effects(graph); + SideEffectsAnalysis side_effects(graph_); side_effects.Run(); - GVNOptimization(graph, side_effects).Run(); + GVNOptimization(graph_, side_effects).Run(); } // Check that all field get instructions are still there. ASSERT_EQ(field_get_in_loop_header->GetBlock(), loop_header); ASSERT_EQ(field_get_in_loop_body->GetBlock(), loop_body); - // The exit block is dominated by the loop header, whose field get + // The `return_block` is dominated by the `loop_header`, whose field get // does not get killed by the loop flags. - ASSERT_TRUE(field_get_in_exit->GetBlock() == nullptr); + ASSERT_TRUE(field_get_in_return_block->GetBlock() == nullptr); // Now remove the field set, and check that all field get instructions have been GVN'ed. loop_body->RemoveInstruction(field_set); { - SideEffectsAnalysis side_effects(graph); + SideEffectsAnalysis side_effects(graph_); side_effects.Run(); - GVNOptimization(graph, side_effects).Run(); + GVNOptimization(graph_, side_effects).Run(); } ASSERT_TRUE(field_get_in_loop_header->GetBlock() == nullptr); ASSERT_TRUE(field_get_in_loop_body->GetBlock() == nullptr); - ASSERT_TRUE(field_get_in_exit->GetBlock() == nullptr); + ASSERT_TRUE(field_get_in_return_block->GetBlock() == nullptr); } // Test that inner loops affect the side effects of the outer loop. TEST_F(GVNTest, LoopSideEffects) { static const SideEffects kCanTriggerGC = SideEffects::CanTriggerGC(); - HGraph* graph = CreateGraph(); - HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); - graph->AddBlock(entry); - graph->SetEntryBlock(entry); - - HBasicBlock* outer_loop_header = new (GetAllocator()) HBasicBlock(graph); - HBasicBlock* outer_loop_body = new (GetAllocator()) HBasicBlock(graph); - HBasicBlock* outer_loop_exit = new (GetAllocator()) HBasicBlock(graph); - HBasicBlock* inner_loop_header = new (GetAllocator()) HBasicBlock(graph); - HBasicBlock* inner_loop_body = new (GetAllocator()) HBasicBlock(graph); - HBasicBlock* inner_loop_exit = new (GetAllocator()) HBasicBlock(graph); - - graph->AddBlock(outer_loop_header); - graph->AddBlock(outer_loop_body); - graph->AddBlock(outer_loop_exit); - graph->AddBlock(inner_loop_header); - graph->AddBlock(inner_loop_body); - graph->AddBlock(inner_loop_exit); - - entry->AddSuccessor(outer_loop_header); - outer_loop_header->AddSuccessor(outer_loop_body); - outer_loop_header->AddSuccessor(outer_loop_exit); - outer_loop_body->AddSuccessor(inner_loop_header); - inner_loop_header->AddSuccessor(inner_loop_body); - inner_loop_header->AddSuccessor(inner_loop_exit); - inner_loop_body->AddSuccessor(inner_loop_header); - inner_loop_exit->AddSuccessor(outer_loop_header); + HBasicBlock* outer_loop_exit = InitEntryMainExitGraphWithReturnVoid(); + auto [outer_preheader, outer_loop_header, inner_loop_exit] = CreateWhileLoop(outer_loop_exit); + outer_loop_header->SwapSuccessors(); // Move the loop exit to the "else" successor. + auto [outer_loop_body, inner_loop_header, inner_loop_body] = CreateWhileLoop(inner_loop_exit); + inner_loop_header->SwapSuccessors(); // Move the loop exit to the "else" successor. HInstruction* parameter = MakeParam(DataType::Type::kBool); - MakeGoto(entry); MakeSuspendCheck(outer_loop_header); MakeIf(outer_loop_header, parameter); - MakeGoto(outer_loop_body); MakeSuspendCheck(inner_loop_header); MakeIf(inner_loop_header, parameter); - MakeGoto(inner_loop_body); - MakeGoto(inner_loop_exit); - MakeExit(outer_loop_exit); - graph->BuildDominatorTree(); + graph_->BuildDominatorTree(); ASSERT_TRUE(inner_loop_header->GetLoopInformation()->IsIn( *outer_loop_header->GetLoopInformation())); @@ -234,12 +159,12 @@ TEST_F(GVNTest, LoopSideEffects) { // Check that the only side effect of loops is to potentially trigger GC. { // Make one block with a side effect. - MakeIFieldSet(entry, parameter, parameter, DataType::Type::kReference, MemberOffset(42)); + MakeIFieldSet(entry_block_, parameter, parameter, DataType::Type::kReference, MemberOffset(42)); - SideEffectsAnalysis side_effects(graph); + SideEffectsAnalysis side_effects(graph_); side_effects.Run(); - ASSERT_TRUE(side_effects.GetBlockEffects(entry).DoesAnyWrite()); + ASSERT_TRUE(side_effects.GetBlockEffects(entry_block_).DoesAnyWrite()); ASSERT_FALSE(side_effects.GetBlockEffects(outer_loop_body).DoesAnyWrite()); ASSERT_FALSE(side_effects.GetLoopEffects(outer_loop_header).DoesAnyWrite()); ASSERT_FALSE(side_effects.GetLoopEffects(inner_loop_header).DoesAnyWrite()); @@ -252,10 +177,10 @@ TEST_F(GVNTest, LoopSideEffects) { MakeIFieldSet( outer_loop_body, parameter, parameter, DataType::Type::kReference, MemberOffset(42)); - SideEffectsAnalysis side_effects(graph); + SideEffectsAnalysis side_effects(graph_); side_effects.Run(); - ASSERT_TRUE(side_effects.GetBlockEffects(entry).DoesAnyWrite()); + ASSERT_TRUE(side_effects.GetBlockEffects(entry_block_).DoesAnyWrite()); ASSERT_TRUE(side_effects.GetBlockEffects(outer_loop_body).DoesAnyWrite()); ASSERT_TRUE(side_effects.GetLoopEffects(outer_loop_header).DoesAnyWrite()); ASSERT_FALSE(side_effects.GetLoopEffects(inner_loop_header).DoesAnyWrite()); @@ -268,10 +193,10 @@ TEST_F(GVNTest, LoopSideEffects) { MakeIFieldSet( inner_loop_body, parameter, parameter, DataType::Type::kReference, MemberOffset(42)); - SideEffectsAnalysis side_effects(graph); + SideEffectsAnalysis side_effects(graph_); side_effects.Run(); - ASSERT_TRUE(side_effects.GetBlockEffects(entry).DoesAnyWrite()); + ASSERT_TRUE(side_effects.GetBlockEffects(entry_block_).DoesAnyWrite()); ASSERT_FALSE(side_effects.GetBlockEffects(outer_loop_body).DoesAnyWrite()); ASSERT_TRUE(side_effects.GetLoopEffects(outer_loop_header).DoesAnyWrite()); ASSERT_TRUE(side_effects.GetLoopEffects(inner_loop_header).DoesAnyWrite()); |