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