1 /*
2 * Copyright (c) 2021-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 "unit_test.h"
17
18 #include "optimizer/optimizations/scheduler.h"
19
20 namespace ark::compiler {
21 class SchedulerTest : public GraphTest {};
22
23 // NOLINTBEGIN(readability-magic-numbers)
TEST_F(SchedulerTest,Basic)24 TEST_F(SchedulerTest, Basic)
25 {
26 GRAPH(GetGraph())
27 {
28 CONSTANT(0U, 42U);
29 CONSTANT(1U, 43U);
30 CONSTANT(2U, 44U);
31 CONSTANT(3U, 45U);
32 CONSTANT(4U, 46U);
33 CONSTANT(5U, 47U);
34 CONSTANT(6U, 48U);
35 CONSTANT(7U, 49U);
36
37 BASIC_BLOCK(2U, -1L)
38 {
39 INST(8U, Opcode::Add).u64().Inputs(0U, 1U);
40 INST(9U, Opcode::Add).u64().Inputs(2U, 3U);
41 // should be moved down
42 INST(10U, Opcode::Add).u64().Inputs(8U, 9U);
43
44 INST(11U, Opcode::Add).u64().Inputs(4U, 5U);
45 INST(12U, Opcode::Add).u64().Inputs(6U, 7U);
46 INST(13U, Opcode::Add).u64().Inputs(11U, 12U);
47 // Grand total
48 INST(14U, Opcode::Add).u64().Inputs(10U, 13U);
49 INST(15U, Opcode::Return).u64().Inputs(14U);
50 }
51 }
52
53 ASSERT_TRUE(GetGraph()->RunPass<Scheduler>());
54
55 ASSERT_EQ(INS(8U).GetNext(), &INS(9U));
56 ASSERT_NE(INS(9U).GetNext(), &INS(10U));
57
58 EXPECT_TRUE((INS(11U).GetNext() == &INS(10U)) || (INS(12U).GetNext() == &INS(10U)));
59
60 ASSERT_EQ(INS(13U).GetNext(), &INS(14U));
61 ASSERT_EQ(INS(14U).GetNext(), &INS(15U));
62 }
63
TEST_F(SchedulerTest,LoadBarrier)64 TEST_F(SchedulerTest, LoadBarrier)
65 {
66 GRAPH(GetGraph())
67 {
68 PARAMETER(0U, 0U).s32(); // index
69 PARAMETER(1U, 1U).ref();
70 CONSTANT(2U, 42U);
71 CONSTANT(3U, 43U);
72 CONSTANT(4U, 44U);
73 CONSTANT(5U, 45U);
74 CONSTANT(6U, 46U);
75 CONSTANT(7U, 47U);
76 CONSTANT(8U, 48U);
77 CONSTANT(9U, 5U); // len array
78
79 BASIC_BLOCK(2U, -1L)
80 {
81 INST(10U, Opcode::Add).u64().Inputs(2U, 3U);
82 INST(11U, Opcode::Add).u64().Inputs(4U, 5U);
83 // should be moved down
84 INST(12U, Opcode::Add).u64().Inputs(10U, 11U);
85
86 INST(13U, Opcode::Add).u64().Inputs(6U, 7U);
87
88 INST(21U, Opcode::SafePoint).Inputs(0U, 1U).SrcVregs({0U, 1U});
89 INST(14U, Opcode::SaveState).Inputs(0U, 1U).SrcVregs({0U, 1U});
90 INST(15U, Opcode::BoundsCheck).s32().Inputs(9U, 0U, 14U);
91 // can't move up because of SafePoint
92 INST(16U, Opcode::LoadArray).u64().Inputs(1U, 15U);
93
94 INST(17U, Opcode::Add).u64().Inputs(8U, 16U);
95 INST(18U, Opcode::Add).u64().Inputs(13U, 17U);
96
97 INST(19U, Opcode::Add).u64().Inputs(12U, 18U);
98 INST(20U, Opcode::Return).u64().Inputs(19U);
99 }
100 }
101
102 ASSERT_TRUE(GetGraph()->RunPass<Scheduler>());
103
104 ASSERT_EQ(INS(11U).GetNext(), &INS(13U));
105 ASSERT_EQ(INS(13U).GetNext(), &INS(12U));
106 ASSERT_EQ(INS(12U).GetNext(), &INS(21U));
107 ASSERT_EQ(INS(21U).GetNext(), &INS(14U));
108 ASSERT_EQ(INS(15U).GetNext(), &INS(16U));
109 ASSERT_EQ(INS(16U).GetNext(), &INS(17U));
110 }
111
TEST_F(SchedulerTest,Load)112 TEST_F(SchedulerTest, Load)
113 {
114 GRAPH(GetGraph())
115 {
116 PARAMETER(0U, 0U).s32(); // index
117 PARAMETER(1U, 1U).ref();
118 CONSTANT(2U, 42U);
119 CONSTANT(3U, 43U);
120 CONSTANT(4U, 44U);
121 CONSTANT(5U, 45U);
122 CONSTANT(6U, 46U);
123 CONSTANT(7U, 47U);
124 CONSTANT(8U, 48U);
125 CONSTANT(9U, 5U); // len array
126
127 BASIC_BLOCK(2U, -1L)
128 {
129 INST(10U, Opcode::Add).u64().Inputs(2U, 3U);
130 INST(11U, Opcode::Add).u64().Inputs(4U, 5U);
131 // should be moved down
132 INST(12U, Opcode::Add).u64().Inputs(10U, 11U);
133
134 INST(13U, Opcode::Add).u64().Inputs(6U, 7U);
135
136 // all three should be moved up
137 INST(14U, Opcode::SaveState).Inputs(0U, 1U).SrcVregs({0U, 1U});
138 INST(15U, Opcode::BoundsCheck).s32().Inputs(9U, 0U, 14U);
139 INST(16U, Opcode::LoadArray).u64().Inputs(1U, 15U);
140
141 INST(17U, Opcode::Add).u64().Inputs(8U, 16U);
142 INST(18U, Opcode::Add).u64().Inputs(13U, 17U);
143
144 INST(19U, Opcode::Add).u64().Inputs(12U, 18U);
145 INST(20U, Opcode::Return).u64().Inputs(19U);
146 }
147 }
148
149 ASSERT_TRUE(GetGraph()->RunPass<Scheduler>());
150
151 ASSERT_EQ(INS(14U).GetNext(), &INS(10U));
152 ASSERT_EQ(INS(10U).GetNext(), &INS(15U));
153 ASSERT_EQ(INS(15U).GetNext(), &INS(11U));
154 ASSERT_EQ(INS(11U).GetNext(), &INS(16U));
155 ASSERT_EQ(INS(16U).GetNext(), &INS(13U));
156 ASSERT_EQ(INS(13U).GetNext(), &INS(12U));
157 ASSERT_EQ(INS(12U).GetNext(), &INS(17U));
158 ASSERT_EQ(INS(17U).GetNext(), &INS(18U));
159 ASSERT_EQ(INS(18U).GetNext(), &INS(19U));
160 ASSERT_EQ(INS(19U).GetNext(), &INS(20U));
161 }
162
TEST_F(SchedulerTest,FixSSInBBAfterScheduler)163 TEST_F(SchedulerTest, FixSSInBBAfterScheduler)
164 {
165 GRAPH(GetGraph())
166 {
167 CONSTANT(1U, 1U).s32();
168 CONSTANT(2U, 2U).s32();
169
170 BASIC_BLOCK(2U, -1L)
171 {
172 INST(4U, Opcode::SaveState).NoVregs();
173 INST(5U, Opcode::LoadAndInitClass).ref().Inputs(4U).TypeId(68U);
174 INST(6U, Opcode::SaveState).NoVregs();
175 INST(7U, Opcode::LoadConstArray).ref().Inputs(6U);
176 INST(8U, Opcode::Add).s32().Inputs(1U, 2U);
177 // LoadArray will move on one position down
178 INST(9U, Opcode::LoadArray).s32().Inputs(7U, 8U);
179 INST(10U, Opcode::SaveState).NoVregs();
180
181 INST(11U, Opcode::NOP);
182 INST(12U, Opcode::Return).s32().Inputs(9U);
183 }
184 }
185
186 ASSERT_TRUE(GetGraph()->RunPass<Scheduler>());
187
188 auto graph = CreateEmptyGraph();
189 GRAPH(graph)
190 {
191 CONSTANT(1U, 1U).s32();
192 CONSTANT(2U, 2U).s32();
193
194 BASIC_BLOCK(2U, -1L)
195 {
196 INST(4U, Opcode::SaveState).NoVregs();
197 INST(5U, Opcode::LoadAndInitClass).ref().Inputs(4U).TypeId(68U);
198 INST(6U, Opcode::SaveState).NoVregs();
199 INST(7U, Opcode::LoadConstArray).ref().Inputs(6U);
200 INST(8U, Opcode::Add).s32().Inputs(1U, 2U);
201
202 INST(10U, Opcode::SaveState).Inputs(7U).SrcVregs({VirtualRegister::BRIDGE});
203 INST(9U, Opcode::LoadArray).s32().Inputs(7U, 8U);
204
205 INST(11U, Opcode::NOP);
206 INST(12U, Opcode::Return).s32().Inputs(9U);
207 }
208 }
209
210 ASSERT_TRUE(GraphComparator().Compare(GetGraph(), graph));
211 }
212
SRC_GRAPH(FixSSInBBAfterSchedulerOutToBlock,Graph * graph)213 SRC_GRAPH(FixSSInBBAfterSchedulerOutToBlock, Graph *graph)
214 {
215 GRAPH(graph)
216 {
217 CONSTANT(1U, 1U).s32();
218 CONSTANT(2U, 2U).s32();
219
220 BASIC_BLOCK(2U, 3U)
221 {
222 INST(4U, Opcode::SaveState).NoVregs();
223 INST(5U, Opcode::LoadAndInitClass).ref().Inputs(4U).TypeId(68U);
224 INST(6U, Opcode::SaveState).NoVregs();
225 INST(7U, Opcode::LoadConstArray).ref().Inputs(6U);
226 }
227 BASIC_BLOCK(3U, -1L)
228 {
229 INST(8U, Opcode::Add).s32().Inputs(1U, 2U);
230 // LoadArray will move on one position down
231 INST(9U, Opcode::LoadArray).s32().Inputs(7U, 8U);
232 INST(10U, Opcode::SaveState).NoVregs();
233
234 INST(11U, Opcode::NOP);
235 INST(12U, Opcode::Return).s32().Inputs(9U);
236 }
237 }
238 }
239
OUT_GRAPH(FixSSInBBAfterSchedulerOutToBlock,Graph * graph)240 OUT_GRAPH(FixSSInBBAfterSchedulerOutToBlock, Graph *graph)
241 {
242 GRAPH(graph)
243 {
244 CONSTANT(1U, 1U).s32();
245 CONSTANT(2U, 2U).s32();
246
247 BASIC_BLOCK(2U, 3U)
248 {
249 INST(4U, Opcode::SaveState).NoVregs();
250 INST(5U, Opcode::LoadAndInitClass).ref().Inputs(4U).TypeId(68U);
251 INST(6U, Opcode::SaveState).NoVregs();
252 INST(7U, Opcode::LoadConstArray).ref().Inputs(6U);
253 }
254 BASIC_BLOCK(3U, -1L)
255 {
256 INST(8U, Opcode::Add).s32().Inputs(1U, 2U);
257
258 INST(10U, Opcode::SaveState).Inputs(7U).SrcVregs({VirtualRegister::BRIDGE});
259 INST(9U, Opcode::LoadArray).s32().Inputs(7U, 8U);
260
261 INST(11U, Opcode::NOP);
262 INST(12U, Opcode::Return).s32().Inputs(9U);
263 }
264 }
265 }
266
TEST_F(SchedulerTest,FixSSInBBAfterSchedulerOutToBlock)267 TEST_F(SchedulerTest, FixSSInBBAfterSchedulerOutToBlock)
268 {
269 src_graph::FixSSInBBAfterSchedulerOutToBlock::CREATE(GetGraph());
270
271 ASSERT_TRUE(GetGraph()->RunPass<Scheduler>());
272
273 auto graph = CreateEmptyGraph();
274 out_graph::FixSSInBBAfterSchedulerOutToBlock::CREATE(graph);
275
276 ASSERT_TRUE(GraphComparator().Compare(GetGraph(), graph));
277 }
278
TEST_F(SchedulerTest,LoadI)279 TEST_F(SchedulerTest, LoadI)
280 {
281 GRAPH(GetGraph())
282 {
283 PARAMETER(0U, 0U).u64();
284 PARAMETER(1U, 1U).ref();
285
286 BASIC_BLOCK(2U, -1L)
287 {
288 INST(2U, Opcode::SaveState).Inputs(0U, 1U).SrcVregs({0U, 1U});
289 INST(3U, Opcode::BoundsCheckI).s32().Inputs(0U, 2U).Imm(1U);
290 INST(4U, Opcode::StoreArrayI).u64().Inputs(1U, 0U).Imm(1U);
291 INST(5U, Opcode::SaveState).Inputs(0U, 1U).SrcVregs({0U, 1U});
292 INST(6U, Opcode::BoundsCheckI).s32().Inputs(0U, 5U).Imm(0U);
293 INST(7U, Opcode::LoadArrayI).u64().Inputs(1U).Imm(0U);
294 INST(8U, Opcode::Return).u64().Inputs(7U);
295 }
296 }
297
298 ASSERT_FALSE(GetGraph()->RunPass<Scheduler>());
299 }
300
TEST_F(SchedulerTest,TrickyLoadI)301 TEST_F(SchedulerTest, TrickyLoadI)
302 {
303 GRAPH(GetGraph())
304 {
305 PARAMETER(0U, 0U).u64();
306 PARAMETER(1U, 1U).ref();
307 BASIC_BLOCK(2U, -1L)
308 {
309 INST(5U, Opcode::SaveState).Inputs(0U, 1U).SrcVregs({0U, 1U});
310 INST(6U, Opcode::BoundsCheckI).s32().Inputs(0U, 5U).Imm(0U);
311 // Manually moved here
312 INST(2U, Opcode::SaveState).Inputs(0U, 1U).SrcVregs({0U, 1U});
313 INST(3U, Opcode::BoundsCheckI).s32().Inputs(0U, 2U).Imm(1U);
314 INST(4U, Opcode::StoreArrayI).u64().Inputs(1U, 0U).Imm(1U);
315 // But than all 3 may be moved below the load
316 INST(7U, Opcode::LoadArrayI).u64().Inputs(1U).Imm(0U);
317 INST(8U, Opcode::Return).u64().Inputs(7U);
318 }
319 }
320
321 ASSERT_TRUE(GetGraph()->RunPass<Scheduler>());
322
323 auto graph = CreateEmptyGraph();
324 GRAPH(graph)
325 {
326 PARAMETER(0U, 0U).u64();
327 PARAMETER(1U, 1U).ref();
328 BASIC_BLOCK(2U, -1L)
329 {
330 INST(5U, Opcode::SaveState).Inputs(0U, 1U).SrcVregs({0U, 1U});
331 INST(6U, Opcode::BoundsCheckI).s32().Inputs(0U, 5U).Imm(0U);
332 INST(7U, Opcode::LoadArrayI).u64().Inputs(1U).Imm(0U);
333
334 INST(2U, Opcode::SaveState).Inputs(0U, 1U).SrcVregs({0U, 1U});
335 INST(3U, Opcode::BoundsCheckI).s32().Inputs(0U, 2U).Imm(1U);
336 INST(4U, Opcode::StoreArrayI).u64().Inputs(1U, 0U).Imm(1U);
337
338 INST(8U, Opcode::Return).u64().Inputs(7U);
339 }
340 }
341 ASSERT_TRUE(GraphComparator().Compare(GetGraph(), graph));
342 }
343
TEST_F(SchedulerTest,MustAliasLoadI)344 TEST_F(SchedulerTest, MustAliasLoadI)
345 {
346 GRAPH(GetGraph())
347 {
348 PARAMETER(0U, 0U).u64();
349 PARAMETER(1U, 1U).ref();
350 BASIC_BLOCK(2U, -1L)
351 {
352 INST(5U, Opcode::SaveState).Inputs(0U, 1U).SrcVregs({0U, 1U});
353 INST(6U, Opcode::BoundsCheckI).s32().Inputs(0U, 5U).Imm(42U);
354 // Manually moved here
355 INST(2U, Opcode::SaveState).Inputs(0U, 1U).SrcVregs({0U, 1U});
356 INST(3U, Opcode::BoundsCheckI).s32().Inputs(0U, 2U).Imm(42U);
357 INST(4U, Opcode::StoreArrayI).u64().Inputs(1U, 0U).Imm(42U);
358 // But than all 3 may be moved below the load
359 INST(7U, Opcode::LoadArrayI).u64().Inputs(1U).Imm(42U);
360 INST(8U, Opcode::Return).u64().Inputs(7U);
361 }
362 }
363
364 ASSERT_FALSE(GetGraph()->RunPass<Scheduler>());
365 }
366
SRC_GRAPH(LoadPair,Graph * graph)367 SRC_GRAPH(LoadPair, Graph *graph)
368 {
369 GRAPH(graph)
370 {
371 PARAMETER(0U, 0U).s32(); // index
372 PARAMETER(1U, 1U).ref();
373 CONSTANT(11U, 41U);
374 CONSTANT(12U, 42U);
375 CONSTANT(13U, 43U);
376 CONSTANT(14U, 44U);
377 CONSTANT(15U, 45U);
378 CONSTANT(16U, 46U);
379 CONSTANT(17U, 47U);
380 CONSTANT(18U, 48U);
381 CONSTANT(19U, 49U);
382 CONSTANT(20U, 50U);
383 CONSTANT(21U, 51U);
384 CONSTANT(22U, 52U);
385 CONSTANT(23U, 53U);
386 CONSTANT(24U, 54U);
387
388 BASIC_BLOCK(2U, -1L)
389 {
390 INST(31U, Opcode::Add).u64().Inputs(11U, 12U);
391 INST(32U, Opcode::Add).u64().Inputs(13U, 14U);
392 INST(41U, Opcode::Add).u64().Inputs(31U, 32U);
393
394 INST(33U, Opcode::Add).u64().Inputs(15U, 16U);
395 INST(34U, Opcode::Add).u64().Inputs(17U, 18U);
396 INST(42U, Opcode::Add).u64().Inputs(33U, 34U);
397
398 INST(35U, Opcode::Add).u64().Inputs(19U, 20U);
399 INST(36U, Opcode::Add).u64().Inputs(21U, 22U);
400 INST(43U, Opcode::Add).u64().Inputs(35U, 36U);
401
402 INST(92U, Opcode::LoadArrayPair).u64().Inputs(1U, 0U);
403 INST(93U, Opcode::LoadPairPart).u64().Inputs(92U).Imm(0U);
404 INST(94U, Opcode::LoadPairPart).u64().Inputs(92U).Imm(1U);
405
406 INST(37U, Opcode::Add).u64().Inputs(23U, 93U);
407 INST(38U, Opcode::Add).u64().Inputs(24U, 94U);
408 INST(44U, Opcode::Add).u64().Inputs(37U, 38U);
409
410 INST(51U, Opcode::Add).u64().Inputs(41U, 42U);
411 INST(52U, Opcode::Add).u64().Inputs(43U, 44U);
412
413 INST(61U, Opcode::Add).u64().Inputs(51U, 52U);
414 INST(62U, Opcode::Return).u64().Inputs(61U);
415 }
416 }
417 }
418
OUT_GRAPH(LoadPair,Graph * graph)419 OUT_GRAPH(LoadPair, Graph *graph)
420 {
421 GRAPH(graph)
422 {
423 PARAMETER(0U, 0U).s32(); // index
424 PARAMETER(1U, 1U).ref();
425 CONSTANT(11U, 41U);
426 CONSTANT(12U, 42U);
427 CONSTANT(13U, 43U);
428 CONSTANT(14U, 44U);
429 CONSTANT(15U, 45U);
430 CONSTANT(16U, 46U);
431 CONSTANT(17U, 47U);
432 CONSTANT(18U, 48U);
433 CONSTANT(19U, 49U);
434 CONSTANT(20U, 50U);
435 CONSTANT(21U, 51U);
436 CONSTANT(22U, 52U);
437 CONSTANT(23U, 53U);
438 CONSTANT(24U, 54U);
439
440 BASIC_BLOCK(2U, -1L)
441 {
442 INST(92U, Opcode::LoadArrayPair).u64().Inputs(1U, 0U);
443 INST(93U, Opcode::LoadPairPart).u64().Inputs(92U).Imm(0U);
444 INST(94U, Opcode::LoadPairPart).u64().Inputs(92U).Imm(1U);
445
446 INST(31U, Opcode::Add).u64().Inputs(11U, 12U);
447 INST(32U, Opcode::Add).u64().Inputs(13U, 14U);
448 INST(33U, Opcode::Add).u64().Inputs(15U, 16U);
449 INST(34U, Opcode::Add).u64().Inputs(17U, 18U);
450 INST(35U, Opcode::Add).u64().Inputs(19U, 20U);
451 INST(36U, Opcode::Add).u64().Inputs(21U, 22U);
452 INST(37U, Opcode::Add).u64().Inputs(23U, 93U);
453 INST(38U, Opcode::Add).u64().Inputs(24U, 94U);
454
455 INST(41U, Opcode::Add).u64().Inputs(31U, 32U);
456 INST(42U, Opcode::Add).u64().Inputs(33U, 34U);
457 INST(43U, Opcode::Add).u64().Inputs(35U, 36U);
458 INST(44U, Opcode::Add).u64().Inputs(37U, 38U);
459
460 INST(51U, Opcode::Add).u64().Inputs(41U, 42U);
461 INST(52U, Opcode::Add).u64().Inputs(43U, 44U);
462
463 INST(61U, Opcode::Add).u64().Inputs(51U, 52U);
464 INST(62U, Opcode::Return).u64().Inputs(61U);
465 }
466 }
467 }
468
TEST_F(SchedulerTest,LoadPair)469 TEST_F(SchedulerTest, LoadPair)
470 {
471 src_graph::LoadPair::CREATE(GetGraph());
472
473 ASSERT_TRUE(GetGraph()->RunPass<Scheduler>());
474
475 auto graph = CreateEmptyGraph();
476 out_graph::LoadPair::CREATE(graph);
477 ASSERT_TRUE(GraphComparator().Compare(GetGraph(), graph));
478 }
479
TEST_F(SchedulerTest,NonVolatileLoadObject)480 TEST_F(SchedulerTest, NonVolatileLoadObject)
481 {
482 GRAPH(GetGraph())
483 {
484 PARAMETER(0U, 0U).ref();
485 PARAMETER(1U, 1U).s32();
486 PARAMETER(2U, 2U).s32();
487 PARAMETER(3U, 3U).s32();
488 BASIC_BLOCK(2U, -1L)
489 {
490 INST(4U, Opcode::Add).s32().Inputs(1U, 2U);
491 INST(5U, Opcode::Add).s32().Inputs(1U, 3U);
492 INST(6U, Opcode::Add).s32().Inputs(2U, 3U);
493 INST(7U, Opcode::Add).s32().Inputs(4U, 5U);
494 INST(8U, Opcode::Add).s32().Inputs(6U, 7U);
495 INST(9U, Opcode::SaveState).Inputs(0U).SrcVregs({0U});
496 INST(10U, Opcode::NullCheck).ref().Inputs(0U, 9U);
497 INST(11U, Opcode::LoadObject).s32().Inputs(10U).TypeId(152U);
498 INST(12U, Opcode::Add).s32().Inputs(8U, 11U);
499 INST(13U, Opcode::Return).s32().Inputs(12U);
500 }
501 }
502 ASSERT_TRUE(GetGraph()->RunPass<Scheduler>());
503
504 auto graph = CreateEmptyGraph();
505 GRAPH(graph)
506 {
507 PARAMETER(0U, 0U).ref();
508 PARAMETER(1U, 1U).s32();
509 PARAMETER(2U, 2U).s32();
510 PARAMETER(3U, 3U).s32();
511 BASIC_BLOCK(2U, -1L)
512 {
513 INST(9U, Opcode::SaveState).Inputs(0U).SrcVregs({0U});
514 INST(4U, Opcode::Add).s32().Inputs(1U, 2U);
515 INST(10U, Opcode::NullCheck).ref().Inputs(0U, 9U);
516 INST(5U, Opcode::Add).s32().Inputs(1U, 3U);
517 INST(11U, Opcode::LoadObject).s32().Inputs(10U).TypeId(152U);
518 INST(6U, Opcode::Add).s32().Inputs(2U, 3U);
519 INST(7U, Opcode::Add).s32().Inputs(4U, 5U);
520 INST(8U, Opcode::Add).s32().Inputs(6U, 7U);
521 INST(12U, Opcode::Add).s32().Inputs(8U, 11U);
522 INST(13U, Opcode::Return).s32().Inputs(12U);
523 }
524 }
525 ASSERT_TRUE(GraphComparator().Compare(GetGraph(), graph));
526 }
527
TEST_F(SchedulerTest,VolatileLoadObject)528 TEST_F(SchedulerTest, VolatileLoadObject)
529 {
530 GRAPH(GetGraph())
531 {
532 PARAMETER(0U, 0U).ref();
533 PARAMETER(1U, 1U).s32();
534 PARAMETER(2U, 2U).s32();
535 PARAMETER(3U, 3U).s32();
536 BASIC_BLOCK(2U, -1L)
537 {
538 INST(4U, Opcode::Add).s32().Inputs(1U, 2U);
539 INST(5U, Opcode::Add).s32().Inputs(1U, 3U);
540 INST(6U, Opcode::Add).s32().Inputs(2U, 3U);
541 INST(7U, Opcode::Add).s32().Inputs(4U, 5U);
542 INST(8U, Opcode::Add).s32().Inputs(6U, 7U);
543 INST(9U, Opcode::SaveState).Inputs(0U).SrcVregs({0U});
544 INST(10U, Opcode::NullCheck).ref().Inputs(0U, 9U);
545 INST(11U, Opcode::LoadObject).s32().Inputs(10U).TypeId(152U).Volatile();
546 INST(12U, Opcode::Add).s32().Inputs(8U, 11U);
547 INST(13U, Opcode::Return).s32().Inputs(12U);
548 }
549 }
550 ASSERT_TRUE(GetGraph()->RunPass<Scheduler>());
551
552 auto graph = CreateEmptyGraph();
553 GRAPH(graph)
554 {
555 PARAMETER(0U, 0U).ref();
556 PARAMETER(1U, 1U).s32();
557 PARAMETER(2U, 2U).s32();
558 PARAMETER(3U, 3U).s32();
559 BASIC_BLOCK(2U, -1L)
560 {
561 INST(4U, Opcode::Add).s32().Inputs(1U, 2U);
562 INST(5U, Opcode::Add).s32().Inputs(1U, 3U);
563 INST(9U, Opcode::SaveState).Inputs(0U).SrcVregs({0U});
564 INST(6U, Opcode::Add).s32().Inputs(2U, 3U);
565 INST(7U, Opcode::Add).s32().Inputs(4U, 5U);
566 INST(10U, Opcode::NullCheck).ref().Inputs(0U, 9U);
567 INST(8U, Opcode::Add).s32().Inputs(6U, 7U);
568 INST(11U, Opcode::LoadObject).s32().Inputs(10U).TypeId(152U).Volatile();
569 INST(12U, Opcode::Add).s32().Inputs(8U, 11U);
570 INST(13U, Opcode::Return).s32().Inputs(12U);
571 }
572 }
573 ASSERT_TRUE(GraphComparator().Compare(GetGraph(), graph));
574 }
575 // NOLINTEND(readability-magic-numbers)
576
577 } // namespace ark::compiler
578