• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 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 <cstdint>
17 #include "libpandabase/utils/utils.h"
18 #include "compiler_logger.h"
19 #include "optimizer/ir_builder/inst_builder.h"
20 #include "optimizer/ir_builder/ir_builder.h"
21 #include "optimizer/ir/inst.h"
22 #include "bytecode_instruction.h"
23 #include "bytecode_instruction-inl.h"
24 
25 namespace panda::compiler {
26 
27 template <Opcode OPCODE>
BuildLaunch(const BytecodeInstruction * bcInst,bool isRange,bool accRead)28 void InstBuilder::BuildLaunch(const BytecodeInstruction *bcInst, bool isRange, bool accRead)
29 {
30     if (graph_->GetArch() == Arch::AARCH32) {
31         failed_ = true;
32         return;
33     }
34     auto pc = GetPc(bcInst->GetAddress());
35     auto inst = graph_->CreateInstLoadRuntimeClass(DataType::REFERENCE, pc, TypeIdMixin::MEM_PROMISE_CLASS_ID,
36                                                    GetGraph()->GetMethod(), nullptr);
37     auto saveState = CreateSaveState(Opcode::SaveState, pc);
38     auto newObj = CreateNewObjectInst(pc, TypeIdMixin::MEM_PROMISE_CLASS_ID, saveState, inst);
39     AddInstruction(saveState, inst, newObj);
40     BuildCall<OPCODE>(bcInst, isRange, accRead, newObj);
41     UpdateDefinitionAcc(newObj);
42 }
43 
44 template void InstBuilder::BuildLaunch<Opcode::CallLaunchStatic>(const BytecodeInstruction *bc_inst, bool is_range,
45                                                                  bool acc_read);
46 template void InstBuilder::BuildLaunch<Opcode::CallLaunchVirtual>(const BytecodeInstruction *bc_inst, bool is_range,
47                                                                   bool acc_read);
48 
BuildLdObjByName(const BytecodeInstruction * bcInst,DataType::Type type)49 void InstBuilder::BuildLdObjByName(const BytecodeInstruction *bcInst, DataType::Type type)
50 {
51     auto pc = GetPc(bcInst->GetAddress());
52     // Create SaveState instruction
53     auto saveState = CreateSaveState(Opcode::SaveState, pc);
54 
55     // Create NullCheck instruction
56     auto nullCheck = graph_->CreateInstNullCheck(DataType::REFERENCE, pc, GetDefinition(bcInst->GetVReg(0)), saveState);
57 
58     auto runtime = GetRuntime();
59     auto fieldIndex = bcInst->GetId(0).AsIndex();
60     auto fieldId = runtime->ResolveFieldIndex(GetMethod(), fieldIndex);
61     if (type != DataType::REFERENCE) {
62         type = runtime->GetFieldTypeById(GetMethod(), fieldId);
63     }
64 
65     RuntimeInterface::IntrinsicId id;
66     switch (type) {
67         case DataType::REFERENCE:
68             id = RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_LD_OBJ_BY_NAME_OBJ;
69             break;
70         case DataType::FLOAT64:
71             id = RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_LD_OBJ_BY_NAME_F64;
72             break;
73         case DataType::FLOAT32:
74             id = RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_LD_OBJ_BY_NAME_F32;
75             break;
76         case DataType::UINT64:
77         case DataType::INT64:
78             id = RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_LD_OBJ_BY_NAME_I64;
79             break;
80         case DataType::UINT8:
81         case DataType::INT8:
82         case DataType::UINT16:
83         case DataType::INT16:
84         case DataType::UINT32:
85         case DataType::INT32:
86             id = RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_LD_OBJ_BY_NAME_I32;
87             break;
88         default:
89             UNREACHABLE();
90             break;
91     }
92     auto intrinsic = GetGraph()->CreateInstIntrinsic(type, pc, id);
93     intrinsic->AllocateInputTypes(GetGraph()->GetAllocator(), 2_I);
94 
95     intrinsic->AppendInput(nullCheck);
96     intrinsic->AddInputType(DataType::REFERENCE);
97 
98     intrinsic->AppendInput(saveState);
99     intrinsic->AddInputType(DataType::NO_TYPE);
100 
101     intrinsic->AddImm(GetGraph()->GetAllocator(), fieldId);
102     intrinsic->AddImm(GetGraph()->GetAllocator(), pc);
103 
104     intrinsic->SetMethodFirstInput();
105     intrinsic->SetMethod(GetMethod());
106 
107     AddInstruction(saveState);
108     AddInstruction(nullCheck);
109     AddInstruction(intrinsic);
110 
111     UpdateDefinitionAcc(intrinsic);
112 }
113 
BuildStObjByName(const BytecodeInstruction * bcInst,DataType::Type type)114 void InstBuilder::BuildStObjByName(const BytecodeInstruction *bcInst, DataType::Type type)
115 {
116     auto pc = GetPc(bcInst->GetAddress());
117     // Create SaveState instruction
118     auto saveState = CreateSaveState(Opcode::SaveState, pc);
119 
120     // Create NullCheck instruction
121     auto nullCheck = graph_->CreateInstNullCheck(DataType::REFERENCE, pc, GetDefinition(bcInst->GetVReg(0)), saveState);
122 
123     auto runtime = GetRuntime();
124     auto fieldIndex = bcInst->GetId(0).AsIndex();
125     auto fieldId = runtime->ResolveFieldIndex(GetMethod(), fieldIndex);
126     if (type != DataType::REFERENCE) {
127         type = runtime->GetFieldTypeById(GetMethod(), fieldId);
128     }
129 
130     // Get a value to store
131     Inst *storeVal = nullptr;
132     storeVal = GetDefinitionAcc();
133 
134     RuntimeInterface::IntrinsicId id;
135     switch (type) {
136         case DataType::REFERENCE:
137             id = RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_ST_OBJ_BY_NAME_OBJ;
138             break;
139         case DataType::FLOAT64:
140             id = RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_ST_OBJ_BY_NAME_F64;
141             break;
142         case DataType::FLOAT32:
143             id = RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_ST_OBJ_BY_NAME_F32;
144             break;
145         case DataType::UINT64:
146         case DataType::INT64:
147             id = RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_ST_OBJ_BY_NAME_I64;
148             break;
149         case DataType::UINT8:
150         case DataType::INT8:
151         case DataType::UINT16:
152         case DataType::INT16:
153         case DataType::UINT32:
154         case DataType::INT32:
155             id = RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_ST_OBJ_BY_NAME_I32;
156             break;
157         default:
158             UNREACHABLE();
159             break;
160     }
161     auto intrinsic = GetGraph()->CreateInstIntrinsic(type, pc, id);
162     intrinsic->AllocateInputTypes(GetGraph()->GetAllocator(), 3_I);
163 
164     intrinsic->AppendInput(nullCheck);
165     intrinsic->AddInputType(DataType::REFERENCE);
166 
167     intrinsic->AppendInput(storeVal);
168     intrinsic->AddInputType(type);
169 
170     intrinsic->AppendInput(saveState);
171     intrinsic->AddInputType(DataType::NO_TYPE);
172     intrinsic->AddImm(GetGraph()->GetAllocator(), fieldId);
173     intrinsic->AddImm(GetGraph()->GetAllocator(), pc);
174 
175     intrinsic->SetMethodFirstInput();
176     intrinsic->SetMethod(GetMethod());
177 
178     AddInstruction(saveState);
179     AddInstruction(nullCheck);
180     AddInstruction(intrinsic);
181 }
182 
183 }  // namespace panda::compiler
184