1b1994897Sopenharmony_ci/** 2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License. 5b1994897Sopenharmony_ci * You may obtain a copy of the License at 6b1994897Sopenharmony_ci * 7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8b1994897Sopenharmony_ci * 9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and 13b1994897Sopenharmony_ci * limitations under the License. 14b1994897Sopenharmony_ci */ 15b1994897Sopenharmony_ci 16b1994897Sopenharmony_ci#include "inst.h" 17b1994897Sopenharmony_ci#include "graph.h" 18b1994897Sopenharmony_ci#include "graph_visitor.h" 19b1994897Sopenharmony_ci#include "optimizer/optimizations/vn.h" 20b1994897Sopenharmony_ci 21b1994897Sopenharmony_cinamespace panda::compiler { 22b1994897Sopenharmony_ci 23b1994897Sopenharmony_civoid Inst::ReserveInputs(size_t capacity) 24b1994897Sopenharmony_ci{ 25b1994897Sopenharmony_ci ASSERT(IsOperandsDynamic()); 26b1994897Sopenharmony_ci GetDynamicOperands()->Reallocate(capacity); 27b1994897Sopenharmony_ci} 28b1994897Sopenharmony_ci 29b1994897Sopenharmony_ciInst *User::GetInst() 30b1994897Sopenharmony_ci{ 31b1994897Sopenharmony_ci if (UNLIKELY(IsDynamic())) { 32b1994897Sopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 33b1994897Sopenharmony_ci return *reinterpret_cast<Inst **>(this + GetIndex() + 1); 34b1994897Sopenharmony_ci } 35b1994897Sopenharmony_ci auto p = reinterpret_cast<uintptr_t>(this); 36b1994897Sopenharmony_ci p += (GetIndex() + 1) * sizeof(User); 37b1994897Sopenharmony_ci 38b1994897Sopenharmony_ci auto inputs_count {SizeField::Decode(properties_)}; 39b1994897Sopenharmony_ci p += (inputs_count + Input::GetPadding(RUNTIME_ARCH, inputs_count)) * sizeof(Input); 40b1994897Sopenharmony_ci return reinterpret_cast<Inst *>(p); 41b1994897Sopenharmony_ci} 42b1994897Sopenharmony_ci 43b1994897Sopenharmony_civoid Inst::InsertBefore(Inst *inst) 44b1994897Sopenharmony_ci{ 45b1994897Sopenharmony_ci ASSERT(bb_ != nullptr); 46b1994897Sopenharmony_ci bb_->InsertBefore(inst, this); 47b1994897Sopenharmony_ci} 48b1994897Sopenharmony_ci 49b1994897Sopenharmony_civoid Inst::InsertAfter(Inst *inst) 50b1994897Sopenharmony_ci{ 51b1994897Sopenharmony_ci ASSERT(bb_ != nullptr); 52b1994897Sopenharmony_ci bb_->InsertAfter(inst, this); 53b1994897Sopenharmony_ci} 54b1994897Sopenharmony_ci 55b1994897Sopenharmony_civoid DynamicOperands::Reallocate([[maybe_unused]] size_t new_capacity /* =0 */) 56b1994897Sopenharmony_ci{ 57b1994897Sopenharmony_ci if (new_capacity == 0) { 58b1994897Sopenharmony_ci constexpr auto IMM_2 = 2; 59b1994897Sopenharmony_ci new_capacity = (((capacity_ != 0U) ? capacity_ : 1U) << 1U) + IMM_2; 60b1994897Sopenharmony_ci } else if (new_capacity <= capacity_) { 61b1994897Sopenharmony_ci return; 62b1994897Sopenharmony_ci } 63b1994897Sopenharmony_ci auto size = new_capacity * (sizeof(User) + sizeof(Inst *)) + sizeof(Inst *); 64b1994897Sopenharmony_ci auto new_stor = reinterpret_cast<uintptr_t>(allocator_->Alloc(size)); 65b1994897Sopenharmony_ci CHECK(new_stor != 0); 66b1994897Sopenharmony_ci 67b1994897Sopenharmony_ci auto owner_inst {GetOwnerInst()}; 68b1994897Sopenharmony_ci // Set pointer to owned instruction into new storage NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 69b1994897Sopenharmony_ci *reinterpret_cast<Inst **>(reinterpret_cast<User *>(new_stor) + new_capacity) = owner_inst; 70b1994897Sopenharmony_ci 71b1994897Sopenharmony_ci if (users_ == nullptr) { 72b1994897Sopenharmony_ci users_ = reinterpret_cast<User *>(new_stor); 73b1994897Sopenharmony_ci capacity_ = new_capacity; 74b1994897Sopenharmony_ci return; 75b1994897Sopenharmony_ci } 76b1994897Sopenharmony_ci Input *old_inputs = Inputs(); 77b1994897Sopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 78b1994897Sopenharmony_ci auto *new_inputs = reinterpret_cast<Input *>(new_stor + sizeof(User) * new_capacity) + 1; 79b1994897Sopenharmony_ci 80b1994897Sopenharmony_ci for (size_t i = 0; i < size_; i++) { 81b1994897Sopenharmony_ci Inst *old_input = old_inputs[i].GetInst(); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 82b1994897Sopenharmony_ci ASSERT(old_input); 83b1994897Sopenharmony_ci // Initialize new User in container. Since users are placed from end of array, i.e. zero index element 84b1994897Sopenharmony_ci // will be at the end of array, we need to add capacity and substitute index. 85b1994897Sopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 86b1994897Sopenharmony_ci User *new_user = new (reinterpret_cast<User *>(new_stor) + new_capacity - i - 1) User(false, i, new_capacity); 87b1994897Sopenharmony_ci auto old_user {GetUser(i)}; 88b1994897Sopenharmony_ci if (owner_inst->IsSaveState()) { 89b1994897Sopenharmony_ci new_user->SetVirtualRegister(old_user->GetVirtualRegister()); 90b1994897Sopenharmony_ci } else if (owner_inst->IsPhi()) { 91b1994897Sopenharmony_ci new_user->SetBbNum(old_user->GetBbNum()); 92b1994897Sopenharmony_ci } 93b1994897Sopenharmony_ci old_input->RemoveUser(old_user); 94b1994897Sopenharmony_ci old_input->AddUser(new_user); 95b1994897Sopenharmony_ci new_inputs[i] = Input(old_input); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 96b1994897Sopenharmony_ci } 97b1994897Sopenharmony_ci capacity_ = new_capacity; 98b1994897Sopenharmony_ci users_ = reinterpret_cast<User *>(new_stor); 99b1994897Sopenharmony_ci} 100b1994897Sopenharmony_ci 101b1994897Sopenharmony_ciunsigned DynamicOperands::Append(Inst *inst) 102b1994897Sopenharmony_ci{ 103b1994897Sopenharmony_ci ASSERT(capacity_ >= size_); 104b1994897Sopenharmony_ci if (capacity_ == size_) { 105b1994897Sopenharmony_ci Reallocate(); 106b1994897Sopenharmony_ci } 107b1994897Sopenharmony_ci SetInput(size_, Input(inst)); 108b1994897Sopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 109b1994897Sopenharmony_ci new (users_ + capacity_ - size_ - 1) User(false, size_, capacity_); 110b1994897Sopenharmony_ci auto user {GetUser(size_)}; 111b1994897Sopenharmony_ci if (GetOwnerInst()->IsPhi()) { 112b1994897Sopenharmony_ci user->SetBbNum(size_); 113b1994897Sopenharmony_ci } 114b1994897Sopenharmony_ci inst->AddUser(user); 115b1994897Sopenharmony_ci return size_++; 116b1994897Sopenharmony_ci} 117b1994897Sopenharmony_ci 118b1994897Sopenharmony_civoid DynamicOperands::Remove(unsigned index) 119b1994897Sopenharmony_ci{ 120b1994897Sopenharmony_ci size_--; 121b1994897Sopenharmony_ci auto *curr_input = GetInput(index)->GetInst(); 122b1994897Sopenharmony_ci if (curr_input->GetBasicBlock() != nullptr && curr_input->HasUsers()) { 123b1994897Sopenharmony_ci curr_input->RemoveUser(GetUser(index)); 124b1994897Sopenharmony_ci } 125b1994897Sopenharmony_ci 126b1994897Sopenharmony_ci auto bb_num {GetUser(index)->GetBbNum()}; 127b1994897Sopenharmony_ci auto owner_inst {GetOwnerInst()}; 128b1994897Sopenharmony_ci 129b1994897Sopenharmony_ci if (index != size_) { 130b1994897Sopenharmony_ci auto *last_input = GetInput(size_)->GetInst(); 131b1994897Sopenharmony_ci if (last_input->HasUsers()) { 132b1994897Sopenharmony_ci last_input->RemoveUser(GetUser(size_)); 133b1994897Sopenharmony_ci last_input->AddUser(GetUser(index)); 134b1994897Sopenharmony_ci } 135b1994897Sopenharmony_ci SetInput(index, *GetInput(size_)); 136b1994897Sopenharmony_ci if (owner_inst->IsSaveState()) { 137b1994897Sopenharmony_ci GetUser(index)->SetVirtualRegister(GetUser(size_)->GetVirtualRegister()); 138b1994897Sopenharmony_ci } else if (owner_inst->IsPhi()) { 139b1994897Sopenharmony_ci GetUser(index)->SetBbNum(GetUser(size_)->GetBbNum()); 140b1994897Sopenharmony_ci } 141b1994897Sopenharmony_ci } 142b1994897Sopenharmony_ci 143b1994897Sopenharmony_ci if (owner_inst->IsPhi()) { 144b1994897Sopenharmony_ci for (size_t i {0}; i < size_; ++i) { 145b1994897Sopenharmony_ci if (GetUser(i)->GetBbNum() == size_) { 146b1994897Sopenharmony_ci GetUser(i)->SetBbNum(bb_num); 147b1994897Sopenharmony_ci break; 148b1994897Sopenharmony_ci } 149b1994897Sopenharmony_ci } 150b1994897Sopenharmony_ci } 151b1994897Sopenharmony_ci} 152b1994897Sopenharmony_ci 153b1994897Sopenharmony_civoid CompareInst::SetVnObject(VnObject *vn_obj) 154b1994897Sopenharmony_ci{ 155b1994897Sopenharmony_ci vn_obj->Add(static_cast<uint32_t>(GetCc())); 156b1994897Sopenharmony_ci} 157b1994897Sopenharmony_ci 158b1994897Sopenharmony_civoid IfInst::SetVnObject(VnObject *vn_obj) 159b1994897Sopenharmony_ci{ 160b1994897Sopenharmony_ci vn_obj->Add(static_cast<uint32_t>(GetCc())); 161b1994897Sopenharmony_ci} 162b1994897Sopenharmony_ci 163b1994897Sopenharmony_civoid IfImmInst::SetVnObject(VnObject *vn_obj) 164b1994897Sopenharmony_ci{ 165b1994897Sopenharmony_ci vn_obj->Add(static_cast<uint32_t>(GetCc())); 166b1994897Sopenharmony_ci} 167b1994897Sopenharmony_ci 168b1994897Sopenharmony_civoid CmpInst::SetVnObject(VnObject *vn_obj) 169b1994897Sopenharmony_ci{ 170b1994897Sopenharmony_ci if (DataType::IsFloatType(GetOperandsType())) { 171b1994897Sopenharmony_ci vn_obj->Add(static_cast<uint32_t>(IsFcmpg())); 172b1994897Sopenharmony_ci } 173b1994897Sopenharmony_ci vn_obj->Add(static_cast<uint32_t>(GetInputType(0))); 174b1994897Sopenharmony_ci} 175b1994897Sopenharmony_ci 176b1994897Sopenharmony_ciBasicBlock *PhiInst::GetPhiInputBb(unsigned index) 177b1994897Sopenharmony_ci{ 178b1994897Sopenharmony_ci ASSERT(index < GetInputsCount()); 179b1994897Sopenharmony_ci 180b1994897Sopenharmony_ci auto bb_num {GetPhiInputBbNum(index)}; 181b1994897Sopenharmony_ci ASSERT(bb_num < GetBasicBlock()->GetPredsBlocks().size()); 182b1994897Sopenharmony_ci return GetBasicBlock()->GetPredsBlocks()[bb_num]; 183b1994897Sopenharmony_ci} 184b1994897Sopenharmony_ci 185b1994897Sopenharmony_ciInst *PhiInst::GetPhiInput(BasicBlock *bb) 186b1994897Sopenharmony_ci{ 187b1994897Sopenharmony_ci auto index = GetPredBlockIndex(bb); 188b1994897Sopenharmony_ci ASSERT(index < GetInputs().size()); 189b1994897Sopenharmony_ci return GetInput(index).GetInst(); 190b1994897Sopenharmony_ci} 191b1994897Sopenharmony_ci 192b1994897Sopenharmony_ciInst *PhiInst::GetPhiDataflowInput(BasicBlock *bb) 193b1994897Sopenharmony_ci{ 194b1994897Sopenharmony_ci auto index = GetPredBlockIndex(bb); 195b1994897Sopenharmony_ci ASSERT(index < GetInputs().size()); 196b1994897Sopenharmony_ci return GetDataFlowInput(index); 197b1994897Sopenharmony_ci} 198b1994897Sopenharmony_ci 199b1994897Sopenharmony_cisize_t PhiInst::GetPredBlockIndex(const BasicBlock *block) const 200b1994897Sopenharmony_ci{ 201b1994897Sopenharmony_ci for (size_t i {0}; i < GetInputsCount(); ++i) { 202b1994897Sopenharmony_ci if (GetPhiInputBb(i) == block) { 203b1994897Sopenharmony_ci return i; 204b1994897Sopenharmony_ci } 205b1994897Sopenharmony_ci } 206b1994897Sopenharmony_ci UNREACHABLE(); 207b1994897Sopenharmony_ci} 208b1994897Sopenharmony_ci 209b1994897Sopenharmony_citemplate <Opcode opc, size_t input_idx> 210b1994897Sopenharmony_ciInst *SkipInstructions(Inst *input_inst) 211b1994897Sopenharmony_ci{ 212b1994897Sopenharmony_ci // NOLINTNEXTLINE(readability-magic-numbers) 213b1994897Sopenharmony_ci for (Opcode opcode = input_inst->GetOpcode(); opcode == opc; opcode = input_inst->GetOpcode()) { 214b1994897Sopenharmony_ci input_inst = input_inst->GetInput(input_idx).GetInst(); 215b1994897Sopenharmony_ci } 216b1994897Sopenharmony_ci return input_inst; 217b1994897Sopenharmony_ci} 218b1994897Sopenharmony_ci/* 219b1994897Sopenharmony_ci * For instructions LoadArray, StoreArray, LoadArrayPair, StoreArrayPair, LoadArrayI, StoreArrayI, LoadArrayPairI, 220b1994897Sopenharmony_ci * StoreArrayPairI, LenArray, LoadObject, StoreObject, CallVirtual, Monitor with NullCheck input the dataflow user 221b1994897Sopenharmony_ci * is object, which is the first input of NullCheck instruction. 222b1994897Sopenharmony_ci * For instructions LoadArray, StoreArray, LoadArrayPair, StoreArrayPair with BoundsCheck input the dataflow user is 223b1994897Sopenharmony_ci * array index, which is the second input of BoundsCheck instruction 224b1994897Sopenharmony_ci * For instructions Div and Mod with ZeroCheck input the dataflow user is the first input of ZeroCheck 225b1994897Sopenharmony_ci */ 226b1994897Sopenharmony_ciInst *Inst::GetDataFlowInput(Inst *input_inst) const 227b1994897Sopenharmony_ci{ 228b1994897Sopenharmony_ci return input_inst; 229b1994897Sopenharmony_ci} 230b1994897Sopenharmony_ci 231b1994897Sopenharmony_cibool Inst::IsPrecedingInSameBlock(const Inst *other) const 232b1994897Sopenharmony_ci{ 233b1994897Sopenharmony_ci ASSERT(other != nullptr && GetBasicBlock() == other->GetBasicBlock()); 234b1994897Sopenharmony_ci if (this == other) { 235b1994897Sopenharmony_ci return true; 236b1994897Sopenharmony_ci } 237b1994897Sopenharmony_ci auto next = GetNext(); 238b1994897Sopenharmony_ci while (next != nullptr) { 239b1994897Sopenharmony_ci if (next == other) { 240b1994897Sopenharmony_ci return true; 241b1994897Sopenharmony_ci } 242b1994897Sopenharmony_ci next = next->GetNext(); 243b1994897Sopenharmony_ci } 244b1994897Sopenharmony_ci return false; 245b1994897Sopenharmony_ci} 246b1994897Sopenharmony_ci 247b1994897Sopenharmony_cibool Inst::IsDominate(const Inst *other) const 248b1994897Sopenharmony_ci{ 249b1994897Sopenharmony_ci ASSERT(other != nullptr); 250b1994897Sopenharmony_ci if (this == other) { 251b1994897Sopenharmony_ci return true; 252b1994897Sopenharmony_ci } 253b1994897Sopenharmony_ci auto this_bb = GetBasicBlock(); 254b1994897Sopenharmony_ci auto other_bb = other->GetBasicBlock(); 255b1994897Sopenharmony_ci return this_bb == other_bb ? IsPrecedingInSameBlock(other) : this_bb->IsDominate(other_bb); 256b1994897Sopenharmony_ci} 257b1994897Sopenharmony_ci 258b1994897Sopenharmony_cibool Inst::InSameBlockOrDominate(const Inst *other) const 259b1994897Sopenharmony_ci{ 260b1994897Sopenharmony_ci return GetBasicBlock() == other->GetBasicBlock() || IsDominate(other); 261b1994897Sopenharmony_ci} 262b1994897Sopenharmony_ci 263b1994897Sopenharmony_ciInst *Inst::Clone(const Graph *targetGraph) const 264b1994897Sopenharmony_ci{ 265b1994897Sopenharmony_ci ASSERT(targetGraph != nullptr); 266b1994897Sopenharmony_ci auto clone = targetGraph->CreateInst(GetOpcode()); 267b1994897Sopenharmony_ci CHECK_NOT_NULL(clone); 268b1994897Sopenharmony_ci clone->bit_fields_ = GetAllFields(); 269b1994897Sopenharmony_ci clone->pc_ = GetPc(); 270b1994897Sopenharmony_ci#ifndef NDEBUG 271b1994897Sopenharmony_ci clone->SetDstReg(GetDstReg()); 272b1994897Sopenharmony_ci#endif 273b1994897Sopenharmony_ci if (IsOperandsDynamic()) { 274b1994897Sopenharmony_ci clone->ReserveInputs(GetInputsCount()); 275b1994897Sopenharmony_ci } 276b1994897Sopenharmony_ci return clone; 277b1994897Sopenharmony_ci} 278b1994897Sopenharmony_ci 279b1994897Sopenharmony_ci#if PANDA_TARGET_MACOS 280b1994897Sopenharmony_citemplate class FixedInputsInst<0>; 281b1994897Sopenharmony_citemplate class FixedInputsInst<1>; 282b1994897Sopenharmony_citemplate class FixedInputsInst<2U>; 283b1994897Sopenharmony_ci#endif 284b1994897Sopenharmony_ci 285b1994897Sopenharmony_ciInst *SpillFillInst::Clone(const Graph *targetGraph) const 286b1994897Sopenharmony_ci{ 287b1994897Sopenharmony_ci auto clone = FixedInputsInst::Clone(targetGraph)->CastToSpillFill(); 288b1994897Sopenharmony_ci for (auto spill_fill : spill_fills_) { 289b1994897Sopenharmony_ci clone->AddSpillFill(spill_fill); 290b1994897Sopenharmony_ci } 291b1994897Sopenharmony_ci return clone; 292b1994897Sopenharmony_ci} 293b1994897Sopenharmony_ci 294b1994897Sopenharmony_ciInst *CompareInst::Clone(const Graph *targetGraph) const 295b1994897Sopenharmony_ci{ 296b1994897Sopenharmony_ci auto clone = FixedInputsInst::Clone(targetGraph); 297b1994897Sopenharmony_ci clone->CastToCompare()->SetCc(GetCc()); 298b1994897Sopenharmony_ci clone->CastToCompare()->SetOperandsType(GetOperandsType()); 299b1994897Sopenharmony_ci return clone; 300b1994897Sopenharmony_ci} 301b1994897Sopenharmony_ci 302b1994897Sopenharmony_ciInst *CmpInst::Clone(const Graph *targetGraph) const 303b1994897Sopenharmony_ci{ 304b1994897Sopenharmony_ci auto clone = FixedInputsInst::Clone(targetGraph); 305b1994897Sopenharmony_ci clone->CastToCmp()->SetOperandsType(GetOperandsType()); 306b1994897Sopenharmony_ci return clone; 307b1994897Sopenharmony_ci} 308b1994897Sopenharmony_ci 309b1994897Sopenharmony_ciInst *IfInst::Clone(const Graph *targetGraph) const 310b1994897Sopenharmony_ci{ 311b1994897Sopenharmony_ci auto clone = FixedInputsInst::Clone(targetGraph); 312b1994897Sopenharmony_ci static_cast<IfInst *>(clone)->SetCc(GetCc()); 313b1994897Sopenharmony_ci static_cast<IfInst *>(clone)->SetOperandsType(GetOperandsType()); 314b1994897Sopenharmony_ci static_cast<IfInst *>(clone)->SetMethod(GetMethod()); 315b1994897Sopenharmony_ci return clone; 316b1994897Sopenharmony_ci} 317b1994897Sopenharmony_ci 318b1994897Sopenharmony_ciInst *IntrinsicInst::Clone(const Graph *targetGraph) const 319b1994897Sopenharmony_ci{ 320b1994897Sopenharmony_ci ASSERT(targetGraph != nullptr); 321b1994897Sopenharmony_ci auto intrinsicClone = Inst::Clone(targetGraph)->CastToIntrinsic(); 322b1994897Sopenharmony_ci intrinsicClone->SetIntrinsicId(GetIntrinsicId()); 323b1994897Sopenharmony_ci CloneTypes(targetGraph->GetAllocator(), intrinsicClone); 324b1994897Sopenharmony_ci if (HasImms()) { 325b1994897Sopenharmony_ci for (auto imm : GetImms()) { 326b1994897Sopenharmony_ci intrinsicClone->AddImm(targetGraph->GetAllocator(), imm); 327b1994897Sopenharmony_ci } 328b1994897Sopenharmony_ci } 329b1994897Sopenharmony_ci return intrinsicClone; 330b1994897Sopenharmony_ci} 331b1994897Sopenharmony_ci 332b1994897Sopenharmony_ciInst *ConstantInst::Clone(const Graph *targetGraph) const 333b1994897Sopenharmony_ci{ 334b1994897Sopenharmony_ci Inst *new_cnst = nullptr; 335b1994897Sopenharmony_ci bool is_support_int32 = GetBasicBlock()->GetGraph()->IsBytecodeOptimizer(); 336b1994897Sopenharmony_ci switch (GetType()) { 337b1994897Sopenharmony_ci case DataType::INT32: 338b1994897Sopenharmony_ci new_cnst = targetGraph->CreateInstConstant(static_cast<int32_t>(GetIntValue()), is_support_int32); 339b1994897Sopenharmony_ci break; 340b1994897Sopenharmony_ci case DataType::INT64: 341b1994897Sopenharmony_ci new_cnst = targetGraph->CreateInstConstant(GetIntValue(), is_support_int32); 342b1994897Sopenharmony_ci break; 343b1994897Sopenharmony_ci case DataType::FLOAT32: 344b1994897Sopenharmony_ci new_cnst = targetGraph->CreateInstConstant(GetFloatValue(), is_support_int32); 345b1994897Sopenharmony_ci break; 346b1994897Sopenharmony_ci case DataType::FLOAT64: 347b1994897Sopenharmony_ci new_cnst = targetGraph->CreateInstConstant(GetDoubleValue(), is_support_int32); 348b1994897Sopenharmony_ci break; 349b1994897Sopenharmony_ci case DataType::ANY: 350b1994897Sopenharmony_ci new_cnst = targetGraph->CreateInstConstant(GetRawValue(), is_support_int32); 351b1994897Sopenharmony_ci new_cnst->SetType(DataType::ANY); 352b1994897Sopenharmony_ci break; 353b1994897Sopenharmony_ci default: 354b1994897Sopenharmony_ci UNREACHABLE(); 355b1994897Sopenharmony_ci } 356b1994897Sopenharmony_ci#ifndef NDEBUG 357b1994897Sopenharmony_ci new_cnst->SetDstReg(GetDstReg()); 358b1994897Sopenharmony_ci#endif 359b1994897Sopenharmony_ci return new_cnst; 360b1994897Sopenharmony_ci} 361b1994897Sopenharmony_ci 362b1994897Sopenharmony_ciInst *ParameterInst::Clone(const Graph *targetGraph) const 363b1994897Sopenharmony_ci{ 364b1994897Sopenharmony_ci auto clone = Inst::Clone(targetGraph)->CastToParameter(); 365b1994897Sopenharmony_ci clone->SetArgNumber(GetArgNumber()); 366b1994897Sopenharmony_ci clone->SetLocationData(GetLocationData()); 367b1994897Sopenharmony_ci return clone; 368b1994897Sopenharmony_ci} 369b1994897Sopenharmony_ci 370b1994897Sopenharmony_ciInst *SaveStateInst::Clone(const Graph *targetGraph) const 371b1994897Sopenharmony_ci{ 372b1994897Sopenharmony_ci auto clone = static_cast<SaveStateInst *>(Inst::Clone(targetGraph)); 373b1994897Sopenharmony_ci if (GetImmediatesCount() > 0) { 374b1994897Sopenharmony_ci clone->AllocateImmediates(targetGraph->GetAllocator(), GetImmediatesCount()); 375b1994897Sopenharmony_ci std::copy(immediates_->begin(), immediates_->end(), clone->immediates_->begin()); 376b1994897Sopenharmony_ci } 377b1994897Sopenharmony_ci clone->method_ = method_; 378b1994897Sopenharmony_ci return clone; 379b1994897Sopenharmony_ci} 380b1994897Sopenharmony_ci 381b1994897Sopenharmony_civoid SaveStateInst::AppendImmediate(uint64_t imm, uint16_t vreg, DataType::Type type, bool is_acc) 382b1994897Sopenharmony_ci{ 383b1994897Sopenharmony_ci if (immediates_ == nullptr) { 384b1994897Sopenharmony_ci ASSERT(GetBasicBlock() != nullptr); 385b1994897Sopenharmony_ci AllocateImmediates(GetBasicBlock()->GetGraph()->GetAllocator(), 0); 386b1994897Sopenharmony_ci } 387b1994897Sopenharmony_ci immediates_->emplace_back(SaveStateImm {imm, vreg, type, is_acc}); 388b1994897Sopenharmony_ci} 389b1994897Sopenharmony_ci 390b1994897Sopenharmony_civoid SaveStateInst::AllocateImmediates(ArenaAllocator *allocator, size_t size) 391b1994897Sopenharmony_ci{ 392b1994897Sopenharmony_ci immediates_ = allocator->New<ArenaVector<SaveStateImm>>(allocator->Adapter()); 393b1994897Sopenharmony_ci CHECK_NOT_NULL(immediates_); 394b1994897Sopenharmony_ci immediates_->resize(size); 395b1994897Sopenharmony_ci} 396b1994897Sopenharmony_ci 397b1994897Sopenharmony_civoid TryInst::AppendCatchTypeId(uint32_t id, uint32_t catch_edge_index) 398b1994897Sopenharmony_ci{ 399b1994897Sopenharmony_ci if (catch_type_ids_ == nullptr) { 400b1994897Sopenharmony_ci ASSERT(catch_edge_indexes_ == nullptr); 401b1994897Sopenharmony_ci ASSERT(GetBasicBlock() != nullptr); 402b1994897Sopenharmony_ci auto allocator = GetBasicBlock()->GetGraph()->GetAllocator(); 403b1994897Sopenharmony_ci catch_type_ids_ = allocator->New<ArenaVector<uint32_t>>(allocator->Adapter()); 404b1994897Sopenharmony_ci catch_edge_indexes_ = allocator->New<ArenaVector<uint32_t>>(allocator->Adapter()); 405b1994897Sopenharmony_ci CHECK_NOT_NULL(catch_type_ids_); 406b1994897Sopenharmony_ci CHECK_NOT_NULL(catch_edge_indexes_); 407b1994897Sopenharmony_ci } 408b1994897Sopenharmony_ci catch_type_ids_->push_back(id); 409b1994897Sopenharmony_ci catch_edge_indexes_->push_back(catch_edge_index); 410b1994897Sopenharmony_ci} 411b1994897Sopenharmony_ci 412b1994897Sopenharmony_civoid CatchPhiInst::AppendThrowableInst(const Inst *inst) 413b1994897Sopenharmony_ci{ 414b1994897Sopenharmony_ci if (throw_insts_ == nullptr) { 415b1994897Sopenharmony_ci ASSERT(GetBasicBlock() != nullptr); 416b1994897Sopenharmony_ci auto allocator = GetBasicBlock()->GetGraph()->GetAllocator(); 417b1994897Sopenharmony_ci throw_insts_ = allocator->New<ArenaVector<const Inst *>>(allocator->Adapter()); 418b1994897Sopenharmony_ci CHECK_NOT_NULL(throw_insts_); 419b1994897Sopenharmony_ci } 420b1994897Sopenharmony_ci throw_insts_->push_back(inst); 421b1994897Sopenharmony_ci} 422b1994897Sopenharmony_ci 423b1994897Sopenharmony_civoid CatchPhiInst::ReplaceThrowableInst(const Inst *old_inst, const Inst *new_inst) 424b1994897Sopenharmony_ci{ 425b1994897Sopenharmony_ci auto index = GetThrowableInstIndex(old_inst); 426b1994897Sopenharmony_ci throw_insts_->at(index) = new_inst; 427b1994897Sopenharmony_ci} 428b1994897Sopenharmony_ci 429b1994897Sopenharmony_civoid CatchPhiInst::RemoveInput(unsigned index) 430b1994897Sopenharmony_ci{ 431b1994897Sopenharmony_ci Inst::RemoveInput(index); 432b1994897Sopenharmony_ci if (throw_insts_ != nullptr) { 433b1994897Sopenharmony_ci throw_insts_->at(index) = throw_insts_->back(); 434b1994897Sopenharmony_ci throw_insts_->pop_back(); 435b1994897Sopenharmony_ci } 436b1994897Sopenharmony_ci} 437b1994897Sopenharmony_ci 438b1994897Sopenharmony_ciInst *TryInst::Clone(const Graph *targetGraph) const 439b1994897Sopenharmony_ci{ 440b1994897Sopenharmony_ci auto clone = FixedInputsInst::Clone(targetGraph)->CastToTry(); 441b1994897Sopenharmony_ci if (auto ids_count = this->GetCatchTypeIdsCount(); ids_count > 0) { 442b1994897Sopenharmony_ci if (clone->catch_type_ids_ == nullptr) { 443b1994897Sopenharmony_ci auto allocator = targetGraph->GetAllocator(); 444b1994897Sopenharmony_ci clone->catch_type_ids_ = allocator->New<ArenaVector<uint32_t>>(allocator->Adapter()); 445b1994897Sopenharmony_ci clone->catch_edge_indexes_ = allocator->New<ArenaVector<uint32_t>>(allocator->Adapter()); 446b1994897Sopenharmony_ci CHECK_NOT_NULL(clone->catch_edge_indexes_); 447b1994897Sopenharmony_ci } 448b1994897Sopenharmony_ci clone->catch_type_ids_->resize(ids_count); 449b1994897Sopenharmony_ci clone->catch_edge_indexes_->resize(ids_count); 450b1994897Sopenharmony_ci std::copy(this->catch_type_ids_->begin(), this->catch_type_ids_->end(), clone->catch_type_ids_->begin()); 451b1994897Sopenharmony_ci std::copy(this->catch_edge_indexes_->begin(), this->catch_edge_indexes_->end(), 452b1994897Sopenharmony_ci clone->catch_edge_indexes_->begin()); 453b1994897Sopenharmony_ci } 454b1994897Sopenharmony_ci return clone; 455b1994897Sopenharmony_ci} 456b1994897Sopenharmony_ci 457b1994897Sopenharmony_ciBasicBlock *IfImmInst::GetEdgeIfInputTrue() 458b1994897Sopenharmony_ci{ 459b1994897Sopenharmony_ci return GetBasicBlock()->GetSuccessor(GetTrueInputEdgeIdx()); 460b1994897Sopenharmony_ci} 461b1994897Sopenharmony_ci 462b1994897Sopenharmony_ciBasicBlock *IfImmInst::GetEdgeIfInputFalse() 463b1994897Sopenharmony_ci{ 464b1994897Sopenharmony_ci return GetBasicBlock()->GetSuccessor(1 - GetTrueInputEdgeIdx()); 465b1994897Sopenharmony_ci} 466b1994897Sopenharmony_ci 467b1994897Sopenharmony_ci/** 468b1994897Sopenharmony_ci * NB! Can be called before Lowering pass only 469b1994897Sopenharmony_ci * Return if_imm's block successor index when input is true 470b1994897Sopenharmony_ci */ 471b1994897Sopenharmony_cisize_t IfImmInst::GetTrueInputEdgeIdx() 472b1994897Sopenharmony_ci{ 473b1994897Sopenharmony_ci ASSERT(GetBasicBlock() != nullptr); 474b1994897Sopenharmony_ci ASSERT(GetBasicBlock()->GetSuccsBlocks().size() == MAX_SUCCS_NUM); 475b1994897Sopenharmony_ci ASSERT(GetCc() == ConditionCode::CC_NE || GetCc() == ConditionCode::CC_EQ); 476b1994897Sopenharmony_ci ASSERT(GetImm() == 0); 477b1994897Sopenharmony_ci return GetCc() == CC_NE ? 0 : 1; 478b1994897Sopenharmony_ci} 479b1994897Sopenharmony_ci 480b1994897Sopenharmony_cibool Inst::IsPropagateLiveness() const 481b1994897Sopenharmony_ci{ 482b1994897Sopenharmony_ci return (CanThrow() && GetBasicBlock()->IsTry()) || CanDeoptimize(); 483b1994897Sopenharmony_ci} 484b1994897Sopenharmony_ci 485b1994897Sopenharmony_cibool Inst::RequireRegMap() const 486b1994897Sopenharmony_ci{ 487b1994897Sopenharmony_ci return CanThrow() && GetBasicBlock()->IsTry(); 488b1994897Sopenharmony_ci} 489b1994897Sopenharmony_ci 490b1994897Sopenharmony_cibool Inst::IsZeroRegInst() const 491b1994897Sopenharmony_ci{ 492b1994897Sopenharmony_ci ASSERT(GetBasicBlock() != nullptr); 493b1994897Sopenharmony_ci ASSERT(GetBasicBlock()->GetGraph() != nullptr); 494b1994897Sopenharmony_ci return false; 495b1994897Sopenharmony_ci} 496b1994897Sopenharmony_ci 497b1994897Sopenharmony_cibool Inst::IsAccRead() const 498b1994897Sopenharmony_ci{ 499b1994897Sopenharmony_ci return GetFlag(inst_flags::ACC_READ); 500b1994897Sopenharmony_ci} 501b1994897Sopenharmony_ci 502b1994897Sopenharmony_cibool Inst::IsAccWrite() const 503b1994897Sopenharmony_ci{ 504b1994897Sopenharmony_ci if (IsConst()) { 505b1994897Sopenharmony_ci return true; 506b1994897Sopenharmony_ci } 507b1994897Sopenharmony_ci return GetFlag(inst_flags::ACC_WRITE); 508b1994897Sopenharmony_ci} 509b1994897Sopenharmony_ci 510b1994897Sopenharmony_ciTryInst *GetTryBeginInst(const BasicBlock *try_begin_bb) 511b1994897Sopenharmony_ci{ 512b1994897Sopenharmony_ci ASSERT(try_begin_bb != nullptr && try_begin_bb->IsTryBegin()); 513b1994897Sopenharmony_ci for (auto inst : try_begin_bb->AllInsts()) { 514b1994897Sopenharmony_ci if (inst->GetOpcode() == Opcode::Try) { 515b1994897Sopenharmony_ci return inst->CastToTry(); 516b1994897Sopenharmony_ci } 517b1994897Sopenharmony_ci } 518b1994897Sopenharmony_ci UNREACHABLE(); 519b1994897Sopenharmony_ci return nullptr; 520b1994897Sopenharmony_ci} 521b1994897Sopenharmony_ci 522b1994897Sopenharmony_ci/** 523b1994897Sopenharmony_ci * Regalloc's helper to checks if intrinsic's arguments should be located on the registers according to 524b1994897Sopenharmony_ci * calling-convention 525b1994897Sopenharmony_ci */ 526b1994897Sopenharmony_cibool IntrinsicInst::IsNativeCall() const 527b1994897Sopenharmony_ci{ 528b1994897Sopenharmony_ci return false; 529b1994897Sopenharmony_ci} 530b1994897Sopenharmony_ci 531b1994897Sopenharmony_ci} // namespace panda::compiler 532