diff options
author | Alex Light <allight@google.com> | 2020-11-14 01:28:22 +0000 |
---|---|---|
committer | Treehugger Robot <treehugger-gerrit@google.com> | 2020-11-14 02:54:26 +0000 |
commit | 2316b3a0779f3721a78681f5c70ed6624ecaebef (patch) | |
tree | 8aa4682729b839a97b2578e6cbe05ee5d35be923 /compiler/optimizing/load_store_elimination_test.cc | |
parent | aeb7f9f8fe718219cfb04e0da5df62683250477d (diff) |
Revert^3 "Partial LSE analysis & store removal"
This reverts commit b6837f0350ff66c13582b0e94178dd5ca283ff0a
This unreverts commit fe270426c8a2a69a8f669339e83b86fbf40e25a1.
This rereverts commit bb6cda60e4418c0ab557ea4090e046bed8206763.
Bug: 67037140
Bug: 173120044
Reason for revert: Git-blame seems to point to the CL as cause of
b/173120044. Revert during investigation.
Change-Id: I46f557ce79c15f07f4e77aacded1926b192754c3
Diffstat (limited to 'compiler/optimizing/load_store_elimination_test.cc')
-rw-r--r-- | compiler/optimizing/load_store_elimination_test.cc | 1185 |
1 files changed, 0 insertions, 1185 deletions
diff --git a/compiler/optimizing/load_store_elimination_test.cc b/compiler/optimizing/load_store_elimination_test.cc index 8196a292d7..f71a4734a6 100644 --- a/compiler/optimizing/load_store_elimination_test.cc +++ b/compiler/optimizing/load_store_elimination_test.cc @@ -27,13 +27,6 @@ namespace art { class LoadStoreEliminationTest : public OptimizingUnitTest { public: - AdjacencyListGraph SetupFromAdjacencyList( - const std::string_view entry_name, - const std::string_view exit_name, - const std::vector<AdjacencyListGraph::Edge>& adj) { - return AdjacencyListGraph(graph_, GetAllocator(), entry_name, exit_name, adj); - } - void PerformLSE() { graph_->BuildDominatorTree(); LoadStoreElimination lse(graph_, /*stats=*/ nullptr); @@ -1449,1182 +1442,4 @@ TEST_F(LoadStoreEliminationTest, ArrayMergeDefault) { EXPECT_TRUE(IsRemoved(alloc_w)); } -// // ENTRY -// obj = new Obj(); -// if (parameter_value) { -// // LEFT -// obj.field = 1; -// call_func(obj); -// foo_r = obj.field -// } else { -// // TO BE ELIMINATED -// obj.field = 2; -// // RIGHT -// // TO BE ELIMINATED -// foo_l = obj.field; -// } -// EXIT -// return PHI(foo_l, foo_r) -TEST_F(LoadStoreEliminationTest, PartialLoadElimination) { - InitGraph(); - AdjacencyListGraph blks(SetupFromAdjacencyList("entry", - "exit_REAL", - { { "entry", "left" }, - { "entry", "right" }, - { "left", "exit" }, - { "right", "exit" }, - { "exit", "exit_REAL" } })); - HBasicBlock* entry = blks.Get("entry"); - HBasicBlock* left = blks.Get("left"); - HBasicBlock* right = blks.Get("right"); - HBasicBlock* exit = blks.Get("exit"); - HInstruction* bool_value = new (GetAllocator()) - HParameterValue(graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kBool); - HInstruction* c1 = graph_->GetIntConstant(1); - HInstruction* c2 = graph_->GetIntConstant(2); - HInstruction* cls = new (GetAllocator()) HLoadClass(graph_->GetCurrentMethod(), - dex::TypeIndex(10), - graph_->GetDexFile(), - ScopedNullHandle<mirror::Class>(), - false, - 0, - false); - HInstruction* new_inst = - new (GetAllocator()) HNewInstance(cls, - 0, - dex::TypeIndex(10), - graph_->GetDexFile(), - false, - QuickEntrypointEnum::kQuickAllocObjectInitialized); - HInstruction* if_inst = new (GetAllocator()) HIf(bool_value); - entry->AddInstruction(bool_value); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(if_inst); - ArenaVector<HInstruction*> current_locals({}, GetAllocator()->Adapter(kArenaAllocInstruction)); - ManuallyBuildEnvFor(cls, ¤t_locals); - new_inst->CopyEnvironmentFrom(cls->GetEnvironment()); - - HInstruction* write_left = new (GetAllocator()) HInstanceFieldSet(new_inst, - c1, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* call_left = new (GetAllocator()) - HInvokeStaticOrDirect(GetAllocator(), - 1, - DataType::Type::kVoid, - 0, - { nullptr, 0 }, - nullptr, - {}, - InvokeType::kStatic, - { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); - HInstruction* read_left = new (GetAllocator()) HInstanceFieldGet(new_inst, - nullptr, - DataType::Type::kInt32, - MemberOffset(16), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* goto_left = new (GetAllocator()) HGoto(); - call_left->AsInvoke()->SetRawInputAt(0, new_inst); - left->AddInstruction(write_left); - left->AddInstruction(call_left); - left->AddInstruction(read_left); - left->AddInstruction(goto_left); - call_left->CopyEnvironmentFrom(cls->GetEnvironment()); - - HInstruction* write_right = new (GetAllocator()) HInstanceFieldSet(new_inst, - c2, - nullptr, - DataType::Type::kInt32, - MemberOffset(16), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* read_right = new (GetAllocator()) HInstanceFieldGet(new_inst, - nullptr, - DataType::Type::kInt32, - MemberOffset(16), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* goto_right = new (GetAllocator()) HGoto(); - right->AddInstruction(write_right); - right->AddInstruction(read_right); - right->AddInstruction(goto_right); - - HInstruction* phi_final = - new (GetAllocator()) HPhi(GetAllocator(), 12, 2, DataType::Type::kInt32); - phi_final->SetRawInputAt(0, read_left); - phi_final->SetRawInputAt(1, read_right); - HInstruction* return_exit = new (GetAllocator()) HReturn(phi_final); - exit->AddPhi(phi_final->AsPhi()); - exit->AddInstruction(return_exit); - - // PerformLSE expects this to be empty. - graph_->ClearDominanceInformation(); - PerformLSE(); - - ASSERT_TRUE(IsRemoved(read_right)); - ASSERT_FALSE(IsRemoved(read_left)); - ASSERT_FALSE(IsRemoved(phi_final)); - ASSERT_TRUE(phi_final->GetInputs()[1] == c2); - ASSERT_TRUE(phi_final->GetInputs()[0] == read_left); - ASSERT_TRUE(IsRemoved(write_right)); -} - -// // ENTRY -// obj = new Obj(); -// if (parameter_value) { -// // LEFT -// obj.field = 1; -// call_func(obj); -// // We don't know what obj.field is now we aren't able to eliminate the read below! -// } else { -// // DO NOT ELIMINATE -// obj.field = 2; -// // RIGHT -// } -// EXIT -// return obj.field -// TODO We eventually want to be able to eliminate the right write along with the final read but -// will need either new blocks or new instructions. -TEST_F(LoadStoreEliminationTest, PartialLoadPreserved) { - InitGraph(); - AdjacencyListGraph blks(SetupFromAdjacencyList("entry", - "exit_REAL", - { { "entry", "left" }, - { "entry", "right" }, - { "left", "exit" }, - { "right", "exit" }, - { "exit", "exit_REAL" } })); - HBasicBlock* entry = blks.Get("entry"); - HBasicBlock* left = blks.Get("left"); - HBasicBlock* right = blks.Get("right"); - HBasicBlock* exit = blks.Get("exit"); - HInstruction* bool_value = new (GetAllocator()) - HParameterValue(graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kBool); - HInstruction* c1 = graph_->GetIntConstant(1); - HInstruction* c2 = graph_->GetIntConstant(2); - HInstruction* cls = new (GetAllocator()) HLoadClass(graph_->GetCurrentMethod(), - dex::TypeIndex(10), - graph_->GetDexFile(), - ScopedNullHandle<mirror::Class>(), - false, - 0, - false); - HInstruction* new_inst = - new (GetAllocator()) HNewInstance(cls, - 0, - dex::TypeIndex(10), - graph_->GetDexFile(), - false, - QuickEntrypointEnum::kQuickAllocObjectInitialized); - HInstruction* if_inst = new (GetAllocator()) HIf(bool_value); - entry->AddInstruction(bool_value); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(if_inst); - ArenaVector<HInstruction*> current_locals({}, GetAllocator()->Adapter(kArenaAllocInstruction)); - ManuallyBuildEnvFor(cls, ¤t_locals); - new_inst->CopyEnvironmentFrom(cls->GetEnvironment()); - - HInstruction* write_left = new (GetAllocator()) HInstanceFieldSet(new_inst, - c1, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* call_left = new (GetAllocator()) - HInvokeStaticOrDirect(GetAllocator(), - 1, - DataType::Type::kVoid, - 0, - { nullptr, 0 }, - nullptr, - {}, - InvokeType::kStatic, - { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); - HInstruction* goto_left = new (GetAllocator()) HGoto(); - call_left->AsInvoke()->SetRawInputAt(0, new_inst); - left->AddInstruction(write_left); - left->AddInstruction(call_left); - left->AddInstruction(goto_left); - call_left->CopyEnvironmentFrom(cls->GetEnvironment()); - - HInstruction* write_right = new (GetAllocator()) HInstanceFieldSet(new_inst, - c2, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* goto_right = new (GetAllocator()) HGoto(); - right->AddInstruction(write_right); - right->AddInstruction(goto_right); - - HInstruction* read_bottom = new (GetAllocator()) HInstanceFieldGet(new_inst, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* return_exit = new (GetAllocator()) HReturn(read_bottom); - exit->AddInstruction(read_bottom); - exit->AddInstruction(return_exit); - // PerformLSE expects this to be empty. - graph_->ClearDominanceInformation(); - PerformLSE(); - - ASSERT_FALSE(IsRemoved(read_bottom)); - ASSERT_FALSE(IsRemoved(write_right)); -} - -// // ENTRY -// obj = new Obj(); -// if (parameter_value) { -// // LEFT -// obj.field = 1; -// call_func(obj); -// // We don't know what obj.field is now we aren't able to eliminate the read below! -// } else { -// // DO NOT ELIMINATE -// if (param2) { -// obj.field = 2; -// } else { -// obj.field = 3; -// } -// // RIGHT -// } -// EXIT -// return obj.field -// TODO We eventually want to be able to eliminate the right write along with the final read but -// will need either new blocks or new instructions. -TEST_F(LoadStoreEliminationTest, PartialLoadPreserved2) { - InitGraph(); - AdjacencyListGraph blks(SetupFromAdjacencyList("entry", - "exit_REAL", - { { "entry", "left" }, - { "entry", "right_start" }, - { "left", "exit" }, - { "right_start", "right_first" }, - { "right_start", "right_second" }, - { "right_first", "right_end" }, - { "right_second", "right_end" }, - { "right_end", "exit" }, - { "exit", "exit_REAL" } })); - HBasicBlock* entry = blks.Get("entry"); - HBasicBlock* left = blks.Get("left"); - HBasicBlock* right_start = blks.Get("right_start"); - HBasicBlock* right_first = blks.Get("right_first"); - HBasicBlock* right_second = blks.Get("right_second"); - HBasicBlock* right_end = blks.Get("right_end"); - HBasicBlock* exit = blks.Get("exit"); - HInstruction* bool_value = new (GetAllocator()) - HParameterValue(graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kBool); - HInstruction* bool_value_2 = new (GetAllocator()) - HParameterValue(graph_->GetDexFile(), dex::TypeIndex(1), 2, DataType::Type::kBool); - HInstruction* c1 = graph_->GetIntConstant(1); - HInstruction* c2 = graph_->GetIntConstant(2); - HInstruction* c3 = graph_->GetIntConstant(3); - HInstruction* cls = new (GetAllocator()) HLoadClass(graph_->GetCurrentMethod(), - dex::TypeIndex(10), - graph_->GetDexFile(), - ScopedNullHandle<mirror::Class>(), - false, - 0, - false); - HInstruction* new_inst = - new (GetAllocator()) HNewInstance(cls, - 0, - dex::TypeIndex(10), - graph_->GetDexFile(), - false, - QuickEntrypointEnum::kQuickAllocObjectInitialized); - HInstruction* if_inst = new (GetAllocator()) HIf(bool_value); - entry->AddInstruction(bool_value); - entry->AddInstruction(bool_value_2); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(if_inst); - ArenaVector<HInstruction*> current_locals({}, GetAllocator()->Adapter(kArenaAllocInstruction)); - ManuallyBuildEnvFor(cls, ¤t_locals); - new_inst->CopyEnvironmentFrom(cls->GetEnvironment()); - - HInstruction* write_left = new (GetAllocator()) HInstanceFieldSet(new_inst, - c1, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* call_left = new (GetAllocator()) - HInvokeStaticOrDirect(GetAllocator(), - 1, - DataType::Type::kVoid, - 0, - { nullptr, 0 }, - nullptr, - {}, - InvokeType::kStatic, - { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); - HInstruction* goto_left = new (GetAllocator()) HGoto(); - call_left->AsInvoke()->SetRawInputAt(0, new_inst); - left->AddInstruction(write_left); - left->AddInstruction(call_left); - left->AddInstruction(goto_left); - call_left->CopyEnvironmentFrom(cls->GetEnvironment()); - - HInstruction* right_if = new (GetAllocator()) HIf(bool_value_2); - right_start->AddInstruction(right_if); - - HInstruction* write_right_first = new (GetAllocator()) HInstanceFieldSet(new_inst, - c2, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* goto_right_first = new (GetAllocator()) HGoto(); - right_first->AddInstruction(write_right_first); - right_first->AddInstruction(goto_right_first); - - HInstruction* write_right_second = new (GetAllocator()) HInstanceFieldSet(new_inst, - c3, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* goto_right_second = new (GetAllocator()) HGoto(); - right_second->AddInstruction(write_right_second); - right_second->AddInstruction(goto_right_second); - - HInstruction* goto_right_end = new (GetAllocator()) HGoto(); - right_end->AddInstruction(goto_right_end); - - HInstruction* read_bottom = new (GetAllocator()) HInstanceFieldGet(new_inst, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* return_exit = new (GetAllocator()) HReturn(read_bottom); - exit->AddInstruction(read_bottom); - exit->AddInstruction(return_exit); - // PerformLSE expects this to be empty. - graph_->ClearDominanceInformation(); - PerformLSE(); - - ASSERT_FALSE(IsRemoved(read_bottom)); - EXPECT_FALSE(IsRemoved(write_right_first)); - EXPECT_FALSE(IsRemoved(write_right_second)); -} - -// // ENTRY -// obj = new Obj(); -// if (parameter_value) { -// // LEFT -// // DO NOT ELIMINATE -// escape(obj); -// obj.field = 1; -// } else { -// // RIGHT -// // ELIMINATE -// obj.field = 2; -// } -// EXIT -// ELIMINATE -// return obj.field -TEST_F(LoadStoreEliminationTest, PartialLoadElimination2) { - InitGraph(); - AdjacencyListGraph blks(SetupFromAdjacencyList("entry", - "exit", - { { "entry", "left" }, - { "entry", "right" }, - { "left", "breturn"}, - { "right", "breturn" }, - { "breturn", "exit" } })); -#define GET_BLOCK(name) HBasicBlock* name = blks.Get(#name) - GET_BLOCK(entry); - GET_BLOCK(exit); - GET_BLOCK(breturn); - GET_BLOCK(left); - GET_BLOCK(right); -#undef GET_BLOCK - HInstruction* bool_value = new (GetAllocator()) - HParameterValue(graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kBool); - HInstruction* c1 = graph_->GetIntConstant(1); - HInstruction* c2 = graph_->GetIntConstant(2); - HInstruction* cls = new (GetAllocator()) HLoadClass(graph_->GetCurrentMethod(), - dex::TypeIndex(10), - graph_->GetDexFile(), - ScopedNullHandle<mirror::Class>(), - false, - 0, - false); - HInstruction* new_inst = - new (GetAllocator()) HNewInstance(cls, - 0, - dex::TypeIndex(10), - graph_->GetDexFile(), - false, - QuickEntrypointEnum::kQuickAllocObjectInitialized); - HInstruction* if_inst = new (GetAllocator()) HIf(bool_value); - entry->AddInstruction(bool_value); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(if_inst); - ArenaVector<HInstruction*> current_locals({}, GetAllocator()->Adapter(kArenaAllocInstruction)); - ManuallyBuildEnvFor(cls, ¤t_locals); - new_inst->CopyEnvironmentFrom(cls->GetEnvironment()); - - HInstruction* call_left = new (GetAllocator()) - HInvokeStaticOrDirect(GetAllocator(), - 1, - DataType::Type::kVoid, - 0, - { nullptr, 0 }, - nullptr, - {}, - InvokeType::kStatic, - { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); - HInstruction* write_left = new (GetAllocator()) HInstanceFieldSet(new_inst, - c1, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* goto_left = new (GetAllocator()) HGoto(); - call_left->AsInvoke()->SetRawInputAt(0, new_inst); - left->AddInstruction(call_left); - left->AddInstruction(write_left); - left->AddInstruction(goto_left); - call_left->CopyEnvironmentFrom(cls->GetEnvironment()); - - HInstruction* write_right = new (GetAllocator()) HInstanceFieldSet(new_inst, - c2, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* goto_right = new (GetAllocator()) HGoto(); - right->AddInstruction(write_right); - right->AddInstruction(goto_right); - - HInstruction* read_bottom = new (GetAllocator()) HInstanceFieldGet(new_inst, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* return_exit = new (GetAllocator()) HReturn(read_bottom); - breturn->AddInstruction(read_bottom); - breturn->AddInstruction(return_exit); - - HInstruction* exit_instruction = new (GetAllocator()) HExit(); - exit->AddInstruction(exit_instruction); - // PerformLSE expects this to be empty. - graph_->ClearDominanceInformation(); - PerformLSE(); - - ASSERT_TRUE(IsRemoved(read_bottom)); - ASSERT_TRUE(IsRemoved(write_right)); - ASSERT_FALSE(IsRemoved(write_left)); - ASSERT_FALSE(IsRemoved(call_left)); -} - -// // ENTRY -// obj = new Obj(); -// if (parameter_value) { -// // LEFT -// // DO NOT ELIMINATE -// obj.field = 1; -// escape(obj); -// return obj.field; -// } else { -// // RIGHT -// // ELIMINATE -// obj.field = 2; -// return obj.field; -// } -// EXIT -TEST_F(LoadStoreEliminationTest, PartialLoadElimination3) { - InitGraph(); - AdjacencyListGraph blks(SetupFromAdjacencyList( - "entry", - "exit", - { { "entry", "left" }, { "entry", "right" }, { "left", "exit" }, { "right", "exit" } })); -#define GET_BLOCK(name) HBasicBlock* name = blks.Get(#name) - GET_BLOCK(entry); - GET_BLOCK(exit); - GET_BLOCK(left); - GET_BLOCK(right); -#undef GET_BLOCK - HInstruction* bool_value = new (GetAllocator()) - HParameterValue(graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kBool); - HInstruction* c1 = graph_->GetIntConstant(1); - HInstruction* c2 = graph_->GetIntConstant(2); - HInstruction* cls = new (GetAllocator()) HLoadClass(graph_->GetCurrentMethod(), - dex::TypeIndex(10), - graph_->GetDexFile(), - ScopedNullHandle<mirror::Class>(), - false, - 0, - false); - HInstruction* new_inst = - new (GetAllocator()) HNewInstance(cls, - 0, - dex::TypeIndex(10), - graph_->GetDexFile(), - false, - QuickEntrypointEnum::kQuickAllocObjectInitialized); - HInstruction* if_inst = new (GetAllocator()) HIf(bool_value); - entry->AddInstruction(bool_value); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(if_inst); - ArenaVector<HInstruction*> current_locals({}, GetAllocator()->Adapter(kArenaAllocInstruction)); - ManuallyBuildEnvFor(cls, ¤t_locals); - new_inst->CopyEnvironmentFrom(cls->GetEnvironment()); - - HInstruction* write_left = new (GetAllocator()) HInstanceFieldSet(new_inst, - c1, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* call_left = new (GetAllocator()) - HInvokeStaticOrDirect(GetAllocator(), - 1, - DataType::Type::kVoid, - 0, - { nullptr, 0 }, - nullptr, - {}, - InvokeType::kStatic, - { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); - HInstruction* read_left = new (GetAllocator()) HInstanceFieldGet(new_inst, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* return_left = new (GetAllocator()) HReturn(read_left); - call_left->AsInvoke()->SetRawInputAt(0, new_inst); - left->AddInstruction(write_left); - left->AddInstruction(call_left); - left->AddInstruction(read_left); - left->AddInstruction(return_left); - call_left->CopyEnvironmentFrom(cls->GetEnvironment()); - - HInstruction* write_right = new (GetAllocator()) HInstanceFieldSet(new_inst, - c2, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* read_right = new (GetAllocator()) HInstanceFieldGet(new_inst, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* return_right = new (GetAllocator()) HReturn(read_right); - right->AddInstruction(write_right); - right->AddInstruction(read_right); - right->AddInstruction(return_right); - - HInstruction* exit_instruction = new (GetAllocator()) HExit(); - exit->AddInstruction(exit_instruction); - // PerformLSE expects this to be empty. - graph_->ClearDominanceInformation(); - PerformLSE(); - - EXPECT_TRUE(IsRemoved(read_right)); - EXPECT_TRUE(IsRemoved(write_right)); - EXPECT_FALSE(IsRemoved(write_left)); - EXPECT_FALSE(IsRemoved(call_left)); - EXPECT_FALSE(IsRemoved(read_left)); -} - -// // ENTRY -// obj = new Obj(); -// if (parameter_value) { -// // LEFT -// // DO NOT ELIMINATE -// obj.field = 1; -// while (true) { -// bool esc = escape(obj); -// // DO NOT ELIMINATE -// obj.field = 3; -// if (esc) break; -// } -// // ELIMINATE. -// return obj.field; -// } else { -// // RIGHT -// // ELIMINATE -// obj.field = 2; -// return obj.field; -// } -// EXIT -TEST_F(LoadStoreEliminationTest, PartialLoadElimination4) { - InitGraph(); - AdjacencyListGraph blks(SetupFromAdjacencyList("entry", - "exit", - { { "entry", "entry_post" }, - { "entry_post", "right" }, - { "right", "exit" }, - { "entry_post", "left_pre" }, - { "left_pre", "left_loop" }, - { "left_loop", "left_loop" }, - { "left_loop", "left_finish" }, - { "left_finish", "exit" } })); -#define GET_BLOCK(name) HBasicBlock* name = blks.Get(#name) - GET_BLOCK(entry); - GET_BLOCK(entry_post); - GET_BLOCK(exit); - GET_BLOCK(left_pre); - GET_BLOCK(left_loop); - GET_BLOCK(left_finish); - GET_BLOCK(right); -#undef GET_BLOCK - // Left-loops first successor is the break. - if (left_loop->GetSuccessors()[0] != left_finish) { - left_loop->SwapSuccessors(); - } - HInstruction* bool_value = new (GetAllocator()) - HParameterValue(graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kBool); - HInstruction* c1 = graph_->GetIntConstant(1); - HInstruction* c2 = graph_->GetIntConstant(2); - HInstruction* c3 = graph_->GetIntConstant(3); - HInstruction* cls = new (GetAllocator()) HLoadClass(graph_->GetCurrentMethod(), - dex::TypeIndex(10), - graph_->GetDexFile(), - ScopedNullHandle<mirror::Class>(), - false, - 0, - false); - HInstruction* new_inst = - new (GetAllocator()) HNewInstance(cls, - 0, - dex::TypeIndex(10), - graph_->GetDexFile(), - false, - QuickEntrypointEnum::kQuickAllocObjectInitialized); - HInstruction* goto_entry = new (GetAllocator()) HGoto(); - entry->AddInstruction(bool_value); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(goto_entry); - ArenaVector<HInstruction*> current_locals({}, GetAllocator()->Adapter(kArenaAllocInstruction)); - ManuallyBuildEnvFor(cls, ¤t_locals); - new_inst->CopyEnvironmentFrom(cls->GetEnvironment()); - - HInstruction* if_inst = new (GetAllocator()) HIf(bool_value); - entry_post->AddInstruction(if_inst); - - HInstruction* write_left_pre = new (GetAllocator()) HInstanceFieldSet(new_inst, - c1, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* goto_left_pre = new (GetAllocator()) HGoto(); - left_pre->AddInstruction(write_left_pre); - left_pre->AddInstruction(goto_left_pre); - - HInstruction* suspend_left_loop = new (GetAllocator()) HSuspendCheck(); - HInstruction* call_left_loop = new (GetAllocator()) - HInvokeStaticOrDirect(GetAllocator(), - 1, - DataType::Type::kBool, - 0, - { nullptr, 0 }, - nullptr, - {}, - InvokeType::kStatic, - { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); - HInstruction* write_left_loop = new (GetAllocator()) HInstanceFieldSet(new_inst, - c3, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* if_left_loop = new (GetAllocator()) HIf(call_left_loop); - call_left_loop->AsInvoke()->SetRawInputAt(0, new_inst); - left_loop->AddInstruction(suspend_left_loop); - left_loop->AddInstruction(call_left_loop); - left_loop->AddInstruction(write_left_loop); - left_loop->AddInstruction(if_left_loop); - suspend_left_loop->CopyEnvironmentFrom(cls->GetEnvironment()); - call_left_loop->CopyEnvironmentFrom(cls->GetEnvironment()); - - HInstruction* read_left_end = new (GetAllocator()) HInstanceFieldGet(new_inst, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* return_left_end = new (GetAllocator()) HReturn(read_left_end); - left_finish->AddInstruction(read_left_end); - left_finish->AddInstruction(return_left_end); - - HInstruction* write_right = new (GetAllocator()) HInstanceFieldSet(new_inst, - c2, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* read_right = new (GetAllocator()) HInstanceFieldGet(new_inst, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* return_right = new (GetAllocator()) HReturn(read_right); - right->AddInstruction(write_right); - right->AddInstruction(read_right); - right->AddInstruction(return_right); - - HInstruction* exit_instruction = new (GetAllocator()) HExit(); - exit->AddInstruction(exit_instruction); - // PerformLSE expects this to be empty. - graph_->ClearDominanceInformation(); - PerformLSE(); - - EXPECT_FALSE(IsRemoved(write_left_pre)); - EXPECT_TRUE(IsRemoved(read_right)); - EXPECT_TRUE(IsRemoved(write_right)); - EXPECT_FALSE(IsRemoved(write_left_loop)); - EXPECT_FALSE(IsRemoved(call_left_loop)); - EXPECT_TRUE(IsRemoved(read_left_end)); -} - -// // ENTRY -// obj = new Obj(); -// if (parameter_value) { -// // LEFT -// // DO NOT ELIMINATE -// obj.field = 1; -// while (true) { -// bool esc = escape(obj); -// if (esc) break; -// // DO NOT ELIMINATE -// obj.field = 3; -// } -// } else { -// // RIGHT -// // DO NOT ELIMINATE -// obj.field = 2; -// } -// // DO NOT ELIMINATE -// return obj.field; -// EXIT -TEST_F(LoadStoreEliminationTest, PartialLoadPreserved3) { - InitGraph(); - AdjacencyListGraph blks(SetupFromAdjacencyList("entry", - "exit", - { { "entry", "entry_post" }, - { "entry_post", "right" }, - { "right", "return_block" }, - { "entry_post", "left_pre" }, - { "left_pre", "left_loop" }, - { "left_loop", "left_loop_post" }, - { "left_loop_post", "left_loop" }, - { "left_loop", "return_block" }, - { "return_block", "exit" } })); -#define GET_BLOCK(name) HBasicBlock* name = blks.Get(#name) - GET_BLOCK(entry); - GET_BLOCK(entry_post); - GET_BLOCK(exit); - GET_BLOCK(return_block); - GET_BLOCK(left_pre); - GET_BLOCK(left_loop); - GET_BLOCK(left_loop_post); - GET_BLOCK(right); -#undef GET_BLOCK - // Left-loops first successor is the break. - if (left_loop->GetSuccessors()[0] != return_block) { - left_loop->SwapSuccessors(); - } - HInstruction* bool_value = new (GetAllocator()) - HParameterValue(graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kBool); - HInstruction* c1 = graph_->GetIntConstant(1); - HInstruction* c2 = graph_->GetIntConstant(2); - HInstruction* c3 = graph_->GetIntConstant(3); - HInstruction* cls = new (GetAllocator()) HLoadClass(graph_->GetCurrentMethod(), - dex::TypeIndex(10), - graph_->GetDexFile(), - ScopedNullHandle<mirror::Class>(), - false, - 0, - false); - HInstruction* new_inst = - new (GetAllocator()) HNewInstance(cls, - 0, - dex::TypeIndex(10), - graph_->GetDexFile(), - false, - QuickEntrypointEnum::kQuickAllocObjectInitialized); - HInstruction* goto_entry = new (GetAllocator()) HGoto(); - entry->AddInstruction(bool_value); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(goto_entry); - ArenaVector<HInstruction*> current_locals({}, GetAllocator()->Adapter(kArenaAllocInstruction)); - ManuallyBuildEnvFor(cls, ¤t_locals); - new_inst->CopyEnvironmentFrom(cls->GetEnvironment()); - - HInstruction* if_inst = new (GetAllocator()) HIf(bool_value); - entry_post->AddInstruction(if_inst); - - HInstruction* write_left_pre = new (GetAllocator()) HInstanceFieldSet(new_inst, - c1, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* goto_left_pre = new (GetAllocator()) HGoto(); - left_pre->AddInstruction(write_left_pre); - left_pre->AddInstruction(goto_left_pre); - - HInstruction* suspend_left_loop = new (GetAllocator()) HSuspendCheck(); - HInstruction* call_left_loop = new (GetAllocator()) - HInvokeStaticOrDirect(GetAllocator(), - 1, - DataType::Type::kBool, - 0, - { nullptr, 0 }, - nullptr, - {}, - InvokeType::kStatic, - { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); - HInstruction* if_left_loop = new (GetAllocator()) HIf(call_left_loop); - call_left_loop->AsInvoke()->SetRawInputAt(0, new_inst); - left_loop->AddInstruction(suspend_left_loop); - left_loop->AddInstruction(call_left_loop); - left_loop->AddInstruction(if_left_loop); - suspend_left_loop->CopyEnvironmentFrom(cls->GetEnvironment()); - call_left_loop->CopyEnvironmentFrom(cls->GetEnvironment()); - - HInstruction* write_left_loop = new (GetAllocator()) HInstanceFieldSet(new_inst, - c3, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* goto_left_loop = new (GetAllocator()) HGoto(); - left_loop_post->AddInstruction(write_left_loop); - left_loop_post->AddInstruction(goto_left_loop); - - HInstruction* write_right = new (GetAllocator()) HInstanceFieldSet(new_inst, - c2, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* goto_right = new (GetAllocator()) HGoto(); - right->AddInstruction(write_right); - right->AddInstruction(goto_right); - - HInstruction* read_return = new (GetAllocator()) HInstanceFieldGet(new_inst, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* return_final = new (GetAllocator()) HReturn(read_return); - return_block->AddInstruction(read_return); - return_block->AddInstruction(return_final); - - HInstruction* exit_instruction = new (GetAllocator()) HExit(); - exit->AddInstruction(exit_instruction); - // PerformLSE expects this to be empty. - graph_->ClearDominanceInformation(); - PerformLSE(); - - EXPECT_FALSE(IsRemoved(write_left_pre)); - EXPECT_FALSE(IsRemoved(read_return)); - EXPECT_FALSE(IsRemoved(write_right)); - EXPECT_FALSE(IsRemoved(write_left_loop)); - EXPECT_FALSE(IsRemoved(call_left_loop)); -} - -// // ENTRY -// obj = new Obj(); -// if (parameter_value) { -// // LEFT -// // ELIMINATE (not visible since always overridden by obj.field = 3) -// obj.field = 1; -// while (true) { -// bool stop = should_stop(); -// // DO NOT ELIMINATE (visible by read at end) -// obj.field = 3; -// if (stop) break; -// } -// } else { -// // RIGHT -// // DO NOT ELIMINATE -// obj.field = 2; -// escape(obj); -// } -// // DO NOT ELIMINATE -// return obj.field; -// EXIT -TEST_F(LoadStoreEliminationTest, PartialLoadPreserved4) { - InitGraph(); - AdjacencyListGraph blks(SetupFromAdjacencyList("entry", - "exit", - { { "entry", "entry_post" }, - { "entry_post", "right" }, - { "right", "return_block" }, - { "entry_post", "left_pre" }, - { "left_pre", "left_loop" }, - { "left_loop", "left_loop" }, - { "left_loop", "return_block" }, - { "return_block", "exit" } })); -#define GET_BLOCK(name) HBasicBlock* name = blks.Get(#name) - GET_BLOCK(entry); - GET_BLOCK(entry_post); - GET_BLOCK(exit); - GET_BLOCK(return_block); - GET_BLOCK(left_pre); - GET_BLOCK(left_loop); - GET_BLOCK(right); -#undef GET_BLOCK - // Left-loops first successor is the break. - if (left_loop->GetSuccessors()[0] != return_block) { - left_loop->SwapSuccessors(); - } - HInstruction* bool_value = new (GetAllocator()) - HParameterValue(graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kBool); - HInstruction* c1 = graph_->GetIntConstant(1); - HInstruction* c2 = graph_->GetIntConstant(2); - HInstruction* c3 = graph_->GetIntConstant(3); - HInstruction* cls = new (GetAllocator()) HLoadClass(graph_->GetCurrentMethod(), - dex::TypeIndex(10), - graph_->GetDexFile(), - ScopedNullHandle<mirror::Class>(), - false, - 0, - false); - HInstruction* new_inst = - new (GetAllocator()) HNewInstance(cls, - 0, - dex::TypeIndex(10), - graph_->GetDexFile(), - false, - QuickEntrypointEnum::kQuickAllocObjectInitialized); - HInstruction* goto_entry = new (GetAllocator()) HGoto(); - entry->AddInstruction(bool_value); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(goto_entry); - ArenaVector<HInstruction*> current_locals({}, GetAllocator()->Adapter(kArenaAllocInstruction)); - ManuallyBuildEnvFor(cls, ¤t_locals); - new_inst->CopyEnvironmentFrom(cls->GetEnvironment()); - - HInstruction* if_inst = new (GetAllocator()) HIf(bool_value); - entry_post->AddInstruction(if_inst); - - HInstruction* write_left_pre = new (GetAllocator()) HInstanceFieldSet(new_inst, - c1, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* goto_left_pre = new (GetAllocator()) HGoto(); - left_pre->AddInstruction(write_left_pre); - left_pre->AddInstruction(goto_left_pre); - - HInstruction* suspend_left_loop = new (GetAllocator()) HSuspendCheck(); - HInstruction* call_left_loop = new (GetAllocator()) - HInvokeStaticOrDirect(GetAllocator(), - 0, - DataType::Type::kBool, - 0, - { nullptr, 0 }, - nullptr, - {}, - InvokeType::kStatic, - { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); - HInstruction* write_left_loop = new (GetAllocator()) HInstanceFieldSet(new_inst, - c3, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* if_left_loop = new (GetAllocator()) HIf(call_left_loop); - left_loop->AddInstruction(suspend_left_loop); - left_loop->AddInstruction(call_left_loop); - left_loop->AddInstruction(write_left_loop); - left_loop->AddInstruction(if_left_loop); - suspend_left_loop->CopyEnvironmentFrom(cls->GetEnvironment()); - call_left_loop->CopyEnvironmentFrom(cls->GetEnvironment()); - - HInstruction* write_right = new (GetAllocator()) HInstanceFieldSet(new_inst, - c2, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* call_right = new (GetAllocator()) - HInvokeStaticOrDirect(GetAllocator(), - 1, - DataType::Type::kBool, - 0, - { nullptr, 0 }, - nullptr, - {}, - InvokeType::kStatic, - { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); - HInstruction* goto_right = new (GetAllocator()) HGoto(); - call_right->AsInvoke()->SetRawInputAt(0, new_inst); - right->AddInstruction(write_right); - right->AddInstruction(call_right); - right->AddInstruction(goto_right); - call_right->CopyEnvironmentFrom(cls->GetEnvironment()); - - HInstruction* read_return = new (GetAllocator()) HInstanceFieldGet(new_inst, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* return_final = new (GetAllocator()) HReturn(read_return); - return_block->AddInstruction(read_return); - return_block->AddInstruction(return_final); - - HInstruction* exit_instruction = new (GetAllocator()) HExit(); - exit->AddInstruction(exit_instruction); - // PerformLSE expects this to be empty. - graph_->ClearDominanceInformation(); - PerformLSE(); - - EXPECT_FALSE(IsRemoved(read_return)); - EXPECT_FALSE(IsRemoved(write_right)); - EXPECT_FALSE(IsRemoved(write_left_loop)); - EXPECT_FALSE(IsRemoved(call_left_loop)); - EXPECT_TRUE(IsRemoved(write_left_pre)); - EXPECT_FALSE(IsRemoved(call_right)); -} } // namespace art |