• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cstring>
17 #include <gtest/gtest.h>
18 #include <iomanip>
19 #include <iostream>
20 #include <memory>
21 #include <sstream>
22 #include <string>
23 
24 #include "basicblock.h"
25 #include "graph.h"
26 #include "graph_test.h"
27 #include "inst.h"
28 #include "mem/pool_manager.h"
29 #include "optimizer/analysis/loop_analyzer.h"
30 
31 using namespace testing::ext;
32 
33 namespace panda::compiler {
34 class CompilerBasicBlockTest : public testing::Test {
35 public:
SetUpTestCase(void)36     static void SetUpTestCase(void) {}
TearDownTestCase(void)37     static void TearDownTestCase(void) {}
SetUp()38     void SetUp() {}
TearDown()39     void TearDown() {}
40 
41     GraphTest graph_test_;
42 };
43 
44 /**
45  * @tc.name: compiler_basicblock_test_001
46  * @tc.desc: Verify the BlocksPathDfsSearch function.
47  * @tc.type: FUNC
48  * @tc.require: issueNumber
49  */
50 HWTEST_F(CompilerBasicBlockTest, compiler_basicblock_test_001, TestSize.Level1)
51 {
52     std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc";
__anond946d00f0102(Graph* graph, std::string &method_name) 53     graph_test_.TestBuildGraphFromFile(pfile, [&](Graph* graph, std::string &method_name) {
54         Marker mrk = 4;  // 4: It's a random number
55         auto start_block = graph->GetStartBlock();
56         auto end_block = graph->GetEndBlock();
57         auto value = BlocksPathDfsSearch(mrk, start_block, start_block, end_block);
58         EXPECT_TRUE(value);
59         for (auto bb : graph->GetBlocksRPO()) {
60             if (!bb->IsCatchBegin()) {
61                 continue;
62             }
63 
64             EXPECT_TRUE(BlocksPathDfsSearch(mrk, start_block, end_block, bb->GetSuccessor(0)));
65             EXPECT_FALSE(BlocksPathDfsSearch(mrk, start_block, bb->GetSuccessor(0), end_block));
66             EXPECT_FALSE(BlocksPathDfsSearch(mrk, end_block, start_block, bb->GetSuccessor(0)));
67         }
68     });
69 }
70 
71 /**
72  * @tc.name: compiler_basicblock_test_002
73  * @tc.desc: Verify the InsertBlockBefore function.
74  * @tc.type: FUNC
75  * @tc.require: issueNumber
76  */
77 HWTEST_F(CompilerBasicBlockTest, compiler_basicblock_test_002, TestSize.Level1)
78 {
79     std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc";
80     const char *test_method_name = "func_main_0";
81     bool status = false;
__anond946d00f0202(Graph* graph, std::string &method_name) 82     graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) {
83         if (test_method_name != method_name) {
84             return;
85         }
86         status = true;
87         for (auto bb : graph->GetBlocksRPO()) {
88             if (!bb->IsTry()) {
89                 continue;
90             }
91             graph->GetEndBlock()->InsertBlockBefore(bb->GetPredecessor(0));
92             graph->GetStartBlock()->InsertBlockBefore(bb->GetPredecessor(0));
93         }
94 
95         EXPECT_TRUE(graph->GetStartBlock()->IsDominate(graph->GetStartBlock()));
96     });
97     EXPECT_TRUE(status);
98 }
99 
100 /**
101  * @tc.name: compiler_basicblock_test_003
102  * @tc.desc: Verify the Clone function.
103  * @tc.type: FUNC
104  * @tc.require: issueNumber
105  */
106 HWTEST_F(CompilerBasicBlockTest, compiler_basicblock_test_003, TestSize.Level1)
107 {
108     std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc";
109     const char *test_method_name = "func_main_0";
110     bool status = false;
__anond946d00f0302(Graph* graph, std::string &method_name) 111     graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) {
112         if (test_method_name != method_name) {
113             return;
114         }
115 
116         for (auto bb : graph->GetBlocksRPO()) {
117             if (bb->IsStartBlock() || bb->IsEndBlock() || bb->IsTryEnd()) {
118                 status = true;
119                 EXPECT_FALSE(bb->Clone(graph)->IsTry());
120             }
121         }
122     });
123     EXPECT_TRUE(status);
124 }
125 
126 /**
127  * @tc.name: compiler_basicblock_test_004
128  * @tc.desc: Verify the CreateImmediateDominator function.
129  * @tc.type: FUNC
130  * @tc.require: issueNumber
131  */
132 HWTEST_F(CompilerBasicBlockTest, compiler_basicblock_test_004, TestSize.Level1)
133 {
134     std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc";
135     const char *test_method_name = "func_main_0";
136     bool status = false;
__anond946d00f0402(Graph* graph, std::string &method_name) 137     graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) {
138         if (test_method_name != method_name) {
139             return;
140         }
141 
142         status = true;
143         EXPECT_TRUE(graph->GetStartBlock()->CreateImmediateDominator()->IsEmpty());
144     });
145     EXPECT_TRUE(status);
146 }
147 
148 /**
149  * @tc.name: compiler_basicblock_test_005
150  * @tc.desc: Verify the IsDominate function.
151  * @tc.type: FUNC
152  * @tc.require: issueNumber
153  */
154 HWTEST_F(CompilerBasicBlockTest, compiler_basicblock_test_005, TestSize.Level1)
155 {
156     std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc";
157     const char *test_method_name = "func_main_0";
158     bool status = false;
__anond946d00f0502(Graph* graph, std::string &method_name) 159     graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) {
160         if (test_method_name != method_name) {
161             return;
162         }
163         status = true;
164         auto start_block = graph->GetStartBlock();
165         auto end_block = graph->GetEndBlock();
166 
167         EXPECT_TRUE(start_block->IsDominate(end_block));
168         EXPECT_FALSE(end_block->IsDominate(start_block));
169     });
170     EXPECT_TRUE(status);
171 }
172 
173 /**
174  * @tc.name: compiler_basicblock_test_006
175  * @tc.desc: Verify the EraseInst function.
176  * @tc.type: FUNC
177  * @tc.require: issueNumber
178  */
179 HWTEST_F(CompilerBasicBlockTest, compiler_basicblock_test_006, TestSize.Level1)
180 {
181     std::string pfile = GRAPH_TEST_ABC_DIR "styleTryCatch.abc";
182     const char *test_method_name = "func_main_0";
183     bool status = false;
184     options.SetCompilerUseSafepoint(false);
__anond946d00f0602(Graph* graph, std::string &method_name) 185     graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) {
186         if (test_method_name != method_name) {
187             return;
188         }
189 
190         EXPECT_NE(graph, nullptr);
191         for (auto bb : graph->GetBlocksRPO()) {
192             for (auto inst : bb->PhiInsts()) {
193                 status = true;
194                 bb->EraseInst(inst, true);
195                 EXPECT_EQ(inst->GetNext(), nullptr);
196                 break;
197             }
198         }
199     });
200     EXPECT_TRUE(status);
201 }
202 
203 /**
204  * @tc.name: compiler_basicblock_test_007
205  * @tc.desc: Verify the RemoveInst function.
206  * @tc.type: FUNC
207  * @tc.require: issueNumber
208  */
209 HWTEST_F(CompilerBasicBlockTest, compiler_basicblock_test_007, TestSize.Level1)
210 {
211     std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc";
212     const char *test_method_name = "func_main_0";
213     bool status = false;
214     graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph,
__anond946d00f0702(Graph* graph, std::string &method_name) 215         std::string &method_name) {
216         if (test_method_name != method_name) {
217             return;
218         }
219         status = true;
220         EXPECT_NE(graph, nullptr);
221         auto start_block = graph->GetStartBlock();
222         start_block->RemoveInst(graph->GetFirstConstInst());
223         for (auto bb : graph->GetBlocksRPO()) {
224             for (auto inst : bb->AllInsts()) {
225                 status = true;
226                 bb->RemoveInst(inst);
227                 EXPECT_EQ(inst->GetNext(), nullptr);
228             }
229         }
230     });
231     EXPECT_TRUE(status);
232 }
233 
234 /**
235  * @tc.name: compiler_basicblock_test_008
236  * @tc.desc: Verify the IsInverted function.
237  * @tc.type: FUNC
238  * @tc.require: issueNumber
239  */
240 HWTEST_F(CompilerBasicBlockTest, compiler_basicblock_test_008, TestSize.Level1)
241 {
242     std::string pfile = GRAPH_TEST_ABC_DIR "testTryCatch.abc";
243     const char *test_method_name = "func_main_0";
244     bool status = false;
__anond946d00f0802(Graph* graph, std::string &method_name) 245     graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) {
246         if (test_method_name != method_name) {
247             return;
248         }
249         status = true;
250         auto bb = graph->GetStartBlock();
251         bb->InstsSafe();
252         EXPECT_EQ(bb->GetPredsBlocks().size(), 0);
253         bb->PhiInstsSafeReverse();
254         EXPECT_FALSE(bb->IsInverted());
255     });
256     EXPECT_TRUE(status);
257 }
258 
259 /**
260  * @tc.name: compiler_basicblock_test_009
261  * @tc.desc: Verify the ReplaceInst function.
262  * @tc.type: FUNC
263  * @tc.require: issueNumber
264  */
265 HWTEST_F(CompilerBasicBlockTest, compiler_basicblock_test_009, TestSize.Level1)
266 {
267     std::string pfile = GRAPH_TEST_ABC_DIR "styleTryCatch.abc";
268     const char *test_method_name = "func_main_0";
269     bool status = false;
270     graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph,
__anond946d00f0902(Graph* graph, std::string &method_name) 271         std::string &method_name) {
272         if (test_method_name != method_name) {
273             return;
274         }
275 
276         EXPECT_NE(graph, nullptr);
277         for (auto bb : graph->GetBlocksRPO()) {
278             for (auto phi : bb->PhiInsts()) {
279                 status = true;
280                 auto phi1 = graph->CreateInstPhi(DataType::ANY, 0U);
281                 bb->ReplaceInst(phi, phi1);
282             }
283         }
284     });
285     EXPECT_TRUE(status);
286 }
287 
288 /**
289  * @tc.name: compiler_basicblock_test_010
290  * @tc.desc: Verify the InsertRangeBefore function.
291  * @tc.type: FUNC
292  * @tc.require: issueNumber
293  */
294 HWTEST_F(CompilerBasicBlockTest, compiler_basicblock_test_010, TestSize.Level1)
295 {
296     std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc";
297     const char *test_method_name = "func2";
298     bool status = false;
__anond946d00f0a02(Graph* graph, std::string &method_name) 299     graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) {
300         if (test_method_name != method_name) {
301             return;
302         }
303 
304         status = true;
305         auto block = graph->GetBlocksRPO()[0];
306         block->InsertRangeBefore(block->GetFirstInst(), block->GetLastInst(), graph->GetFirstConstInst());
307         EXPECT_EQ(block->GetLastInst()->GetNext(), graph->GetFirstConstInst());
308     });
309     EXPECT_TRUE(status);
310 }
311 
312 /**
313  * @tc.name: compiler_basicblock_test_011
314  * @tc.desc: Verify the InvalidateLoopIfIrreducible function.
315  * @tc.type: FUNC
316  * @tc.require: issueNumber
317  */
318 HWTEST_F(CompilerBasicBlockTest, compiler_basicblock_test_011, TestSize.Level1)
319 {
320     std::string pfile = GRAPH_TEST_ABC_DIR "styleTryCatch.abc";
321     const char *test_method_name = "func_main_0";
322     bool status = false;
323     bool status1 = false;
324     bool status2 = false;
325     graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status, &status1, &status2](Graph* graph,
__anond946d00f0b02(Graph* graph, std::string &method_name) 326         std::string &method_name) {
327         if (test_method_name != method_name) {
328             return;
329         }
330 
331         EXPECT_NE(graph, nullptr);
332         uint32_t id = 2;
333         for (auto block : graph->GetBlocksRPO()) {
334             if (block->IsTry()) {
335                 status = true;
336                 Loop loop(graph->GetAllocator(), block, id);
337                 loop.SetIsIrreducible(true);
338                 EXPECT_TRUE(loop.IsIrreducible());
339                 block->SetLoop(&loop);
340                 EXPECT_NE(block->GetLoop(), nullptr);
341                 block->InvalidateLoopIfIrreducible();
342             }
343             if (block->IsTryBegin()) {
344                 status1 = true;
345                 Loop loop1(graph->GetAllocator(), block, id);
346                 block->SetLoop(&loop1);
347                 EXPECT_NE(block->GetLoop(), nullptr);
348                 block->InvalidateLoopIfIrreducible();
349             }
350             if (block->IsTryEnd()) {
351                 status2 = true;
352                 Loop loop2(graph->GetAllocator(), graph->GetEndBlock(), id);
353                 loop2.SetIsIrreducible(true);
354                 EXPECT_TRUE(loop2.IsIrreducible());
355                 block->SetLoop(&loop2);
356                 EXPECT_NE(block->GetLoop(), nullptr);
357             }
358         }
359     });
360     EXPECT_TRUE(status);
361     EXPECT_TRUE(status1);
362     EXPECT_TRUE(status2);
363 }
364 
365 /**
366  * @tc.name: compiler_basicblock_test_012
367  * @tc.desc: Verify the InsertAfter function.
368  * @tc.type: FUNC
369  * @tc.require: issueNumber
370  */
371 HWTEST_F(CompilerBasicBlockTest, compiler_basicblock_test_012, TestSize.Level1)
372 {
373     std::string pfile = GRAPH_TEST_ABC_DIR "moduleTryCatch.abc";
374     const char *test_method_name = "func2";
375     bool status = false;
__anond946d00f0c02(Graph* graph, std::string &method_name) 376     graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) {
377         if (test_method_name != method_name) {
378             return;
379         }
380         status = true;
381 
382         for (auto block : graph->GetBlocksRPO()) {
383             auto inst = graph->CreateInstSaveState(DataType::ANY, 0);
384             graph->GetFirstConstInst()->SetBasicBlock(block);
385             EXPECT_EQ(graph->GetFirstConstInst()->GetBasicBlock(), block);
386             block->InsertAfter(inst, graph->GetFirstConstInst());
387             EXPECT_EQ(graph->GetFirstConstInst()->GetNext(), inst);
388         }
389     });
390     EXPECT_TRUE(status);
391 }
392 
393 /**
394  * @tc.name: compiler_basicblock_test_013
395  * @tc.desc: Verify the AppendRangeInst function.
396  * @tc.type: FUNC
397  * @tc.require: issueNumber
398  */
399 HWTEST_F(CompilerBasicBlockTest, compiler_basicblock_test_013, TestSize.Level1)
400 {
401     std::string pfile = GRAPH_TEST_ABC_DIR "styleTryCatch.abc";
402     const char *test_method_name = "func_main_0";
403     bool status = false;
__anond946d00f0d02(Graph* graph, std::string &method_name) 404     graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) {
405         if (test_method_name != method_name) {
406             return;
407         }
408 
409         EXPECT_NE(graph, nullptr);
410         status = true;
411         auto start_block = graph->GetStartBlock();
412         auto end_block = graph->GetEndBlock();
413 
414         graph->GetFirstConstInst()->SetPrev(nullptr);
415         EXPECT_EQ(graph->GetFirstConstInst()->GetPrev(), nullptr);
416         start_block->AppendRangeInst(graph->GetFirstConstInst(), start_block->GetLastInst());
417         EXPECT_EQ(graph->GetFirstConstInst()->GetPrev(), start_block->GetLastInst());
418         start_block->AddSucc(end_block);
419         EXPECT_NE(start_block->InsertNewBlockToSuccEdge(end_block), nullptr);
420     });
421     EXPECT_TRUE(status);
422 }
423 
424 /**
425  * @tc.name: compiler_basicblock_test_014
426  * @tc.desc: Verify the SplitBlockAfterInstruction function.
427  * @tc.type: FUNC
428  * @tc.require: issueNumber
429  */
430 HWTEST_F(CompilerBasicBlockTest, compiler_basicblock_test_014, TestSize.Level1)
431 {
432     std::string pfile = GRAPH_TEST_ABC_DIR "styleTryCatch.abc";
433     const char *test_method_name = "func_main_0";
434     bool status = false;
435     bool status1 = false;
436     graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status, &status1](Graph* graph,
__anond946d00f0e02(Graph* graph, std::string &method_name) 437         std::string &method_name) {
438         if (test_method_name != method_name) {
439             return;
440         }
441 
442         EXPECT_NE(graph, nullptr);
443         for (auto bb : graph->GetBlocksRPO()) {
444             if (bb->IsTry() && bb->IsLoopValid()) {
445                 auto inst = bb->GetLastInst();
446                 EXPECT_NE(bb->SplitBlockAfterInstruction(inst, false), nullptr);
447                 EXPECT_NE(bb->SplitBlockAfterInstruction(inst, true), nullptr);
448                 status = true;
449                 break;
450             }
451         }
452 
453         for (auto bb : graph->GetVectorBlocks()) {
454             for (auto inst : bb->AllInsts()) {
455                 if (inst->IsPhi() || bb->IsStartBlock() || bb->IsEndBlock()) {
456                     continue;
457                 }
458                 status1 = true;
459                 EXPECT_NE(bb->SplitBlockAfterInstruction(inst, true), nullptr);
460             }
461         }
462     });
463     EXPECT_TRUE(status);
464     EXPECT_TRUE(status1);
465 }
466 
467 /**
468  * @tc.name: compiler_basicblock_test_015
469  * @tc.desc: Verify the IsIfBlock function.
470  * @tc.type: FUNC
471  * @tc.require: issueNumber
472  */
473 HWTEST_F(CompilerBasicBlockTest, compiler_basicblock_test_015, TestSize.Level1)
474 {
475     std::string pfile = GRAPH_TEST_ABC_DIR "styleTryCatch.abc";
476     const char *test_method_name = "func_main_0";
477     bool status = false;
478     bool status1 = false;
479     graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status, &status1](Graph* graph,
__anond946d00f0f02(Graph* graph, std::string &method_name) 480         std::string &method_name) {
481         if (test_method_name != method_name) {
482             return;
483         }
484         EXPECT_NE(graph, nullptr);
485         auto end_block = graph->GetEndBlock();
486         for (auto bb : graph->GetBlocksRPO()) {
487             for (auto inst : bb->AllInsts()) {
488                 if (inst->GetOpcode() == Opcode::IfImm) {
489                     status = true;
490                     EXPECT_TRUE(bb->IsIfBlock());
491                     bb->GetLastInst()->SetOpcode(Opcode::If);
492                     EXPECT_TRUE(bb->IsIfBlock());
493                 }
494                 if (inst->IsTry()) {
495                     status1 = true;
496                     EXPECT_FALSE(bb->IsIfBlock());
497                 }
498 
499                 EXPECT_FALSE(end_block->IsIfBlock());
500             }
501         }
502     });
503     EXPECT_TRUE(status);
504 }
505 
506 /**
507  * @tc.name: compiler_basicblock_test_016
508  * @tc.desc: Verify the CopyTryCatchProps function.
509  * @tc.type: FUNC
510  * @tc.require: issueNumber
511  */
512 HWTEST_F(CompilerBasicBlockTest, compiler_basicblock_test_016, TestSize.Level1)
513 {
514     std::string pfile = GRAPH_TEST_ABC_DIR "testTryCatch.abc";
515     const char *test_method_name = "func_main_0";
516     bool status = false;
__anond946d00f1002(Graph* graph, std::string &method_name) 517     graph_test_.TestBuildGraphFromFile(pfile, [&test_method_name, &status](Graph* graph, std::string &method_name) {
518         if (test_method_name != method_name) {
519             return;
520         }
521         auto bb = graph->GetStartBlock();
522         status = true;
523         bb->SetTry(true);
524         bb->CopyTryCatchProps(bb);
525         EXPECT_EQ(bb->GetTryId(), INVALID_ID);
526         EXPECT_FALSE(bb->IsOsrEntry());
527     });
528     EXPECT_TRUE(status);
529 }
530 }  // namespace panda::compiler
531