• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 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 "ets_opt.h"
17 #include "bytecode_optimizer/reg_acc_alloc.h"
18 #include "bytecode_optimizer/optimize_bytecode.h"
19 
20 namespace ark::bytecodeopt::test {
21 
22 // NOLINTBEGIN(readability-magic-numbers)
23 
24 class RegAccAllocTest : public EtsOptTest {
25 public:
CheckInstructionsDestRegIsAcc(std::vector<int> && instIds)26     void CheckInstructionsDestRegIsAcc(std::vector<int> &&instIds)
27     {
28         for (auto id : instIds) {
29             ASSERT_EQ(INS(id).GetDstReg(), compiler::ACC_REG_ID);
30         }
31     }
32 
CheckInstructionsSrcRegIsAcc(std::vector<int> && instIds)33     void CheckInstructionsSrcRegIsAcc(std::vector<int> &&instIds)
34     {
35         for (auto id : instIds) {
36             uint8_t idx = 0;
37             switch (INS(id).GetOpcode()) {
38                 case compiler::Opcode::LoadArray:
39                 case compiler::Opcode::StoreObject:
40                 case compiler::Opcode::StoreStatic:
41                     idx = 1;
42                     break;
43                 case compiler::Opcode::StoreArray:
44                     idx = 2U;
45                     break;
46                 default:
47                     break;
48             }
49 
50             ASSERT_EQ(INS(id).GetSrcReg(idx), compiler::ACC_REG_ID);
51         }
52     }
53 };
54 
TEST_F(RegAccAllocTest,Ets_Ldobj)55 TEST_F(RegAccAllocTest, Ets_Ldobj)
56 {
57     pandasm::Parser p;
58     auto source = std::string(R"(
59         .language eTS
60         .record $NamedAccessMeta-std.core.String {
61             std.core.String status
62         }
63         .record ETSGLOBAL <ets.abstract, ets.extends=std.core.Object, access.record=public> {
64         }
65         .record std.core.Object <external>
66         .record std.core.String <external>
67 
68         .record std.time.ETSGLOBAL <external>
69         .function void ETSGLOBAL.foo(std.core.Object[] a0) <static, access.function=public> {
70             mov.obj v0, a0
71             lda.obj v0
72             sta.obj v0
73             ldai 0x1
74             ldarr.obj v0
75             sta.obj v0
76             ets.ldobj.name.obj v0, $NamedAccessMeta-std.core.String.status
77             return.void
78         }
79         )");
80 
81     auto res = p.Parse(source);
82     auto &program = res.Value();
83     pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps;
84     std::string fileName = "Ets_Ldobj";
85     auto pfile = pandasm::AsmEmitter::Emit(fileName, program, nullptr, &maps);
86     ASSERT_NE(pfile, false);
87 
88     auto oldOptions = ark::bytecodeopt::g_options;
89     ark::bytecodeopt::g_options = ark::bytecodeopt::Options("--opt-level=2");
90     EXPECT_TRUE(OptimizeBytecode(&program, &maps, fileName, false, true));
91     ark::bytecodeopt::g_options = oldOptions;
92     for (const auto &inst : program.functionStaticTable.find("ETSGLOBAL.foo:(std.core.Object[])")->second.ins) {
93         if (inst.opcode == ark::pandasm::Opcode::ETS_LDOBJ_NAME_OBJ) {
94             ASSERT_FALSE(inst.HasFlag(pandasm::InstFlags::ACC_READ));
95         }
96     }
97 }
98 
99 // NOLINTEND(readability-magic-numbers)
100 
101 }  // namespace ark::bytecodeopt::test
102