From 5e399b8715f3cb153ddb619a7c47515583799db3 Mon Sep 17 00:00:00 2001 From: Artem Serov Date: Thu, 21 Dec 2017 14:28:35 +0000 Subject: ART: Rename cloner_test. Rename cloner_test to superblock_cloner_test to be consistent with the test naming conventioni as a new SuperblockCloner file is arriving. Test: superblock_cloner_test.cc. Change-Id: I066a20b4599de6c59b83676bb11295135a512791 --- compiler/optimizing/cloner_test.cc | 185 -------------------------- compiler/optimizing/superblock_cloner_test.cc | 185 ++++++++++++++++++++++++++ 2 files changed, 185 insertions(+), 185 deletions(-) delete mode 100644 compiler/optimizing/cloner_test.cc create mode 100644 compiler/optimizing/superblock_cloner_test.cc (limited to 'compiler/optimizing') diff --git a/compiler/optimizing/cloner_test.cc b/compiler/optimizing/cloner_test.cc deleted file mode 100644 index d34dd81767..0000000000 --- a/compiler/optimizing/cloner_test.cc +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "graph_checker.h" -#include "nodes.h" -#include "optimizing_unit_test.h" - -#include "gtest/gtest.h" - -namespace art { - -// This class provides methods and helpers for testing various cloning and copying routines: -// individual instruction cloning and cloning of the more coarse-grain structures. -class ClonerTest : public OptimizingUnitTest { - public: - ClonerTest() - : graph_(CreateGraph()), entry_block_(nullptr), exit_block_(nullptr), parameter_(nullptr) {} - - void CreateBasicLoopControlFlow(/* out */ HBasicBlock** header_p, - /* out */ HBasicBlock** body_p) { - entry_block_ = new (GetAllocator()) HBasicBlock(graph_); - graph_->AddBlock(entry_block_); - graph_->SetEntryBlock(entry_block_); - - HBasicBlock* loop_preheader = new (GetAllocator()) HBasicBlock(graph_); - HBasicBlock* loop_header = new (GetAllocator()) HBasicBlock(graph_); - HBasicBlock* loop_body = new (GetAllocator()) HBasicBlock(graph_); - HBasicBlock* loop_exit = new (GetAllocator()) HBasicBlock(graph_); - - graph_->AddBlock(loop_preheader); - graph_->AddBlock(loop_header); - graph_->AddBlock(loop_body); - graph_->AddBlock(loop_exit); - - exit_block_ = new (GetAllocator()) HBasicBlock(graph_); - graph_->AddBlock(exit_block_); - graph_->SetExitBlock(exit_block_); - - entry_block_->AddSuccessor(loop_preheader); - loop_preheader->AddSuccessor(loop_header); - // Loop exit first to have a proper exit condition/target for HIf. - loop_header->AddSuccessor(loop_exit); - loop_header->AddSuccessor(loop_body); - loop_body->AddSuccessor(loop_header); - loop_exit->AddSuccessor(exit_block_); - - *header_p = loop_header; - *body_p = loop_body; - - parameter_ = new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(0), - 0, - DataType::Type::kInt32); - entry_block_->AddInstruction(parameter_); - loop_exit->AddInstruction(new (GetAllocator()) HReturnVoid()); - exit_block_->AddInstruction(new (GetAllocator()) HExit()); - } - - void CreateBasicLoopDataFlow(HBasicBlock* loop_header, HBasicBlock* loop_body) { - uint32_t dex_pc = 0; - - // Entry block. - HIntConstant* const_0 = graph_->GetIntConstant(0); - HIntConstant* const_1 = graph_->GetIntConstant(1); - HIntConstant* const_128 = graph_->GetIntConstant(128); - - // Header block. - HPhi* phi = new (GetAllocator()) HPhi(GetAllocator(), 0, 0, DataType::Type::kInt32); - HInstruction* suspend_check = new (GetAllocator()) HSuspendCheck(); - - loop_header->AddPhi(phi); - loop_header->AddInstruction(suspend_check); - loop_header->AddInstruction(new (GetAllocator()) HGreaterThanOrEqual(phi, const_128)); - loop_header->AddInstruction(new (GetAllocator()) HIf(parameter_)); - - // Loop body block. - HInstruction* null_check = new (GetAllocator()) HNullCheck(parameter_, dex_pc); - HInstruction* array_length = new (GetAllocator()) HArrayLength(null_check, dex_pc); - HInstruction* bounds_check = new (GetAllocator()) HBoundsCheck(phi, array_length, dex_pc); - HInstruction* array_get = - new (GetAllocator()) HArrayGet(null_check, bounds_check, DataType::Type::kInt32, dex_pc); - HInstruction* add = new (GetAllocator()) HAdd(DataType::Type::kInt32, array_get, const_1); - HInstruction* array_set = - new (GetAllocator()) HArraySet(null_check, bounds_check, add, DataType::Type::kInt32, dex_pc); - HInstruction* induction_inc = new (GetAllocator()) HAdd(DataType::Type::kInt32, phi, const_1); - - loop_body->AddInstruction(null_check); - loop_body->AddInstruction(array_length); - loop_body->AddInstruction(bounds_check); - loop_body->AddInstruction(array_get); - loop_body->AddInstruction(add); - loop_body->AddInstruction(array_set); - loop_body->AddInstruction(induction_inc); - loop_body->AddInstruction(new (GetAllocator()) HGoto()); - - phi->AddInput(const_0); - phi->AddInput(induction_inc); - - graph_->SetHasBoundsChecks(true); - - // Adjust HEnvironment for each instruction which require that. - ArenaVector current_locals({phi, const_128, parameter_}, - GetAllocator()->Adapter(kArenaAllocInstruction)); - - HEnvironment* env = ManuallyBuildEnvFor(suspend_check, ¤t_locals); - null_check->CopyEnvironmentFrom(env); - bounds_check->CopyEnvironmentFrom(env); - } - - HEnvironment* ManuallyBuildEnvFor(HInstruction* instruction, - ArenaVector* current_locals) { - HEnvironment* environment = new (GetAllocator()) HEnvironment( - (GetAllocator()), - current_locals->size(), - graph_->GetArtMethod(), - instruction->GetDexPc(), - instruction); - - environment->CopyFrom(ArrayRef(*current_locals)); - instruction->SetRawEnvironment(environment); - return environment; - } - - bool CheckGraph() { - GraphChecker checker(graph_); - checker.Run(); - if (!checker.IsValid()) { - for (const std::string& error : checker.GetErrors()) { - std::cout << error << std::endl; - } - return false; - } - return true; - } - - HGraph* graph_; - - HBasicBlock* entry_block_; - HBasicBlock* exit_block_; - - HInstruction* parameter_; -}; - -TEST_F(ClonerTest, IndividualInstrCloner) { - HBasicBlock* header = nullptr; - HBasicBlock* loop_body = nullptr; - - CreateBasicLoopControlFlow(&header, &loop_body); - CreateBasicLoopDataFlow(header, loop_body); - graph_->BuildDominatorTree(); - ASSERT_TRUE(CheckGraph()); - - HSuspendCheck* old_suspend_check = header->GetLoopInformation()->GetSuspendCheck(); - CloneAndReplaceInstructionVisitor visitor(graph_); - // Do instruction cloning and replacement twice with different visiting order. - - visitor.VisitInsertionOrder(); - size_t instr_replaced_by_clones_count = visitor.GetInstrReplacedByClonesCount(); - EXPECT_EQ(instr_replaced_by_clones_count, 12u); - EXPECT_TRUE(CheckGraph()); - - visitor.VisitReversePostOrder(); - instr_replaced_by_clones_count = visitor.GetInstrReplacedByClonesCount(); - EXPECT_EQ(instr_replaced_by_clones_count, 24u); - EXPECT_TRUE(CheckGraph()); - - HSuspendCheck* new_suspend_check = header->GetLoopInformation()->GetSuspendCheck(); - EXPECT_NE(new_suspend_check, old_suspend_check); - EXPECT_NE(new_suspend_check, nullptr); -} - -} // namespace art diff --git a/compiler/optimizing/superblock_cloner_test.cc b/compiler/optimizing/superblock_cloner_test.cc new file mode 100644 index 0000000000..fd77eb81fc --- /dev/null +++ b/compiler/optimizing/superblock_cloner_test.cc @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "graph_checker.h" +#include "nodes.h" +#include "optimizing_unit_test.h" + +#include "gtest/gtest.h" + +namespace art { + +// This class provides methods and helpers for testing various cloning and copying routines: +// individual instruction cloning and cloning of the more coarse-grain structures. +class SuperblockClonerTest : public OptimizingUnitTest { + public: + SuperblockClonerTest() + : graph_(CreateGraph()), entry_block_(nullptr), exit_block_(nullptr), parameter_(nullptr) {} + + void CreateBasicLoopControlFlow(/* out */ HBasicBlock** header_p, + /* out */ HBasicBlock** body_p) { + entry_block_ = new (GetAllocator()) HBasicBlock(graph_); + graph_->AddBlock(entry_block_); + graph_->SetEntryBlock(entry_block_); + + HBasicBlock* loop_preheader = new (GetAllocator()) HBasicBlock(graph_); + HBasicBlock* loop_header = new (GetAllocator()) HBasicBlock(graph_); + HBasicBlock* loop_body = new (GetAllocator()) HBasicBlock(graph_); + HBasicBlock* loop_exit = new (GetAllocator()) HBasicBlock(graph_); + + graph_->AddBlock(loop_preheader); + graph_->AddBlock(loop_header); + graph_->AddBlock(loop_body); + graph_->AddBlock(loop_exit); + + exit_block_ = new (GetAllocator()) HBasicBlock(graph_); + graph_->AddBlock(exit_block_); + graph_->SetExitBlock(exit_block_); + + entry_block_->AddSuccessor(loop_preheader); + loop_preheader->AddSuccessor(loop_header); + // Loop exit first to have a proper exit condition/target for HIf. + loop_header->AddSuccessor(loop_exit); + loop_header->AddSuccessor(loop_body); + loop_body->AddSuccessor(loop_header); + loop_exit->AddSuccessor(exit_block_); + + *header_p = loop_header; + *body_p = loop_body; + + parameter_ = new (GetAllocator()) HParameterValue(graph_->GetDexFile(), + dex::TypeIndex(0), + 0, + DataType::Type::kInt32); + entry_block_->AddInstruction(parameter_); + loop_exit->AddInstruction(new (GetAllocator()) HReturnVoid()); + exit_block_->AddInstruction(new (GetAllocator()) HExit()); + } + + void CreateBasicLoopDataFlow(HBasicBlock* loop_header, HBasicBlock* loop_body) { + uint32_t dex_pc = 0; + + // Entry block. + HIntConstant* const_0 = graph_->GetIntConstant(0); + HIntConstant* const_1 = graph_->GetIntConstant(1); + HIntConstant* const_128 = graph_->GetIntConstant(128); + + // Header block. + HPhi* phi = new (GetAllocator()) HPhi(GetAllocator(), 0, 0, DataType::Type::kInt32); + HInstruction* suspend_check = new (GetAllocator()) HSuspendCheck(); + + loop_header->AddPhi(phi); + loop_header->AddInstruction(suspend_check); + loop_header->AddInstruction(new (GetAllocator()) HGreaterThanOrEqual(phi, const_128)); + loop_header->AddInstruction(new (GetAllocator()) HIf(parameter_)); + + // Loop body block. + HInstruction* null_check = new (GetAllocator()) HNullCheck(parameter_, dex_pc); + HInstruction* array_length = new (GetAllocator()) HArrayLength(null_check, dex_pc); + HInstruction* bounds_check = new (GetAllocator()) HBoundsCheck(phi, array_length, dex_pc); + HInstruction* array_get = + new (GetAllocator()) HArrayGet(null_check, bounds_check, DataType::Type::kInt32, dex_pc); + HInstruction* add = new (GetAllocator()) HAdd(DataType::Type::kInt32, array_get, const_1); + HInstruction* array_set = + new (GetAllocator()) HArraySet(null_check, bounds_check, add, DataType::Type::kInt32, dex_pc); + HInstruction* induction_inc = new (GetAllocator()) HAdd(DataType::Type::kInt32, phi, const_1); + + loop_body->AddInstruction(null_check); + loop_body->AddInstruction(array_length); + loop_body->AddInstruction(bounds_check); + loop_body->AddInstruction(array_get); + loop_body->AddInstruction(add); + loop_body->AddInstruction(array_set); + loop_body->AddInstruction(induction_inc); + loop_body->AddInstruction(new (GetAllocator()) HGoto()); + + phi->AddInput(const_0); + phi->AddInput(induction_inc); + + graph_->SetHasBoundsChecks(true); + + // Adjust HEnvironment for each instruction which require that. + ArenaVector current_locals({phi, const_128, parameter_}, + GetAllocator()->Adapter(kArenaAllocInstruction)); + + HEnvironment* env = ManuallyBuildEnvFor(suspend_check, ¤t_locals); + null_check->CopyEnvironmentFrom(env); + bounds_check->CopyEnvironmentFrom(env); + } + + HEnvironment* ManuallyBuildEnvFor(HInstruction* instruction, + ArenaVector* current_locals) { + HEnvironment* environment = new (GetAllocator()) HEnvironment( + (GetAllocator()), + current_locals->size(), + graph_->GetArtMethod(), + instruction->GetDexPc(), + instruction); + + environment->CopyFrom(ArrayRef(*current_locals)); + instruction->SetRawEnvironment(environment); + return environment; + } + + bool CheckGraph() { + GraphChecker checker(graph_); + checker.Run(); + if (!checker.IsValid()) { + for (const std::string& error : checker.GetErrors()) { + std::cout << error << std::endl; + } + return false; + } + return true; + } + + HGraph* graph_; + + HBasicBlock* entry_block_; + HBasicBlock* exit_block_; + + HInstruction* parameter_; +}; + +TEST_F(SuperblockClonerTest, IndividualInstrCloner) { + HBasicBlock* header = nullptr; + HBasicBlock* loop_body = nullptr; + + CreateBasicLoopControlFlow(&header, &loop_body); + CreateBasicLoopDataFlow(header, loop_body); + graph_->BuildDominatorTree(); + ASSERT_TRUE(CheckGraph()); + + HSuspendCheck* old_suspend_check = header->GetLoopInformation()->GetSuspendCheck(); + CloneAndReplaceInstructionVisitor visitor(graph_); + // Do instruction cloning and replacement twice with different visiting order. + + visitor.VisitInsertionOrder(); + size_t instr_replaced_by_clones_count = visitor.GetInstrReplacedByClonesCount(); + EXPECT_EQ(instr_replaced_by_clones_count, 12u); + EXPECT_TRUE(CheckGraph()); + + visitor.VisitReversePostOrder(); + instr_replaced_by_clones_count = visitor.GetInstrReplacedByClonesCount(); + EXPECT_EQ(instr_replaced_by_clones_count, 24u); + EXPECT_TRUE(CheckGraph()); + + HSuspendCheck* new_suspend_check = header->GetLoopInformation()->GetSuspendCheck(); + EXPECT_NE(new_suspend_check, old_suspend_check); + EXPECT_NE(new_suspend_check, nullptr); +} + +} // namespace art -- cgit v1.2.3-59-g8ed1b