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 <gtest/gtest.h>
17 #include <unordered_map>
18 #include <fstream>
19
20 #include "libabckit/include/c/abckit.h"
21 #include "adapter_static/ir_static.h"
22 #include "libabckit/include/c/statuses.h"
23 #include "libabckit/include/c/metadata_core.h"
24 #include "helpers/helpers.h"
25 #include "helpers/helpers_runtime.h"
26
27 namespace libabckit::test {
28
29 static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
30 static auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
31 static auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32 static auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33 static auto g_statG = AbckitGetIsaApiStaticImpl(ABCKIT_VERSION_RELEASE_1_0_0);
34 static auto g_dynG = AbckitGetIsaApiDynamicImpl(ABCKIT_VERSION_RELEASE_1_0_0);
35
36 static constexpr auto EXPECTED =
37 "Method: Lgraph_dynamic;::func_main_0 0x[a-f0-9]+\n\n"
38 "BB 1\n"
39 "prop: start, bc: 0x[a-f0-9]+\n"
40 "hotness=0\n"
41 "\\s+0.any Parameter\\s+arg 0\\s+\n"
42 "r8187 -> r8187 \\[u64\\]\n"
43 "\\s+1.any Parameter\\s+arg 1\\s+\n"
44 "r8188 -> r8188 \\[u64\\]\n"
45 "\\s+2.any Parameter\\s+arg 2\\s+\n"
46 "r8189 -> r8189 \\[u64\\]\n"
47 "\\s+12.i32 Constant\\s+0x0 -> \\(v13\\)\\s+\n"
48 "\\s+18.i32 Constant\\s+0x1 -> \\(v19\\)\\s+\n"
49 "\\s+22.i32 Constant\\s+0x4 -> \\(v26\\)\\s+\n"
50 "\\s+23.i32 Constant\\s+0x5 -> \\(v26\\)\\s+\n"
51 "\\s+24.i32 Constant\\s+0x6 -> \\(v26\\)\\s+\n"
52 "\\s+25.i32 Constant\\s+0x7 -> \\(v26\\)\\s+\n"
53 "succs: \\[bb 0\\]\n\n"
54 "BB 0 preds: \\[bb 1\\]\n"
55 "prop: bc: 0x[a-f0-9]+\n"
56 "hotness=0\n"
57 "\\s+3.any Intrinsic.definefunc\\s+0x[a-f0-9]+, 0x[a-f0-9]+, 0x1 \\(v21\\)\\s+bc: 0x[a-f0-9]+\n"
58 "\\s+4.any Intrinsic.definefunc\\s+0x[a-f0-9]+, 0x[a-f0-9]+, 0x5 \\(v26\\)\\s+bc: 0x[a-f0-9]+\n"
59 "\\s+5.any Intrinsic.ldhole\\s+\\(v6\\)\\s+bc: 0x[a-f0-9]+\n"
60 "\\s+6.any Intrinsic.defineclasswithbuffer 0x[a-f0-9]+, 0x[a-f0-9]+, "
61 // CC-OFFNXT(WordsTool.190)
62 "0x[a-f0-9]+, 0x[a-f0-9]+ v5 -> \\(v8, v7\\)\\s+bc: 0x[a-f0-9]+\n"
63 "\\s+7.any Intrinsic.ldobjbyname\\s+0x[a-f0-9]+, 0x[a-f0-9]+ v6\\s+bc: 0x[a-f0-9]+\n"
64 "\\s+8.any Intrinsic.newobjrange\\s+0x5, 0x[a-f0-9]+ v6 -> "
65 "\\(v21, v17, v16, v11, v10\\)\\s+bc: 0x[a-f0-9]+\n"
66 "\\s+9.any Intrinsic.tryldglobalbyname 0x[a-f0-9]+, 0x[a-f0-9]+ \\(v14\\)\\s+bc: 0x[a-f0-9]+\n"
67 // CC-OFFNXT(WordsTool.190)
68 "\\s+10.any Intrinsic.ldobjbyname\\s+0x[a-f0-9]+, 0x[a-f0-9]+ v8 -> \\(v11\\)\\s+bc: 0x[a-f0-9]+\n"
69 // CC-OFFNXT(WordsTool.190)
70 "\\s+11.any Intrinsic.callthis0\\s+0x[a-f0-9]+ v10, v8 -> \\(v13\\)\\s+bc: 0x[a-f0-9]+\n"
71 "\\s+13.any Intrinsic.ldobjbyvalue\\s+0x[a-f0-9]+ v12, v11 -> \\(v14\\)\\s+bc: 0x[a-f0-9]+\n"
72 "\\s+14.any Intrinsic.callarg1\\s+0x[a-f0-9]+ v9, v13\\s+bc: 0x[a-f0-9]+\n"
73 "\\s+15.any Intrinsic.tryldglobalbyname 0x[a-f0-9]+, 0x[a-f0-9]+ \\(v20\\)\\s+bc: 0x[a-f0-9]+\n"
74 // CC-OFFNXT(WordsTool.190)
75 "\\s+16.any Intrinsic.ldobjbyname\\s+0x[a-f0-9]+, 0x[a-f0-9]+ v8 -> \\(v17\\)\\s+bc: 0x[a-f0-9]+\n"
76 // CC-OFFNXT(WordsTool.190)
77 "\\s+17.any Intrinsic.callthis0\\s+0x[a-f0-9]+ v16, v8 -> \\(v19\\)\\s+bc: 0x[a-f0-9]+\n"
78 "\\s+19.any Intrinsic.ldobjbyvalue\\s+0x[a-f0-9]+ v18, v17 -> \\(v20\\)\\s+bc: 0x[a-f0-9]+\n"
79 "\\s+20.any Intrinsic.callarg1\\s+0x[a-f0-9]+ v15, v19\\s+bc: 0x[a-f0-9]+\n"
80 // CC-OFFNXT(WordsTool.190)
81 "\\s+21.any Intrinsic.callarg1\\s+0x[a-f0-9]+ v3, v8\\s+bc: 0x[a-f0-9]+\n"
82 "\\s+26.any Intrinsic.callrange\\s+0x[a-f0-9]+, 0x4 v4, v22, v23, v24, v25\\s+bc: 0x[a-f0-9]+\n"
83 "\\s+27.void Intrinsic.returnundefined\\s+bc: 0x[a-f0-9]+\n"
84 "succs: \\[bb 2\\]\n\n"
85 "BB 2 preds: \\[bb 0\\]\n"
86 "prop: end, bc: 0x[a-f0-9]+\n"
87 "hotness=0\n\n\n";
88
89 class LibAbcKitIrGraphTest : public ::testing::Test {};
90
91 // Test: test-kind=api, api=GraphApiImpl::gDump, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitIrGraphTest,Gdump_1)92 TEST_F(LibAbcKitIrGraphTest, Gdump_1)
93 {
94 auto cb = [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
95 auto fileName = ABCKIT_ABC_DIR "ut/ir_core/graph/tmpGD.txt";
96 std::FILE *fp = fopen(fileName, "we");
97 ASSERT_NE(fp, nullptr);
98 g_implG->gDump(graph, fileno(fp));
99 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
100 ASSERT_EQ(fclose(fp), 0);
101 std::ifstream tmpFile(fileName);
102 std::string line;
103 std::stringstream ss;
104 ASSERT_TRUE(tmpFile.is_open());
105 while (tmpFile.good()) {
106 getline(tmpFile, line);
107 ss << line << std::endl;
108 }
109 // CC-OFFNXT(G.FMT.02)
110 tmpFile.close();
111 std::remove(fileName);
112
113 EXPECT_TRUE(helpers::Match(ss.str(), EXPECTED));
114 };
115 helpers::InspectMethod(ABCKIT_ABC_DIR "ut/ir_core/graph/graph_dynamic.abc", "func_main_0", cb);
116 }
117
118 // Test: test-kind=api, api=GraphApiImpl::gDump, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitIrGraphTest,Gdump_2)119 TEST_F(LibAbcKitIrGraphTest, Gdump_2)
120 {
121 helpers::InspectMethod(
122 ABCKIT_ABC_DIR "ut/ir_core/graph/graph_static.abc", "main",
123 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
124 auto fileName = ABCKIT_ABC_DIR "ut/ir_core/graph/tmpGS.txt";
125 std::FILE *fp = fopen(fileName, "we");
126 ASSERT_NE(fp, nullptr);
127 g_implG->gDump(graph, fileno(fp));
128 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
129 ASSERT_EQ(fclose(fp), 0);
130 std::ifstream tmpFile(fileName);
131 std::string line;
132 std::stringstream ss;
133 ASSERT_TRUE(tmpFile.is_open());
134 while (tmpFile.good()) {
135 getline(tmpFile, line);
136 ss << line << std::endl;
137 }
138 tmpFile.close();
139 std::remove(fileName);
140 auto expected =
141 "Method: graph_static.ETSGLOBAL::main 0x[a-f0-9]+\n\n"
142 "BB 1\n"
143 "prop: start, bc: 0x[a-f0-9]+\n"
144 "hotness=0\n"
145 "\\s+2.i32 Constant\\s+0x1 -> \\(v3\\)\\s+\n"
146 "succs: \\[bb 0\\]\n\n"
147 "BB 0 preds: \\[bb 1\\]\n"
148 "prop: bc: 0x[a-f0-9]+\n"
149 "hotness=0\n"
150 "\\s+0.ref Intrinsic.AbckitInitObjectShort 0x[a-f0-9]+ \\(v7, v3, v1\\)\\s+bc: 0x[a-f0-9]+\n"
151 "\\s+1.void CallVirtual [a-f0-9]+ graph_static.Test::test v0\\s+bc: 0x[a-f0-9]+\n"
152 "\\s+3.i32 CallVirtual [a-f0-9]+ graph_static.Test::test2 v0, v2\\s+bc: 0x[a-f0-9]+\n"
153 "\\s+4.void CallStatic [a-f0-9]+ graph_static.ETSGLOBAL::test0\\s+bc: 0x[a-f0-9]+\n"
154 "\\s+5.ref Intrinsic.AbckitLoadString\\s+0x[a-f0-9]+ \\(v6\\)\\s+bc: 0x[a-f0-9]+\n"
155 "\\s+6.void CallStatic [a-f0-9]+ graph_static.ETSGLOBAL::test1 v5\\s+bc: 0x[a-f0-9]+\n"
156 "\\s+7.void CallVirtual [a-f0-9]+ graph_static.Test::test2 v0\\s+bc: 0x[a-f0-9]+\n"
157 "\\s+8.void ReturnVoid\\s+bc: 0x[a-f0-9]+\n"
158 "succs: \\[bb 2\\]\n\n"
159 "BB 2 preds: \\[bb 0\\]\n"
160 "prop: end, bc: 0x[a-f0-9]+\n"
161 "hotness=0\n\n\n";
162 EXPECT_TRUE(helpers::Match(ss.str(), expected));
163 });
164 }
165
166 // Test: test-kind=api, api=GraphApiImpl::gGetFile, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitIrGraphTest,GgetFile_1)167 TEST_F(LibAbcKitIrGraphTest, GgetFile_1)
168 {
169 helpers::InspectMethod(ABCKIT_ABC_DIR "ut/ir_core/graph/graph_dynamic.abc", "func_main_0",
170 [](AbckitFile *file, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
171 auto f = g_implG->gGetFile(graph);
172 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
173 ASSERT_EQ(f, file);
174 });
175 }
176
177 // Test: test-kind=api, api=GraphApiImpl::gGetFile, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitIrGraphTest,GgetFile_2)178 TEST_F(LibAbcKitIrGraphTest, GgetFile_2)
179 {
180 helpers::InspectMethod(ABCKIT_ABC_DIR "ut/ir_core/graph/graph_static.abc", "main",
181 [](AbckitFile *file, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
182 auto f = g_implG->gGetFile(graph);
183 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
184 ASSERT_EQ(f, file);
185 });
186 }
187
188 // Test: test-kind=api, api=GraphApiImpl::gGetIsa, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitIrGraphTest,GgetIsa_1)189 TEST_F(LibAbcKitIrGraphTest, GgetIsa_1)
190 {
191 helpers::InspectMethod(ABCKIT_ABC_DIR "ut/ir_core/graph/graph_dynamic.abc", "func_main_0",
192 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
193 auto isa = g_implG->gGetIsa(graph);
194 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
195 ASSERT_EQ(isa, AbckitIsaType::ABCKIT_ISA_TYPE_DYNAMIC);
196 });
197 }
198
199 // Test: test-kind=api, api=GraphApiImpl::gGetIsa, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitIrGraphTest,GgetIsa_2)200 TEST_F(LibAbcKitIrGraphTest, GgetIsa_2)
201 {
202 helpers::InspectMethod(ABCKIT_ABC_DIR "ut/ir_core/graph/graph_static.abc", "main",
203 [](AbckitFile * /*file*/, AbckitCoreFunction * /*method*/, AbckitGraph *graph) {
204 auto isa = g_implG->gGetIsa(graph);
205 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
206 ASSERT_EQ(isa, AbckitIsaType::ABCKIT_ISA_TYPE_STATIC);
207 });
208 }
209 } // namespace libabckit::test
210