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/abckit.h"
17 #include "libabckit/include/c/metadata_core.h"
18 #include "libabckit/include/c/ir_core.h"
19
20 #include "helpers/helpers_runtime.h"
21 #include "helpers/helpers.h"
22 #include "libabckit/src/logger.h"
23 #include <gtest/gtest.h>
24
25 // NOLINTBEGIN(readability-magic-numbers)
26
27 namespace libabckit::test {
28
29 namespace {
30
31 auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32 auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33 auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
34 auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
35 auto g_dynG = AbckitGetIsaApiDynamicImpl(ABCKIT_VERSION_RELEASE_1_0_0);
36 auto g_statG = AbckitGetIsaApiStaticImpl(ABCKIT_VERSION_RELEASE_1_0_0);
37
CreateLoopDynamic(AbckitGraph * graph,AbckitFile * file)38 void CreateLoopDynamic(AbckitGraph *graph, AbckitFile *file)
39 {
40 AbckitBasicBlock *startBB = g_implG->gGetStartBasicBlock(graph);
41 std::vector<AbckitBasicBlock *> succBBs = helpers::BBgetSuccBlocks(startBB);
42 AbckitBasicBlock *endBB = g_implG->gGetEndBasicBlock(graph);
43
44 AbckitInst *forConst = g_implG->gFindOrCreateConstantU64(graph, 0xa);
45 AbckitInst *zero = g_implG->gFindOrCreateConstantU64(graph, 0x0);
46 AbckitInst *forStep = g_implG->gFindOrCreateConstantU64(graph, 0x2);
47
48 g_implG->bbAddInstBack(startBB, forConst);
49 g_implG->bbAddInstBack(startBB, zero);
50 g_implG->bbAddInstBack(startBB, forStep);
51 g_implG->bbDisconnectSuccBlock(startBB, 0);
52
53 AbckitBasicBlock *forBB = g_implG->bbCreateEmpty(graph);
54 g_implG->bbAppendSuccBlock(startBB, forBB);
55
56 AbckitInst *phi = g_implG->bbCreatePhi(forBB, 1, zero);
57
58 AbckitInst *intrinsicLess = g_dynG->iCreateLess(graph, phi, forConst);
59 g_implG->bbAddInstBack(forBB, intrinsicLess);
60
61 AbckitInst *ifInst = g_dynG->iCreateIf(graph, intrinsicLess, ABCKIT_ISA_API_DYNAMIC_CONDITION_CODE_CC_NE);
62 g_implG->bbAddInstBack(forBB, ifInst);
63
64 AbckitBasicBlock *trueBB = g_implG->bbCreateEmpty(graph);
65 AbckitInst *add = g_dynG->iCreateAdd2(graph, phi, forStep);
66
67 g_implG->bbAddInstBack(trueBB, add);
68 g_implG->iAppendInput(phi, add);
69
70 auto *print = g_dynG->iCreateTryldglobalbyname(graph, g_implM->createString(file, "print", strlen("print")));
71 g_implG->bbAddInstBack(trueBB, print);
72 auto *call = g_dynG->iCreateCallarg1(graph, print, phi);
73 g_implG->bbAddInstBack(trueBB, call);
74 g_implG->bbAppendSuccBlock(forBB, trueBB);
75
76 AbckitBasicBlock *retBB = g_implG->bbCreateEmpty(graph);
77 g_implG->bbAppendSuccBlock(forBB, retBB);
78 g_implG->bbAppendSuccBlock(trueBB, forBB);
79 g_implG->bbAppendSuccBlock(retBB, endBB);
80
81 AbckitInst *ret = g_dynG->iCreateReturnundefined(graph);
82
83 g_implG->bbAddInstBack(retBB, ret);
84 }
85
CreateLoopStatic(AbckitGraph * graph,AbckitCoreFunction * consoleLogInt)86 void CreateLoopStatic(AbckitGraph *graph, AbckitCoreFunction *consoleLogInt)
87 {
88 AbckitBasicBlock *startBB = g_implG->gGetStartBasicBlock(graph);
89 std::vector<AbckitBasicBlock *> succBBs = helpers::BBgetSuccBlocks(startBB);
90 AbckitBasicBlock *endBB = g_implG->gGetEndBasicBlock(graph);
91
92 AbckitInst *forConst = g_implG->gFindOrCreateConstantU64(graph, 0xa);
93 AbckitInst *zero = g_implG->gFindOrCreateConstantU64(graph, 0x0);
94 AbckitInst *forStep = g_implG->gFindOrCreateConstantU64(graph, 0x1);
95
96 g_implG->bbAddInstBack(startBB, forConst);
97 g_implG->bbAddInstBack(startBB, zero);
98 g_implG->bbAddInstBack(startBB, forStep);
99
100 g_implG->bbDisconnectSuccBlock(startBB, 0);
101
102 AbckitBasicBlock *forBB = g_implG->bbCreateEmpty(graph);
103 g_implG->bbAppendSuccBlock(startBB, forBB);
104
105 AbckitInst *phi = g_implG->bbCreatePhi(forBB, 1, zero);
106
107 AbckitInst *ifInst = g_statG->iCreateIf(graph, phi, forConst, ABCKIT_ISA_API_STATIC_CONDITION_CODE_CC_LT);
108 g_implG->bbAddInstBack(forBB, ifInst);
109
110 AbckitBasicBlock *trueBB = g_implG->bbCreateEmpty(graph);
111 AbckitInst *add = g_statG->iCreateAdd(graph, phi, forStep);
112
113 g_implG->bbAddInstBack(trueBB, add);
114 g_implG->iAppendInput(phi, add);
115
116 AbckitInst *callLogInt = g_statG->iCreateCallStatic(graph, consoleLogInt, 1, phi);
117 g_implG->bbAddInstBack(trueBB, callLogInt);
118
119 g_implG->bbAppendSuccBlock(forBB, trueBB);
120
121 AbckitBasicBlock *retBB = g_implG->bbCreateEmpty(graph);
122 g_implG->bbAppendSuccBlock(forBB, retBB);
123 g_implG->bbAppendSuccBlock(trueBB, forBB);
124 g_implG->bbAppendSuccBlock(retBB, endBB);
125
126 AbckitInst *ret = g_statG->iCreateReturnVoid(graph);
127 g_implG->bbAddInstBack(retBB, ret);
128 }
129
130 } // namespace
131
132 class LibAbcKitLoopStaticTest : public ::testing::Test {};
133
134 // Test: test-kind=api, api=GraphApiImpl::bbCreatePhi, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitLoopStaticTest,LibAbcKitLoopTestStatic)135 TEST_F(LibAbcKitLoopStaticTest, LibAbcKitLoopTestStatic)
136 {
137 auto output =
138 helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/ir_core/loops/loop_static.abc", "loop_static/ETSGLOBAL", "main");
139 helpers::TransformMethod(
140 ABCKIT_ABC_DIR "ut/ir_core/loops/loop_static.abc", ABCKIT_ABC_DIR "ut/ir_core/loops/loop_static_modified.abc",
141 "bar",
142 [](AbckitFile * /*file*/, AbckitCoreFunction *method, AbckitGraph *graph) {
143 auto *consoleLogInt = helpers::FindMethodByName(g_implI->functionGetFile(method), "console_log_int");
144 CreateLoopStatic(graph, consoleLogInt);
145 },
146 []([[maybe_unused]] AbckitGraph *graph) {});
147 output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/ir_core/loops/loop_static_modified.abc",
148 "loop_static/ETSGLOBAL", "main");
149 }
150
151 // Test: test-kind=api, api=GraphApiImpl::bbCreatePhi, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitLoopStaticTest,LibAbcKitLoopDynamic)152 TEST_F(LibAbcKitLoopStaticTest, LibAbcKitLoopDynamic)
153 {
154 auto output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "ut/ir_core/loops/loop_dynamic.abc", "loop_dynamic");
155 helpers::TransformMethod(
156 ABCKIT_ABC_DIR "ut/ir_core/loops/loop_dynamic.abc", ABCKIT_ABC_DIR "ut/ir_core/loops/loop_dynamic_modified.abc",
157 "bar", [&](AbckitFile *file, AbckitCoreFunction *, AbckitGraph *graph) { CreateLoopDynamic(graph, file); },
158 [&]([[maybe_unused]] AbckitGraph *graph) {});
159
160 output = helpers::ExecuteDynamicAbc(ABCKIT_ABC_DIR "ut/ir_core/loops/loop_dynamic_modified.abc", "loop_dynamic");
161 }
162
163 } // namespace libabckit::test
164
165 // NOLINTEND(readability-magic-numbers)
166