1 /*
2 * Copyright (c) 2023-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 "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 .union_field std.core.String status
61 .record ETSGLOBAL <ets.abstract, ets.extends=std.core.Object, access.record=public> {
62 }
63 .record std.core.Object <external>
64 .record std.core.String <external>
65
66 .record std.time.ETSGLOBAL <external>
67 .function void ETSGLOBAL.foo(std.core.Object[] a0) <static, access.function=public> {
68 mov.obj v0, a0
69 lda.obj v0
70 sta.obj v0
71 ldai 0x1
72 ldarr.obj v0
73 sta.obj v0
74 ets.ldobj.name.obj v0, status
75 return.void
76 }
77 )");
78
79 auto res = p.Parse(source);
80 auto &program = res.Value();
81 pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps;
82 std::string fileName = "Ets_Ldobj";
83 auto pfile = pandasm::AsmEmitter::Emit(fileName, program, nullptr, &maps);
84 ASSERT_NE(pfile, false);
85
86 auto oldOptions = ark::bytecodeopt::g_options;
87 ark::bytecodeopt::g_options = ark::bytecodeopt::Options("--opt-level=2");
88 EXPECT_TRUE(OptimizeBytecode(&program, &maps, fileName, false, true));
89 ark::bytecodeopt::g_options = oldOptions;
90 for (const auto &inst : program.functionTable.find("ETSGLOBAL.foo:(std.core.Object[])")->second.ins) {
91 if (inst.opcode == ark::pandasm::Opcode::ETS_LDOBJ_NAME_OBJ) {
92 ASSERT_FALSE(inst.HasFlag(pandasm::InstFlags::ACC_READ));
93 }
94 }
95 }
96
97 // NOLINTEND(readability-magic-numbers)
98
99 } // namespace ark::bytecodeopt::test
100