• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 "bytecodeopt_peepholes.h"
17 #include "common.h"
18 #include "compiler/optimizer/optimizations/cleanup.h"
19 
20 namespace ark::bytecodeopt::test {
21 
22 // NOLINTBEGIN(readability-magic-numbers)
23 
TEST_F(IrBuilderTest,PeepholesTryBlockInstBetween)24 TEST_F(IrBuilderTest, PeepholesTryBlockInstBetween)
25 {
26     auto source = R"(
27     .record E {}
28     .record R {
29         u1 field
30     }
31 
32     .function void R.ctor(R a0) <ctor> {
33         newobj v0, E
34         throw v0
35     }
36 
37     .function u8 main() {
38     try_begin:
39         movi v1, 0x1
40         newobj v0, R
41         movi v1, 0x2
42         call.short R.ctor, v0
43     try_end:
44         ldai 0x0
45         return
46     catch_all:
47         lda v1
48         return
49     .catchall try_begin, try_end, catch_all
50     }
51     )";
52     ASSERT_TRUE(ParseToGraph(source, "main"));
53 
54     EXPECT_FALSE(GetGraph()->RunPass<BytecodeOptPeepholes>());
55 }
56 
TEST_F(IrBuilderTest,PeepholesTryBlockNoInstBetween)57 TEST_F(IrBuilderTest, PeepholesTryBlockNoInstBetween)
58 {
59     auto source = R"(
60     .record E {}
61     .record R {
62         u1 field
63     }
64 
65     .function void R.ctor(R a0) <ctor> {
66         newobj v0, E
67         throw v0
68     }
69 
70     .function u8 main() {
71     try_begin:
72         movi v1, 0x1
73         newobj v0, R
74         call.short R.ctor, v0
75     try_end:
76         ldai 0x0
77         return
78     catch_all:
79         lda v1
80         return
81     .catchall try_begin, try_end, catch_all
82     }
83     )";
84     ASSERT_TRUE(ParseToGraph(source, "main"));
85 
86     EXPECT_TRUE(GetGraph()->RunPass<BytecodeOptPeepholes>());
87 }
88 
89 // NOTE(aromanov): enable
TEST_F(CommonTest,DISABLED_NoNullCheck)90 TEST_F(CommonTest, DISABLED_NoNullCheck)
91 {
92     RuntimeInterfaceMock runtime(0U);
93     auto graph = CreateEmptyGraph();
94     graph->SetRuntime(&runtime);
95     GRAPH(graph)
96     {
97         // NOLINTNEXTLINE(google-build-using-namespace)
98         using namespace compiler::DataType;
99         CONSTANT(6U, 0U);
100         BASIC_BLOCK(2U, -1L)
101         {
102             INST(0U, Opcode::SaveState).NoVregs();
103             INST(1U, Opcode::LoadAndInitClass).ref().Inputs(0U).TypeId(68U);
104             INST(2U, Opcode::NewObject).ref().Inputs(1U, 0U).TypeId(68U);
105             INST(3U, Opcode::SaveState).NoVregs();
106             INST(5U, Opcode::CallStatic).v0id().Inputs({{REFERENCE, 2U}, {NO_TYPE, 3U}});
107             INST(7U, Opcode::Return).s32().Inputs(6U);
108         }
109     }
110 
111     EXPECT_TRUE(graph->RunPass<BytecodeOptPeepholes>());
112     EXPECT_TRUE(graph->RunPass<compiler::Cleanup>());
113 
114     auto after = CreateEmptyGraph();
115     GRAPH(after)
116     {
117         // NOLINTNEXTLINE(google-build-using-namespace)
118         using namespace compiler::DataType;
119         CONSTANT(6U, 0U);
120         BASIC_BLOCK(2U, -1L)
121         {
122             INST(0U, Opcode::SaveState).NoVregs();
123             INST(1U, Opcode::LoadAndInitClass).ref().Inputs(0U).TypeId(68U);
124             INST(3U, Opcode::SaveState).NoVregs();
125             INST(8U, Opcode::InitObject).ref().Inputs({{REFERENCE, 1U}, {NO_TYPE, 3U}});
126             INST(7U, Opcode::Return).s32().Inputs(6U);
127         }
128     }
129 
130     EXPECT_TRUE(GraphComparator().Compare(graph, after));
131 }
132 
133 // NOTE(aromanov): enable
TEST_F(CommonTest,DISABLED_NotRelatedNullCheck)134 TEST_F(CommonTest, DISABLED_NotRelatedNullCheck)
135 {
136     RuntimeInterfaceMock runtime(1U);
137     auto graph = CreateEmptyGraph();
138     graph->SetRuntime(&runtime);
139     GRAPH(graph)
140     {
141         // NOLINTNEXTLINE(google-build-using-namespace)
142         using namespace compiler::DataType;
143         PARAMETER(10U, 0U).ref();
144         CONSTANT(6U, 0U);
145         BASIC_BLOCK(2U, -1L)
146         {
147             INST(0U, Opcode::SaveState).NoVregs();
148             INST(1U, Opcode::LoadAndInitClass).ref().Inputs(0U);
149             INST(2U, Opcode::NewObject).ref().Inputs(1U, 0U);
150             INST(3U, Opcode::SaveState).NoVregs();
151             INST(4U, Opcode::NullCheck).ref().Inputs(10U, 3U);
152             INST(5U, Opcode::CallStatic).v0id().Inputs({{REFERENCE, 2U}, {NO_TYPE, 3U}});
153             INST(7U, Opcode::Return).s32().Inputs(6U);
154         }
155     }
156 
157     EXPECT_FALSE(graph->RunPass<BytecodeOptPeepholes>());
158 }
159 
TEST_F(CommonTest,CallStaticOtherBasicBlock)160 TEST_F(CommonTest, CallStaticOtherBasicBlock)
161 {
162     RuntimeInterfaceMock runtime(1U);
163     auto graph = CreateEmptyGraph();
164     graph->SetRuntime(&runtime);
165     GRAPH(graph)
166     {
167         // NOLINTNEXTLINE(google-build-using-namespace)
168         using namespace compiler::DataType;
169         PARAMETER(10U, 0U).ref();
170         CONSTANT(6U, 0U);
171         BASIC_BLOCK(2U, 3U)
172         {
173             INST(0U, Opcode::SaveState).NoVregs();
174             INST(1U, Opcode::LoadAndInitClass).ref().Inputs(0U);
175             INST(2U, Opcode::NewObject).ref().Inputs(1U, 0U);
176             INST(3U, Opcode::SaveState).NoVregs();
177         }
178         BASIC_BLOCK(3U, -1L)
179         {
180             INST(5U, Opcode::CallStatic).v0id().Inputs({{REFERENCE, 2U}, {NO_TYPE, 3U}});
181             INST(7U, Opcode::Return).s32().Inputs(6U);
182         }
183     }
184 
185     EXPECT_FALSE(graph->RunPass<BytecodeOptPeepholes>());
186 }
187 
188 // NOTE(aromanov): enable
TEST_F(CommonTest,DISABLED_NoSaveStateNullCheckAfterNewObject)189 TEST_F(CommonTest, DISABLED_NoSaveStateNullCheckAfterNewObject)
190 {
191     RuntimeInterfaceMock runtime(0U);
192     auto graph = CreateEmptyGraph();
193     graph->SetRuntime(&runtime);
194     GRAPH(graph)
195     {
196         // NOLINTNEXTLINE(google-build-using-namespace)
197         using namespace compiler::DataType;
198         BASIC_BLOCK(2U, -1L)
199         {
200             INST(0U, Opcode::SaveState).NoVregs();
201             INST(1U, Opcode::LoadAndInitClass).ref().Inputs(0U);
202             INST(2U, Opcode::NewObject).ref().Inputs(1U, 0U);
203             CONSTANT(3U, 0U).s32();
204             INST(4U, Opcode::SaveState).NoVregs();
205             INST(5U, Opcode::CallStatic).v0id().Inputs({{REFERENCE, 2U}, {NO_TYPE, 4U}});
206             INST(6U, Opcode::ReturnVoid).v0id();
207         }
208     }
209 
210     EXPECT_FALSE(graph->RunPass<BytecodeOptPeepholes>());
211 }
212 
TEST_F(CommonTest,CallConstructorOtherClass)213 TEST_F(CommonTest, CallConstructorOtherClass)
214 {
215     RuntimeInterfaceMock runtime(1U, false);
216     auto graph = CreateEmptyGraph();
217     graph->SetRuntime(&runtime);
218     GRAPH(graph)
219     {
220         // NOLINTNEXTLINE(google-build-using-namespace)
221         using namespace compiler::DataType;
222         PARAMETER(10U, 0U).ref();
223         CONSTANT(6U, 0U);
224         BASIC_BLOCK(2U, -1L)
225         {
226             INST(0U, Opcode::SaveState).NoVregs();
227             INST(1U, Opcode::LoadAndInitClass).ref().Inputs(0U);
228             INST(2U, Opcode::NewObject).ref().Inputs(1U, 0U);
229             INST(3U, Opcode::SaveState).NoVregs();
230             INST(5U, Opcode::CallStatic).v0id().Inputs({{REFERENCE, 2U}, {NO_TYPE, 3U}});
231             INST(7U, Opcode::Return).s32().Inputs(6U);
232         }
233     }
234 
235     EXPECT_FALSE(graph->RunPass<BytecodeOptPeepholes>());
236 }
237 
238 // NOLINTEND(readability-magic-numbers)
239 
240 }  // namespace ark::bytecodeopt::test
241