• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 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 "common.h"
17 #include "const_array_resolver.h"
18 
19 namespace panda::bytecodeopt::test {
20 
TEST_F(CommonTest,ConstArrayResolverInt64)21 TEST_F(CommonTest, ConstArrayResolverInt64)
22 {
23     auto graph = CreateEmptyGraph();
24     GRAPH(graph)
25     {
26         CONSTANT(1, 2).s64();
27         CONSTANT(2, 0).s64();
28 
29         BASIC_BLOCK(2, -1)
30         {
31             INST(20, Opcode::SaveState).NoVregs();
32             INST(4, Opcode::LoadAndInitClass).ref().Inputs(20).TypeId(68);
33             INST(3, Opcode::NewArray).ref().Inputs(4, 1, 20);
34             INST(11, Opcode::StoreArray).u64().Inputs(3, 2, 2);
35             INST(13, Opcode::StoreArray).u64().Inputs(3, 2, 2);
36             INST(10, Opcode::Return).ref().Inputs(3);
37         }
38     }
39 
40     pandasm::Program program;
41     pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps;
42     maps.classes.emplace(0, "i64[]");
43     IrInterfaceTest interface(&program, &maps);
44     options.SetConstArrayResolver(true);
45     EXPECT_TRUE(graph->RunPass<ConstArrayResolver>(&interface));
46     auto expected = CreateEmptyGraph();
47     GRAPH(expected)
48     {
49         CONSTANT(1, 2).s64();
50         CONSTANT(2, 0).s64();
51 
52         BASIC_BLOCK(2, -1)
53         {
54             INST(20, Opcode::SaveState).NoVregs();
55             INST(4, Opcode::LoadAndInitClass).ref().Inputs(20).TypeId(68);
56             INST(22, Opcode::SaveState).NoVregs();
57             INST(21, Opcode::LoadConstArray).ref().Inputs(22);
58             INST(10, Opcode::Return).ref().Inputs(21);
59         }
60     }
61     EXPECT_TRUE(GraphComparator().Compare(graph, expected));
62 }
63 
TEST_F(CommonTest,ConstArrayResolverInt32)64 TEST_F(CommonTest, ConstArrayResolverInt32)
65 {
66     auto graph = CreateEmptyGraph();
67     GRAPH(graph)
68     {
69         CONSTANT(1, 2).s32();
70         CONSTANT(2, 0).s32();
71 
72         BASIC_BLOCK(2, -1)
73         {
74             INST(20, Opcode::SaveState).NoVregs();
75             INST(4, Opcode::LoadAndInitClass).ref().Inputs(20).TypeId(68);
76             INST(3, Opcode::NewArray).ref().Inputs(4, 1, 20);
77             INST(11, Opcode::StoreArray).u32().Inputs(3, 2, 2);
78             INST(13, Opcode::StoreArray).u32().Inputs(3, 2, 2);
79             INST(10, Opcode::Return).ref().Inputs(3);
80         }
81     }
82 
83     pandasm::Program program;
84     pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps;
85     maps.classes.emplace(0, "i32[]");
86     IrInterfaceTest interface(&program, &maps);
87     options.SetConstArrayResolver(true);
88     EXPECT_TRUE(graph->RunPass<ConstArrayResolver>(&interface));
89 }
90 
TEST_F(CommonTest,ConstArrayResolverFloat32)91 TEST_F(CommonTest, ConstArrayResolverFloat32)
92 {
93     auto graph = CreateEmptyGraph();
94     GRAPH(graph)
95     {
96         CONSTANT(0, 3).s32();
97         CONSTANT(4, 0).s32();
98         CONSTANT(6, 100).f64();
99         CONSTANT(10, 1).s32();
100         CONSTANT(13, 200).f64();
101         CONSTANT(16, 2).s32();
102         CONSTANT(20, 300).f64();
103 
104         BASIC_BLOCK(2, -1)
105         {
106             using namespace compiler::DataType;
107 
108             INST(3, Opcode::SaveState).NoVregs();
109             INST(44, Opcode::LoadAndInitClass).ref().Inputs(3).TypeId(68);
110             INST(5, Opcode::NewArray).ref().Inputs(44, 0, 3);
111             INST(12, Opcode::Cast).f32().SrcType(FLOAT64).Inputs(6);
112             INST(11, Opcode::StoreArray).f32().Inputs(5, 4, 12);
113             INST(19, Opcode::Cast).f32().SrcType(FLOAT64).Inputs(13);
114             INST(18, Opcode::StoreArray).f32().Inputs(5, 10, 19);
115             INST(26, Opcode::Cast).f32().SrcType(FLOAT64).Inputs(20);
116             INST(25, Opcode::StoreArray).f32().Inputs(5, 16, 26);
117             INST(27, Opcode::Return).ref().Inputs(5);
118         }
119     }
120 
121     pandasm::Program program;
122     pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps;
123     maps.classes.emplace(0, "f32[]");
124     IrInterfaceTest interface(&program, &maps);
125     options.SetConstArrayResolver(true);
126     EXPECT_TRUE(graph->RunPass<ConstArrayResolver>(&interface));
127 }
128 
TEST_F(CommonTest,ConstArrayResolverFloat64)129 TEST_F(CommonTest, ConstArrayResolverFloat64)
130 {
131     auto graph = CreateEmptyGraph();
132     GRAPH(graph)
133     {
134         CONSTANT(0, 0).s32();
135         CONSTANT(1, 1).s32();
136         CONSTANT(2, 2).s32();
137         CONSTANT(3, 100.0).f64();
138         CONSTANT(4, 200.0).f64();
139 
140         BASIC_BLOCK(2, -1)
141         {
142             INST(20, Opcode::SaveState).NoVregs();
143             INST(44, Opcode::LoadAndInitClass).ref().Inputs(20).TypeId(68);
144             INST(5, Opcode::NewArray).ref().Inputs(44, 2, 20);
145             INST(11, Opcode::StoreArray).f64().Inputs(5, 0, 3);
146             INST(13, Opcode::StoreArray).f64().Inputs(5, 1, 4);
147             INST(10, Opcode::Return).ref().Inputs(5);
148         }
149     }
150 
151     pandasm::Program program;
152     pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps;
153     maps.classes.emplace(0, "f64[]");
154     IrInterfaceTest interface(&program, &maps);
155     options.SetConstArrayResolver(true);
156     EXPECT_TRUE(graph->RunPass<ConstArrayResolver>(&interface));
157 }
158 
TEST_F(CommonTest,ConstArrayResolverByteAccess)159 TEST_F(CommonTest, ConstArrayResolverByteAccess)
160 {
161     auto graph = CreateEmptyGraph();
162     GRAPH(graph)
163     {
164         CONSTANT(0, 0).s32();
165         CONSTANT(1, 1).s32();
166         CONSTANT(2, 2).s32();
167         CONSTANT(3, 3).s32();
168 
169         BASIC_BLOCK(2, -1)
170         {
171             INST(4, Opcode::SaveState).NoVregs();
172             INST(44, Opcode::LoadAndInitClass).ref().Inputs(4).TypeId(68);
173             INST(5, Opcode::NewArray).ref().Inputs(44, 3, 4);
174             INST(6, Opcode::StoreArray).s8().Inputs(5, 0, 0);
175             INST(7, Opcode::StoreArray).s8().Inputs(5, 1, 1);
176             INST(8, Opcode::StoreArray).s8().Inputs(5, 2, 2);
177             INST(9, Opcode::Return).ref().Inputs(5);
178             ;
179         }
180     }
181 
182     pandasm::Program program;
183     pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps;
184     maps.classes.emplace(0, "i8[]");
185     IrInterfaceTest interface(&program, &maps);
186     options.SetConstArrayResolver(true);
187     EXPECT_TRUE(graph->RunPass<ConstArrayResolver>(&interface));
188 
189     auto expected = CreateEmptyGraph();
190     GRAPH(expected)
191     {
192         CONSTANT(0, 0).s32();
193         CONSTANT(1, 1).s32();
194         CONSTANT(2, 2).s32();
195         CONSTANT(3, 3).s32();
196 
197         BASIC_BLOCK(2, -1)
198         {
199             INST(4, Opcode::SaveState).NoVregs();
200             INST(44, Opcode::LoadAndInitClass).ref().Inputs(4).TypeId(68);
201             INST(11, Opcode::SaveState).NoVregs();
202             INST(10, Opcode::LoadConstArray).ref().Inputs(11);
203             INST(9, Opcode::Return).ref().Inputs(10);
204         }
205     }
206 
207     EXPECT_TRUE(GraphComparator().Compare(graph, expected));
208 }
209 
TEST_F(CommonTest,ConstArrayResolverStringAccess)210 TEST_F(CommonTest, ConstArrayResolverStringAccess)
211 {
212     auto graph = CreateEmptyGraph();
213     GRAPH(graph)
214     {
215         CONSTANT(0, 0).s32();
216         CONSTANT(1, 1).s32();
217         CONSTANT(2, 2).s32();
218         CONSTANT(3, 3).s32();
219 
220         BASIC_BLOCK(2, -1)
221         {
222             INST(4, Opcode::SaveState).NoVregs();
223             INST(44, Opcode::LoadAndInitClass).ref().Inputs(4).TypeId(68);
224             INST(5, Opcode::NewArray).ref().Inputs(44, 3, 4);
225 
226             INST(6, Opcode::SaveState).NoVregs();
227             INST(7, Opcode::LoadString).ref().Inputs(6);
228             INST(8, Opcode::StoreArray).ref().Inputs(5, 0, 7);
229 
230             INST(9, Opcode::SaveState).NoVregs();
231             INST(10, Opcode::LoadString).ref().Inputs(9);
232             INST(11, Opcode::StoreArray).ref().Inputs(5, 1, 10);
233 
234             INST(12, Opcode::SaveState).NoVregs();
235             INST(13, Opcode::LoadString).ref().Inputs(12);
236             INST(24, Opcode::StoreArray).ref().Inputs(5, 2, 13);
237 
238             INST(15, Opcode::Return).ref().Inputs(5);
239         }
240     }
241 
242     pandasm::Program program;
243     pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps;
244     maps.classes.emplace(0, "panda/String[]");
245     IrInterfaceTest interface(&program, &maps);
246     options.SetConstArrayResolver(true);
247     EXPECT_TRUE(graph->RunPass<ConstArrayResolver>(&interface));
248 
249     auto expected = CreateEmptyGraph();
250     GRAPH(expected)
251     {
252         CONSTANT(0, 0).s32();
253         CONSTANT(1, 1).s32();
254         CONSTANT(2, 2).s32();
255         CONSTANT(3, 3).s32();
256 
257         BASIC_BLOCK(2, -1)
258         {
259             INST(4, Opcode::SaveState).NoVregs();
260             INST(44, Opcode::LoadAndInitClass).ref().Inputs(4).TypeId(68);
261             INST(5, Opcode::SaveState).NoVregs();
262             INST(6, Opcode::LoadConstArray).ref().Inputs(5);
263 
264             INST(7, Opcode::SaveState).NoVregs();
265             INST(8, Opcode::LoadString).ref().Inputs(7);
266             INST(9, Opcode::SaveState).NoVregs();
267             INST(10, Opcode::LoadString).ref().Inputs(9);
268             INST(11, Opcode::SaveState).NoVregs();
269             INST(12, Opcode::LoadString).ref().Inputs(11);
270 
271             INST(13, Opcode::Return).ref().Inputs(6);
272         }
273     }
274 
275     EXPECT_TRUE(GraphComparator().Compare(graph, expected));
276 }
277 
TEST_F(CommonTest,ConstArrayResolverParameterAsArray)278 TEST_F(CommonTest, ConstArrayResolverParameterAsArray)
279 {
280     auto graph = CreateEmptyGraph();
281     GRAPH(graph)
282     {
283         PARAMETER(0, 0).ref();
284         CONSTANT(1, 0).s64();
285         CONSTANT(2, 0).s64();
286 
287         BASIC_BLOCK(2, -1)
288         {
289             INST(3, Opcode::LoadArray).u64().Inputs(0, 1);
290             INST(4, Opcode::Return).u64().Inputs(3);
291         }
292     }
293 
294     pandasm::Program program;
295     pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps;
296     maps.classes.emplace(0, "i64[]");
297     IrInterfaceTest interface(&program, &maps);
298     options.SetConstArrayResolver(true);
299     EXPECT_FALSE(graph->RunPass<ConstArrayResolver>(&interface));
300 }
301 
TEST_F(CommonTest,ConstArrayResolverDifferentBlocks)302 TEST_F(CommonTest, ConstArrayResolverDifferentBlocks)
303 {
304     auto graph = CreateEmptyGraph();
305     GRAPH(graph)
306     {
307         PARAMETER(0, 0).s32();
308         CONSTANT(1, 0).s64();
309         CONSTANT(2, 0).s64();
310 
311         BASIC_BLOCK(2, 3, 4)
312         {
313             INST(3, Opcode::SaveState);
314             INST(44, Opcode::LoadAndInitClass).ref().Inputs(3).TypeId(68);
315             INST(4, Opcode::NewArray).ref().Inputs(44, 1, 3);
316             INST(5, Opcode::IfImm).SrcType(compiler::DataType::INT32).CC(compiler::CC_EQ).Imm(0).Inputs(0);
317         }
318         BASIC_BLOCK(3, -1)
319         {
320             INST(6, Opcode::StoreArray).u64().Inputs(4, 1, 2);
321             INST(7, Opcode::Return).ref().Inputs(4);
322         }
323         BASIC_BLOCK(4, -1)
324         {
325             INST(8, Opcode::ReturnVoid).v0id();
326         }
327     }
328 
329     pandasm::Program program;
330     pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps;
331     maps.classes.emplace(0, "i64[]");
332     IrInterfaceTest interface(&program, &maps);
333     options.SetConstArrayResolver(true);
334     EXPECT_FALSE(graph->RunPass<ConstArrayResolver>(&interface));
335 }
336 
TEST_F(CommonTest,ConstArrayResolverArraySizeNotConstant)337 TEST_F(CommonTest, ConstArrayResolverArraySizeNotConstant)
338 {
339     auto graph = CreateEmptyGraph();
340     GRAPH(graph)
341     {
342         PARAMETER(0, 0).s64();
343         CONSTANT(4, 0).s64();
344         CONSTANT(5, 0).s64();
345 
346         BASIC_BLOCK(2, -1)
347         {
348             INST(1, Opcode::SaveState);
349             INST(44, Opcode::LoadAndInitClass).ref().Inputs(1).TypeId(68);
350             INST(2, Opcode::NewArray).ref().Inputs(44, 0, 1);
351             INST(3, Opcode::StoreArray).u64().Inputs(2, 4, 5);
352             INST(6, Opcode::ReturnVoid).v0id();
353         }
354     }
355 
356     pandasm::Program program;
357     pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps;
358     maps.classes.emplace(0, "i64[]");
359     IrInterfaceTest interface(&program, &maps);
360     options.SetConstArrayResolver(true);
361     EXPECT_FALSE(graph->RunPass<ConstArrayResolver>(&interface));
362 }
363 
364 }  // namespace panda::bytecodeopt::test
365