• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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