1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include <gtest/gtest.h> 17 18 #include "compiler/optimizer/ir/basicblock.h" 19 #include "graph.h" 20 #include "graph_test.h" 21 #include "mem/pool_manager.h" 22 #include "optimizer/analysis/loop_analyzer.h" 23 #include "optimizer/analysis/rpo.h" 24 25 using namespace testing::ext; 26 27 namespace panda::compiler { 28 class LoopAnalyzerTest : public testing::Test { 29 public: SetUpTestCase(void)30 static void SetUpTestCase(void) {} TearDownTestCase(void)31 static void TearDownTestCase(void) {} SetUp()32 void SetUp() {} TearDown()33 void TearDown() {} 34 35 GraphTest graph_test_; 36 }; 37 38 /** 39 * @tc.name: loop_analyzer_test_001 40 * @tc.desc: Verify the RunImpl function. 41 * @tc.type: FUNC 42 * @tc.require: issueNumber 43 */ 44 HWTEST_F(LoopAnalyzerTest, loop_analyzer_test_001, TestSize.Level1) 45 { 46 std::string pfile = GRAPH_TEST_ABC_DIR "dominatorsTryCatch.abc"; 47 const char *test_method_name = "func_main_0"; 48 bool status = false; 49 __anon7b86c5900102(Graph* graph, std::string &method_name) 50 graph_test_.TestBuildGraphFromFile(pfile, [test_method_name, &status](Graph* graph, std::string &method_name) { 51 if (test_method_name != method_name) { 52 return; 53 } 54 status = true; 55 EXPECT_NE(graph, nullptr); 56 EXPECT_TRUE(graph->RunPass<LoopAnalyzer>()); 57 }); 58 EXPECT_TRUE(status); 59 } 60 61 /** 62 * @tc.name: loop_analyzer_test_002 63 * @tc.desc: Verify the IsInside function. 64 * @tc.type: FUNC 65 * @tc.require: issueNumber 66 */ 67 HWTEST_F(LoopAnalyzerTest, loop_analyzer_test_002, TestSize.Level1) 68 { 69 std::string pfile = GRAPH_TEST_ABC_DIR "dominatorsTryCatch.abc"; 70 const char *test_method_name = "func_main_0"; 71 bool status = false; 72 __anon7b86c5900202(Graph* graph, std::string &method_name) 73 graph_test_.TestBuildGraphFromFile(pfile, [test_method_name, &status](Graph* graph, std::string &method_name) { 74 if (test_method_name != method_name) { 75 return; 76 } 77 status = true; 78 EXPECT_NE(graph, nullptr); 79 for (auto bb : graph->GetBlocksRPO()) { 80 EXPECT_NE(bb, nullptr); 81 if (!bb->IsTryBegin()) { 82 continue; 83 } 84 Loop loop(graph->GetAllocator(), bb->GetSuccessor(0), 1); 85 Loop other(graph->GetAllocator(), bb->GetSuccessor(0), 1); 86 EXPECT_FALSE(loop.IsInside(&other)); 87 88 loop.SetOuterLoop(&other); 89 EXPECT_TRUE(loop.IsInside(&other)); 90 } 91 }); 92 EXPECT_TRUE(status); 93 } 94 95 /** 96 * @tc.name: loop_analyzer_test_003 97 * @tc.desc: Verify the GetLoopOutsideSuccessor function. 98 * @tc.type: FUNC 99 * @tc.require: issueNumber 100 */ 101 HWTEST_F(LoopAnalyzerTest, loop_analyzer_test_003, TestSize.Level1) 102 { 103 std::string pfile = GRAPH_TEST_ABC_DIR "dominatorsTryCatch.abc"; 104 const char *test_method_name = "func_main_0"; 105 bool status = false; 106 __anon7b86c5900302(Graph* graph, std::string &method_name) 107 graph_test_.TestBuildGraphFromFile(pfile, [test_method_name, &status](Graph* graph, std::string &method_name) { 108 if (test_method_name != method_name) { 109 return; 110 } 111 status = true; 112 EXPECT_NE(graph, nullptr); 113 for (auto bb : graph->GetBlocksRPO()) { 114 EXPECT_NE(bb, nullptr); 115 if (!bb->IsTryBegin()) { 116 continue; 117 } 118 Loop loop(graph->GetAllocator(), bb->GetSuccessor(0), 1); 119 loop.AppendBackEdge(bb->GetSuccessor(1)); 120 loop.GetBackEdges()[0]->AddSucc(bb->GetSuccessor(0)); 121 EXPECT_EQ(loop.GetBackEdges()[0]->GetSuccBlockIndex(loop.GetHeader()), 1); 122 EXPECT_NE(GetLoopOutsideSuccessor(&loop), nullptr); 123 EXPECT_FALSE(loop.IsRoot()); 124 } 125 }); 126 EXPECT_TRUE(status); 127 } 128 129 /** 130 * @tc.name: loop_analyzer_test_004 131 * @tc.desc: Verify the IsLoopSingleBackEdgeExitPoint function. 132 * @tc.type: FUNC 133 * @tc.require: issueNumber 134 */ 135 HWTEST_F(LoopAnalyzerTest, loop_analyzer_test_004, TestSize.Level1) 136 { 137 std::string pfile = GRAPH_TEST_ABC_DIR "dominatorsTryCatch.abc"; 138 const char *test_method_name = "func_main_0"; 139 bool status = false; 140 __anon7b86c5900402(Graph* graph, std::string &method_name) 141 graph_test_.TestBuildGraphFromFile(pfile, [test_method_name, &status](Graph* graph, std::string &method_name) { 142 if (test_method_name != method_name) { 143 return; 144 } 145 status = true; 146 EXPECT_NE(graph, nullptr); 147 for (auto bb : graph->GetBlocksRPO()) { 148 EXPECT_NE(bb, nullptr); 149 if (!bb->IsTryBegin()) { 150 continue; 151 } 152 Loop loop(graph->GetAllocator(), bb->GetSuccessor(0), 1); 153 EXPECT_FALSE(IsLoopSingleBackEdgeExitPoint(&loop)); 154 155 loop.SetIsIrreducible(true); 156 EXPECT_TRUE(loop.IsIrreducible()); 157 EXPECT_FALSE(IsLoopSingleBackEdgeExitPoint(&loop)); 158 } 159 }); 160 EXPECT_TRUE(status); 161 } 162 163 /** 164 * @tc.name: loop_analyzer_test_005 165 * @tc.desc: Verify the IsLoopSingleBackEdgeExitPoint function. 166 * @tc.type: FUNC 167 * @tc.require: issueNumber 168 */ 169 HWTEST_F(LoopAnalyzerTest, loop_analyzer_test_005, TestSize.Level1) 170 { 171 std::string pfile = GRAPH_TEST_ABC_DIR "dominatorsTryCatch.abc"; 172 const char *test_method_name = "func_main_0"; 173 bool status = false; 174 __anon7b86c5900502(Graph* graph, std::string &method_name) 175 graph_test_.TestBuildGraphFromFile(pfile, [test_method_name, &status](Graph* graph, std::string &method_name) { 176 if (test_method_name != method_name) { 177 return; 178 } 179 status = true; 180 EXPECT_NE(graph, nullptr); 181 for (auto bb : graph->GetBlocksRPO()) { 182 EXPECT_NE(bb, nullptr); 183 if (!bb->IsTryBegin()) { 184 continue; 185 } 186 Loop loop(graph->GetAllocator(), bb->GetSuccessor(0), 1); 187 188 loop.AppendBackEdge(bb->GetSuccessor(1)); 189 loop.AppendBlock(bb->GetSuccessor(1)); 190 EXPECT_TRUE(IsLoopSingleBackEdgeExitPoint(&loop)); 191 192 loop.AppendBlock(bb->GetSuccessor(0)); 193 EXPECT_FALSE(IsLoopSingleBackEdgeExitPoint(&loop)); 194 } 195 }); 196 EXPECT_TRUE(status); 197 } 198 199 /** 200 * @tc.name: oop_analyzer_test_006 201 * @tc.desc: Verify the MoveHeaderToSucc function. 202 * @tc.type: FUNC 203 * @tc.require: issueNumber 204 */ 205 HWTEST_F(LoopAnalyzerTest, loop_analyzer_test_006, TestSize.Level1) 206 { 207 std::string pfile = GRAPH_TEST_ABC_DIR "dominatorsTryCatch.abc"; 208 const char *test_method_name = "func_main_0"; 209 bool status = false; 210 __anon7b86c5900602(Graph* graph, std::string &method_name) 211 graph_test_.TestBuildGraphFromFile(pfile, [test_method_name, &status](Graph* graph, std::string &method_name) { 212 if (test_method_name != method_name) { 213 return; 214 } 215 status = true; 216 EXPECT_NE(graph, nullptr); 217 auto bb = graph->GetEndBlock(); 218 Loop loop(graph->GetAllocator(), bb, 0); 219 loop.AppendBlock(bb); 220 EXPECT_EQ(bb->GetSuccsBlocks().size(), 0); 221 bb->AddSucc(bb); 222 EXPECT_EQ(bb->GetSuccsBlocks().size(), 1); 223 loop.MoveHeaderToSucc(); 224 EXPECT_NE(loop.GetHeader(), nullptr); 225 }); 226 EXPECT_TRUE(status); 227 } 228 } // namespace panda::compiler 229