• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2024 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 "libabckit/include/c/metadata_core.h"
17 #include "libabckit/include/c/ir_core.h"
18 #include "helpers/helpers.h"
19 #include "libabckit/include/c/abckit.h"
20 #include "logger.h"
21 
22 #include <gtest/gtest.h>
23 
24 namespace libabckit::test {
25 
26 class LibAbcKitBasicBlocksTest : public ::testing::Test {};
27 
28 static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
29 static auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
30 static auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
31 static auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32 static auto g_statG = AbckitGetIsaApiStaticImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33 
VerifyGraphStart(AbckitFile * file)34 static void VerifyGraphStart(AbckitFile *file)
35 {
36     // Find transformed method
37     AbckitCoreFunction *testMethod = helpers::FindMethodByName(file, "foo");
38     ASSERT_NE(testMethod, nullptr);
39 
40     // Get graph
41     AbckitGraph *graph = g_implI->createGraphFromFunction(testMethod);
42     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
43 
44     AbckitBasicBlock *startBB = g_implG->gGetStartBasicBlock(graph);
45     ASSERT_NE(startBB, nullptr);
46 
47     // Verify bb predecessors
48     ASSERT_EQ(helpers::BBgetPredBlocks(startBB).size(), 0);
49 
50     // Verify bb successors
51     ASSERT_EQ(helpers::BBgetSuccBlocks(startBB).size(), 1);
52 
53     // Verify instructions
54     auto *inst = g_implG->bbGetFirstInst(startBB);
55 
56     ASSERT_EQ(g_statG->iGetOpcode(inst), ABCKIT_ISA_API_STATIC_OPCODE_PARAMETER);
57     ASSERT_EQ(g_implG->iGetId(inst), 0);
58 
59     g_impl->destroyGraph(graph);
60 }
61 
VerifyGraphEnd(AbckitFile * file)62 static void VerifyGraphEnd(AbckitFile *file)
63 {
64     // Find transformed method
65     AbckitCoreFunction *testMethod = helpers::FindMethodByName(file, "foo");
66     ASSERT_NE(testMethod, nullptr);
67 
68     // Get graph
69     AbckitGraph *graph = g_implI->createGraphFromFunction(testMethod);
70     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
71 
72     AbckitBasicBlock *endBB = g_implG->gGetEndBasicBlock(graph);
73     ASSERT_NE(endBB, nullptr);
74 
75     // Verify bb predecessors
76     ASSERT_EQ(helpers::BBgetPredBlocks(endBB).size(), 1);
77 
78     // Verify bb successors
79     ASSERT_EQ(helpers::BBgetSuccBlocks(endBB).size(), 0);
80 
81     // Verify instructions
82     ASSERT_EQ(g_implG->bbGetFirstInst(endBB), nullptr);
83 
84     g_impl->destroyGraph(graph);
85 }
86 
VerifyGraphVisitBlocks(AbckitFile * file)87 static void VerifyGraphVisitBlocks(AbckitFile *file)
88 {
89     // Find transformed method
90     AbckitCoreFunction *testMethod = helpers::FindMethodByName(file, "foo");
91     ASSERT_NE(testMethod, nullptr);
92 
93     // Get graph
94     AbckitGraph *graph = g_implI->createGraphFromFunction(testMethod);
95     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
96 
97     std::vector<AbckitBasicBlock *> bbs;
98 
99     // Collect basic blocks
100     g_implG->gVisitBlocksRpo(graph, &bbs, [](AbckitBasicBlock *bb, void *data) {
101         reinterpret_cast<std::vector<AbckitBasicBlock *> *>(data)->emplace_back(bb);
102         return true;
103     });
104 
105     ASSERT_EQ(bbs.size(), 3U);
106 
107     auto *startBB = bbs[0];
108 
109     // Verify bb predecessors
110     ASSERT_EQ(helpers::BBgetPredBlocks(startBB).size(), 0);
111 
112     // Verify bb successors
113     ASSERT_EQ(helpers::BBgetSuccBlocks(startBB).size(), 1);
114 
115     // Verify instructions
116     auto *inst = g_implG->bbGetFirstInst(startBB);
117 
118     ASSERT_EQ(g_statG->iGetOpcode(inst), ABCKIT_ISA_API_STATIC_OPCODE_PARAMETER);
119     ASSERT_EQ(g_implG->iGetId(inst), 0);
120 
121     startBB = bbs[1];
122 
123     // Verify bb predecessors
124     ASSERT_EQ(helpers::BBgetPredBlocks(startBB).size(), 1);
125 
126     // Verify bb successors
127     ASSERT_EQ(helpers::BBgetSuccBlocks(startBB).size(), 1);
128 
129     // Verify instructions
130     inst = g_implG->bbGetFirstInst(startBB);
131 
132     ASSERT_EQ(g_statG->iGetOpcode(inst), ABCKIT_ISA_API_STATIC_OPCODE_RETURN);
133     ASSERT_EQ(g_implG->iGetId(inst), 2U);
134 
135     startBB = bbs[2U];
136     ASSERT_NE(startBB, nullptr);
137 
138     // Verify bb predecessors
139     ASSERT_EQ(helpers::BBgetPredBlocks(startBB).size(), 1);
140 
141     // Verify bb successors
142     ASSERT_EQ(helpers::BBgetSuccBlocks(startBB).size(), 0);
143 
144     // Verify instructions
145     inst = g_implG->bbGetFirstInst(startBB);
146     ASSERT_EQ(inst, nullptr);
147 
148     g_impl->destroyGraph(graph);
149 }
150 
151 // Test: test-kind=api, api=GraphApiImpl::gGetStartBasicBlock, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitBasicBlocksTest,GgetStartBasicBlockValid)152 TEST_F(LibAbcKitBasicBlocksTest, GgetStartBasicBlockValid)
153 {
154     constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "ut/ir_core/graph_basic_block/graph_basic_block.abc";
155     AbckitFile *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
156     LIBABCKIT_LOG(DEBUG) << "LibAbcKitTestStaticGgetStartBasicBlock: " << INPUT_PATH << std::endl;
157 
158     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
159 
160     VerifyGraphStart(file);
161 
162     g_impl->closeFile(file);
163     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
164 }
165 
166 // Test: test-kind=api, api=GraphApiImpl::gGetEndBasicBlock, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitBasicBlocksTest,GgetEndBasicBlockValid)167 TEST_F(LibAbcKitBasicBlocksTest, GgetEndBasicBlockValid)
168 {
169     constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "ut/ir_core/graph_basic_block/graph_basic_block.abc";
170     AbckitFile *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
171     LIBABCKIT_LOG(DEBUG) << "LibAbcKitTestStaticGgetEndBasicBlock: " << INPUT_PATH << std::endl;
172     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
173 
174     VerifyGraphEnd(file);
175 
176     g_impl->closeFile(file);
177     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
178 }
179 
180 // Test: test-kind=api, api=GraphApiImpl::gVisitBlocksRpo, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitBasicBlocksTest,GvisitBlocksRPO)181 TEST_F(LibAbcKitBasicBlocksTest, GvisitBlocksRPO)
182 {
183     constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "ut/ir_core/graph_basic_block/graph_basic_block.abc";
184     AbckitFile *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
185     LIBABCKIT_LOG(DEBUG) << "LibAbcKitTestStaticGgetEndBasicBlock: " << INPUT_PATH << std::endl;
186 
187     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
188 
189     VerifyGraphVisitBlocks(file);
190 
191     g_impl->closeFile(file);
192     ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
193 }
194 
195 }  // namespace libabckit::test
196