14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#include "ecmascript/compiler/escape_analysis.h" 174514f5e3Sopenharmony_ci 184514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu { 194514f5e3Sopenharmony_ci 204514f5e3Sopenharmony_ciVirtualObject::VirtualObject(size_t numIn, Chunk* chunk) 214514f5e3Sopenharmony_ci : fields_(chunk), users_(chunk) 224514f5e3Sopenharmony_ci{ 234514f5e3Sopenharmony_ci for (size_t i = 0; i < numIn; i++) { 244514f5e3Sopenharmony_ci FieldLocation tmp; 254514f5e3Sopenharmony_ci fields_.emplace_back(tmp); 264514f5e3Sopenharmony_ci } 274514f5e3Sopenharmony_ci} 284514f5e3Sopenharmony_ci 294514f5e3Sopenharmony_civoid VirtualObject::SetEscaped() 304514f5e3Sopenharmony_ci{ 314514f5e3Sopenharmony_ci escaped_ = true; 324514f5e3Sopenharmony_ci} 334514f5e3Sopenharmony_ci 344514f5e3Sopenharmony_cibool VirtualObject::IsEscaped() const 354514f5e3Sopenharmony_ci{ 364514f5e3Sopenharmony_ci return escaped_; 374514f5e3Sopenharmony_ci} 384514f5e3Sopenharmony_ci 394514f5e3Sopenharmony_ciFieldLocation VirtualObject::GetField(size_t offset) 404514f5e3Sopenharmony_ci{ 414514f5e3Sopenharmony_ci constexpr size_t fieldSize = 8; 424514f5e3Sopenharmony_ci ASSERT(offset % fieldSize == 0); 434514f5e3Sopenharmony_ci if (offset / fieldSize >= fields_.size()) { 444514f5e3Sopenharmony_ci return FieldLocation::Invalid(); 454514f5e3Sopenharmony_ci } 464514f5e3Sopenharmony_ci return fields_.at(offset/fieldSize); 474514f5e3Sopenharmony_ci} 484514f5e3Sopenharmony_ci 494514f5e3Sopenharmony_cisize_t FieldLocation::maxid = 0; 504514f5e3Sopenharmony_ci 514514f5e3Sopenharmony_ciChunkVector<GateRef>& VirtualObject::GetUsers() 524514f5e3Sopenharmony_ci{ 534514f5e3Sopenharmony_ci return users_; 544514f5e3Sopenharmony_ci} 554514f5e3Sopenharmony_ci 564514f5e3Sopenharmony_civoid VirtualObject::ClearUsers() 574514f5e3Sopenharmony_ci{ 584514f5e3Sopenharmony_ci users_.clear(); 594514f5e3Sopenharmony_ci} 604514f5e3Sopenharmony_ci 614514f5e3Sopenharmony_civoid VirtualObject::AddUser(GateRef gate) 624514f5e3Sopenharmony_ci{ 634514f5e3Sopenharmony_ci users_.push_back(gate); 644514f5e3Sopenharmony_ci} 654514f5e3Sopenharmony_ci 664514f5e3Sopenharmony_ciGateInfo::GateInfo(Circuit* circuit, GateRef curGate, EscapeAnalysis* escapeAnalysis, Chunk* chunk) 674514f5e3Sopenharmony_ci : circuit_(circuit), acc_(circuit), curGate_(curGate), escapeAnalysis_(escapeAnalysis), state_(chunk) 684514f5e3Sopenharmony_ci{ 694514f5e3Sopenharmony_ci if (acc_.GetOpCode(curGate) == OpCode::DEPEND_SELECTOR) { 704514f5e3Sopenharmony_ci state_ = MergeState(curGate); 714514f5e3Sopenharmony_ci } else { 724514f5e3Sopenharmony_ci ASSERT(acc_.GetDependCount(curGate) <= 1); 734514f5e3Sopenharmony_ci if (acc_.GetDependCount(curGate) == 1) { 744514f5e3Sopenharmony_ci state_ = escapeAnalysis_->GetOrCreateState(acc_.GetDep(curGate)); 754514f5e3Sopenharmony_ci } 764514f5e3Sopenharmony_ci } 774514f5e3Sopenharmony_ci} 784514f5e3Sopenharmony_ci 794514f5e3Sopenharmony_ciGateInfo::~GateInfo() 804514f5e3Sopenharmony_ci{ 814514f5e3Sopenharmony_ci State& preState = escapeAnalysis_->GetOrCreateState(curGate_); 824514f5e3Sopenharmony_ci if (state_.IsMapEqual(preState) || 834514f5e3Sopenharmony_ci object_ != escapeAnalysis_->TryGetVirtualObject(curGate_)) { 844514f5e3Sopenharmony_ci escapeAnalysis_->SetReplaceGate(curGate_); 854514f5e3Sopenharmony_ci } 864514f5e3Sopenharmony_ci escapeAnalysis_->SetState(curGate_, state_); 874514f5e3Sopenharmony_ci 884514f5e3Sopenharmony_ci escapeAnalysis_->SetVirtualObject(curGate_, object_); 894514f5e3Sopenharmony_ci escapeAnalysis_->SetReplacement(curGate_, replacement_); 904514f5e3Sopenharmony_ci} 914514f5e3Sopenharmony_ci 924514f5e3Sopenharmony_ciGateRef GateInfo::GetCurrentGate() const 934514f5e3Sopenharmony_ci{ 944514f5e3Sopenharmony_ci return curGate_; 954514f5e3Sopenharmony_ci} 964514f5e3Sopenharmony_ci 974514f5e3Sopenharmony_ciState GateInfo::MergeState(GateRef gate) 984514f5e3Sopenharmony_ci{ 994514f5e3Sopenharmony_ci size_t numIn = acc_.GetDependCount(gate); 1004514f5e3Sopenharmony_ci State& preState = escapeAnalysis_->GetOrCreateState(acc_.GetDep(gate, 0)); 1014514f5e3Sopenharmony_ci State result = preState; 1024514f5e3Sopenharmony_ci for (auto fieldValue : preState) { 1034514f5e3Sopenharmony_ci FieldLocation field = fieldValue.first; 1044514f5e3Sopenharmony_ci GateRef value = fieldValue.second; 1054514f5e3Sopenharmony_ci ASSERT(field != FieldLocation::Invalid()); 1064514f5e3Sopenharmony_ci if (value != Circuit::NullGate()) { 1074514f5e3Sopenharmony_ci std::vector<GateRef> input; 1084514f5e3Sopenharmony_ci input.push_back(acc_.GetState(gate)); 1094514f5e3Sopenharmony_ci input.push_back(value); 1104514f5e3Sopenharmony_ci size_t numAliveState = 1; 1114514f5e3Sopenharmony_ci bool differentFlag = false; 1124514f5e3Sopenharmony_ci for (size_t i = 1; i < numIn; i++) { 1134514f5e3Sopenharmony_ci State& inputState = escapeAnalysis_->GetOrCreateState(acc_.GetDep(gate, i)); 1144514f5e3Sopenharmony_ci GateRef inputValue = inputState.GetFieldValue(field); 1154514f5e3Sopenharmony_ci if (inputValue != Circuit::NullGate()) { 1164514f5e3Sopenharmony_ci numAliveState++; 1174514f5e3Sopenharmony_ci } 1184514f5e3Sopenharmony_ci if (inputValue != value) { 1194514f5e3Sopenharmony_ci differentFlag = true; 1204514f5e3Sopenharmony_ci } 1214514f5e3Sopenharmony_ci input.push_back(inputValue); 1224514f5e3Sopenharmony_ci } 1234514f5e3Sopenharmony_ci 1244514f5e3Sopenharmony_ci if (numAliveState == 1 && acc_.GetOpCode(acc_.GetState(gate)) == OpCode::LOOP_BEGIN) { 1254514f5e3Sopenharmony_ci result.SetFieldValue(field, value); 1264514f5e3Sopenharmony_ci } else if (numAliveState < numIn) { 1274514f5e3Sopenharmony_ci result.SetFieldValue(field, Circuit::NullGate()); 1284514f5e3Sopenharmony_ci } else { 1294514f5e3Sopenharmony_ci if (!differentFlag) { 1304514f5e3Sopenharmony_ci result.SetFieldValue(field, value); 1314514f5e3Sopenharmony_ci } else { 1324514f5e3Sopenharmony_ci State& oldState = escapeAnalysis_->GetOrCreateState(gate); 1334514f5e3Sopenharmony_ci GateRef oldValue = oldState.GetFieldValue(field); 1344514f5e3Sopenharmony_ci if (oldValue != Circuit::NullGate() && 1354514f5e3Sopenharmony_ci acc_.GetOpCode(oldValue) == OpCode::DEPEND_SELECTOR && 1364514f5e3Sopenharmony_ci acc_.GetState(oldValue) == acc_.GetState(gate)) { 1374514f5e3Sopenharmony_ci for (size_t i = 0; i < numIn; i++) { 1384514f5e3Sopenharmony_ci ASSERT(input[i + 1] != Circuit::NullGate()); 1394514f5e3Sopenharmony_ci if (acc_.GetValueIn(oldValue, i) != input[i + 1]) { 1404514f5e3Sopenharmony_ci acc_.ReplaceValueIn(oldValue, input[i + 1], i); 1414514f5e3Sopenharmony_ci escapeAnalysis_->RevisitGate(oldValue); 1424514f5e3Sopenharmony_ci } 1434514f5e3Sopenharmony_ci } 1444514f5e3Sopenharmony_ci result.SetFieldValue(field, oldValue); 1454514f5e3Sopenharmony_ci } else { 1464514f5e3Sopenharmony_ci MachineType machineType = acc_.GetMachineType(value); 1474514f5e3Sopenharmony_ci auto gateType = acc_.GetGateType(value); 1484514f5e3Sopenharmony_ci const GateMetaData* meta = circuit_->ValueSelector(numIn); 1494514f5e3Sopenharmony_ci GateRef valueSelector = circuit_->NewGate(meta, machineType, input.size(), 1504514f5e3Sopenharmony_ci input.data(), gateType); 1514514f5e3Sopenharmony_ci result.SetFieldValue(field, valueSelector); 1524514f5e3Sopenharmony_ci escapeAnalysis_->RevisitGate(valueSelector); 1534514f5e3Sopenharmony_ci } 1544514f5e3Sopenharmony_ci } 1554514f5e3Sopenharmony_ci } 1564514f5e3Sopenharmony_ci } 1574514f5e3Sopenharmony_ci } 1584514f5e3Sopenharmony_ci return result; 1594514f5e3Sopenharmony_ci} 1604514f5e3Sopenharmony_ci 1614514f5e3Sopenharmony_ciGateRef GateInfo::GetFieldValue(FieldLocation field) const 1624514f5e3Sopenharmony_ci{ 1634514f5e3Sopenharmony_ci return state_.GetFieldValue(field); 1644514f5e3Sopenharmony_ci} 1654514f5e3Sopenharmony_ci 1664514f5e3Sopenharmony_civoid GateInfo::SetFieldValue(FieldLocation field, GateRef value) 1674514f5e3Sopenharmony_ci{ 1684514f5e3Sopenharmony_ci state_.SetFieldValue(field, value); 1694514f5e3Sopenharmony_ci} 1704514f5e3Sopenharmony_ci 1714514f5e3Sopenharmony_civoid GateInfo::SetEliminated() 1724514f5e3Sopenharmony_ci{ 1734514f5e3Sopenharmony_ci replacement_ = circuit_->DeadGate(); 1744514f5e3Sopenharmony_ci object_ = nullptr; 1754514f5e3Sopenharmony_ci} 1764514f5e3Sopenharmony_ci 1774514f5e3Sopenharmony_civoid GateInfo::SetReplacement(GateRef replacement) 1784514f5e3Sopenharmony_ci{ 1794514f5e3Sopenharmony_ci replacement_ = replacement; 1804514f5e3Sopenharmony_ci object_ = escapeAnalysis_->TryGetVirtualObject(replacement); 1814514f5e3Sopenharmony_ci} 1824514f5e3Sopenharmony_ci 1834514f5e3Sopenharmony_civoid GateInfo::SetVirtualObject(VirtualObject* object) 1844514f5e3Sopenharmony_ci{ 1854514f5e3Sopenharmony_ci object_ = object; 1864514f5e3Sopenharmony_ci} 1874514f5e3Sopenharmony_ci 1884514f5e3Sopenharmony_civoid State::SetFieldValue(FieldLocation field, GateRef gate) 1894514f5e3Sopenharmony_ci{ 1904514f5e3Sopenharmony_ci map_[field] = gate; 1914514f5e3Sopenharmony_ci} 1924514f5e3Sopenharmony_ci 1934514f5e3Sopenharmony_ciGateRef State::GetFieldValue(FieldLocation field) const 1944514f5e3Sopenharmony_ci{ 1954514f5e3Sopenharmony_ci auto result = map_.find(field); 1964514f5e3Sopenharmony_ci if (result == map_.end()) { 1974514f5e3Sopenharmony_ci return Circuit::NullGate(); 1984514f5e3Sopenharmony_ci } 1994514f5e3Sopenharmony_ci return result->second; 2004514f5e3Sopenharmony_ci} 2014514f5e3Sopenharmony_ci 2024514f5e3Sopenharmony_cibool State::IsMapEqual(const State &state) const 2034514f5e3Sopenharmony_ci{ 2044514f5e3Sopenharmony_ci return map_.size() == state.map_.size() && 2054514f5e3Sopenharmony_ci std::equal(map_.begin(), map_.end(), state.map_.begin()); 2064514f5e3Sopenharmony_ci} 2074514f5e3Sopenharmony_ci 2084514f5e3Sopenharmony_civoid EscapeAnalysis::SetReplacement(GateRef gate, GateRef replacement) 2094514f5e3Sopenharmony_ci{ 2104514f5e3Sopenharmony_ci replacements_[gate] = replacement; 2114514f5e3Sopenharmony_ci} 2124514f5e3Sopenharmony_ci 2134514f5e3Sopenharmony_ciGateRef EscapeAnalysis::TryGetReplacement(GateRef gate) const 2144514f5e3Sopenharmony_ci{ 2154514f5e3Sopenharmony_ci if (!replacements_.count(gate)) { 2164514f5e3Sopenharmony_ci return Circuit::NullGate(); 2174514f5e3Sopenharmony_ci } 2184514f5e3Sopenharmony_ci return replacements_.at(gate); 2194514f5e3Sopenharmony_ci} 2204514f5e3Sopenharmony_ci 2214514f5e3Sopenharmony_ciGateRef EscapeAnalysis::GetCurrentGate(GateRef gate) const 2224514f5e3Sopenharmony_ci{ 2234514f5e3Sopenharmony_ci GateRef replacement = TryGetReplacement(gate); 2244514f5e3Sopenharmony_ci if (replacement == Circuit::NullGate()) { 2254514f5e3Sopenharmony_ci return gate; 2264514f5e3Sopenharmony_ci } 2274514f5e3Sopenharmony_ci return replacement; 2284514f5e3Sopenharmony_ci} 2294514f5e3Sopenharmony_ci 2304514f5e3Sopenharmony_ciVirtualObject* EscapeAnalysis::TryGetVirtualObject(GateRef gate) const 2314514f5e3Sopenharmony_ci{ 2324514f5e3Sopenharmony_ci if (gateToVirtualObject_.count(gate)) { 2334514f5e3Sopenharmony_ci VirtualObject* vObj = gateToVirtualObject_.at(gate); 2344514f5e3Sopenharmony_ci return vObj; 2354514f5e3Sopenharmony_ci } 2364514f5e3Sopenharmony_ci return nullptr; 2374514f5e3Sopenharmony_ci} 2384514f5e3Sopenharmony_ci 2394514f5e3Sopenharmony_ciVirtualObject* EscapeAnalysis::TryGetVirtualObjectAndAddUser(GateRef gate, GateRef currentGate) 2404514f5e3Sopenharmony_ci{ 2414514f5e3Sopenharmony_ci if (gateToVirtualObject_.count(gate)) { 2424514f5e3Sopenharmony_ci VirtualObject* vObj = gateToVirtualObject_[gate]; 2434514f5e3Sopenharmony_ci if (vObj != nullptr) { 2444514f5e3Sopenharmony_ci vObj->AddUser(currentGate); 2454514f5e3Sopenharmony_ci } 2464514f5e3Sopenharmony_ci return vObj; 2474514f5e3Sopenharmony_ci } 2484514f5e3Sopenharmony_ci return nullptr; 2494514f5e3Sopenharmony_ci} 2504514f5e3Sopenharmony_ci 2514514f5e3Sopenharmony_ci 2524514f5e3Sopenharmony_civoid EscapeAnalysis::SetVirtualObject(GateRef gate, VirtualObject* object) 2534514f5e3Sopenharmony_ci{ 2544514f5e3Sopenharmony_ci gateToVirtualObject_[gate] = object; 2554514f5e3Sopenharmony_ci} 2564514f5e3Sopenharmony_ci 2574514f5e3Sopenharmony_civoid EscapeAnalysis::RevisitUser(VirtualObject* vObj) 2584514f5e3Sopenharmony_ci{ 2594514f5e3Sopenharmony_ci auto& users = vObj->GetUsers(); 2604514f5e3Sopenharmony_ci for (auto user : users) { 2614514f5e3Sopenharmony_ci if (isTraced_) { 2624514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << "[escape analysis] revisit user : " <<acc_.GetId(user); 2634514f5e3Sopenharmony_ci } 2644514f5e3Sopenharmony_ci visitor_->ReVisitGate(user); 2654514f5e3Sopenharmony_ci } 2664514f5e3Sopenharmony_ci vObj->ClearUsers(); 2674514f5e3Sopenharmony_ci} 2684514f5e3Sopenharmony_ci 2694514f5e3Sopenharmony_civoid EscapeAnalysis::SetEscaped(GateRef gate) 2704514f5e3Sopenharmony_ci{ 2714514f5e3Sopenharmony_ci if (isTraced_) { 2724514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << "[escape analysis] set escaped: " << acc_.GetId(gate); 2734514f5e3Sopenharmony_ci } 2744514f5e3Sopenharmony_ci VirtualObject* vObj = TryGetVirtualObject(gate); 2754514f5e3Sopenharmony_ci if (vObj != nullptr && !vObj->IsEscaped()) { 2764514f5e3Sopenharmony_ci vObj->SetEscaped(); 2774514f5e3Sopenharmony_ci RevisitUser(vObj); 2784514f5e3Sopenharmony_ci } 2794514f5e3Sopenharmony_ci} 2804514f5e3Sopenharmony_ci 2814514f5e3Sopenharmony_ciVirtualObject* EscapeAnalysis::GetOrCreateVirtualObject(size_t numIn, GateInfo* info) 2824514f5e3Sopenharmony_ci{ 2834514f5e3Sopenharmony_ci GateRef gate = info->GetCurrentGate(); 2844514f5e3Sopenharmony_ci VirtualObject* vobj = TryGetVirtualObject(gate); 2854514f5e3Sopenharmony_ci if (vobj == nullptr) { 2864514f5e3Sopenharmony_ci vobj = chunk_->New<VirtualObject>(numIn, chunk_); 2874514f5e3Sopenharmony_ci } 2884514f5e3Sopenharmony_ci vobj->AddUser(gate); 2894514f5e3Sopenharmony_ci info->SetVirtualObject(vobj); 2904514f5e3Sopenharmony_ci return vobj; 2914514f5e3Sopenharmony_ci} 2924514f5e3Sopenharmony_ci 2934514f5e3Sopenharmony_ci 2944514f5e3Sopenharmony_ciGateRef EscapeAnalysis::VisitCreateObjectWithBuffer(GateRef gate, GateInfo* info) 2954514f5e3Sopenharmony_ci{ 2964514f5e3Sopenharmony_ci constexpr size_t startIn = 4; // 4 : start of props 2974514f5e3Sopenharmony_ci constexpr size_t fieldSize = 8; // 8 : bytes per field 2984514f5e3Sopenharmony_ci constexpr size_t stride = 2; // 2: offset and value 2994514f5e3Sopenharmony_ci auto numIn = acc_.GetNumValueIn(gate); 3004514f5e3Sopenharmony_ci size_t size = acc_.GetConstantValue(acc_.GetValueIn(gate, 0)) / fieldSize; 3014514f5e3Sopenharmony_ci VirtualObject* vObj = GetOrCreateVirtualObject(size, info); 3024514f5e3Sopenharmony_ci 3034514f5e3Sopenharmony_ci for (size_t i = startIn; i < numIn; i += stride) { 3044514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, i); 3054514f5e3Sopenharmony_ci GateRef offset = acc_.GetValueIn(gate, i + 1); 3064514f5e3Sopenharmony_ci if (vObj != nullptr && !vObj->IsEscaped() && 3074514f5e3Sopenharmony_ci vObj->GetField(acc_.GetConstantValue(offset)) != FieldLocation::Invalid()) { 3084514f5e3Sopenharmony_ci info->SetFieldValue(vObj->GetField(acc_.GetConstantValue(offset)), value); 3094514f5e3Sopenharmony_ci } else { 3104514f5e3Sopenharmony_ci SetEscaped(value); 3114514f5e3Sopenharmony_ci SetEscaped(gate); 3124514f5e3Sopenharmony_ci } 3134514f5e3Sopenharmony_ci } 3144514f5e3Sopenharmony_ci info->SetVirtualObject(vObj); 3154514f5e3Sopenharmony_ci return replaceGate_; 3164514f5e3Sopenharmony_ci} 3174514f5e3Sopenharmony_ci 3184514f5e3Sopenharmony_ciGateRef EscapeAnalysis::VisitLoadProperty(GateRef gate, GateInfo* info) 3194514f5e3Sopenharmony_ci{ 3204514f5e3Sopenharmony_ci GateRef object = acc_.GetValueIn(gate, 0); 3214514f5e3Sopenharmony_ci GateRef offset = acc_.GetValueIn(gate, 1); 3224514f5e3Sopenharmony_ci VirtualObject* vObj = TryGetVirtualObjectAndAddUser(object, gate); 3234514f5e3Sopenharmony_ci 3244514f5e3Sopenharmony_ci PropertyLookupResult plr(acc_.GetConstantValue(offset)); 3254514f5e3Sopenharmony_ci 3264514f5e3Sopenharmony_ci if (vObj != nullptr && !vObj->IsEscaped() && vObj->GetField(plr.GetOffset()) != FieldLocation::Invalid()) { 3274514f5e3Sopenharmony_ci GateRef value = info->GetFieldValue(vObj->GetField(plr.GetOffset())); 3284514f5e3Sopenharmony_ci if (value != Circuit::NullGate()) { 3294514f5e3Sopenharmony_ci if (isTraced_) { 3304514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << "[escape analysis] replace" << acc_.GetId(gate) << " with " << acc_.GetId(value); 3314514f5e3Sopenharmony_ci } 3324514f5e3Sopenharmony_ci info->SetReplacement(value); 3334514f5e3Sopenharmony_ci } else { 3344514f5e3Sopenharmony_ci SetEscaped(object); 3354514f5e3Sopenharmony_ci } 3364514f5e3Sopenharmony_ci } else { 3374514f5e3Sopenharmony_ci SetEscaped(object); 3384514f5e3Sopenharmony_ci } 3394514f5e3Sopenharmony_ci return replaceGate_; 3404514f5e3Sopenharmony_ci} 3414514f5e3Sopenharmony_ci 3424514f5e3Sopenharmony_ciGateRef EscapeAnalysis::VisitLoadConstOffset(GateRef gate, GateInfo* info) 3434514f5e3Sopenharmony_ci{ 3444514f5e3Sopenharmony_ci GateRef object = acc_.GetValueIn(gate, 0); 3454514f5e3Sopenharmony_ci size_t offset = acc_.GetOffset(gate); 3464514f5e3Sopenharmony_ci VirtualObject* vObj = TryGetVirtualObjectAndAddUser(object, gate); 3474514f5e3Sopenharmony_ci 3484514f5e3Sopenharmony_ci if (vObj != nullptr && !vObj->IsEscaped() && vObj->GetField(offset) != FieldLocation::Invalid()) { 3494514f5e3Sopenharmony_ci GateRef value = info->GetFieldValue(vObj->GetField(offset)); 3504514f5e3Sopenharmony_ci if (value != Circuit::NullGate()) { 3514514f5e3Sopenharmony_ci if (isTraced_) { 3524514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << "[escape analysis] replace " << 3534514f5e3Sopenharmony_ci acc_.GetId(gate) << " with " << acc_.GetId(value); 3544514f5e3Sopenharmony_ci } 3554514f5e3Sopenharmony_ci info->SetReplacement(value); 3564514f5e3Sopenharmony_ci } else { 3574514f5e3Sopenharmony_ci SetEscaped(object); 3584514f5e3Sopenharmony_ci } 3594514f5e3Sopenharmony_ci } else { 3604514f5e3Sopenharmony_ci SetEscaped(object); 3614514f5e3Sopenharmony_ci } 3624514f5e3Sopenharmony_ci return replaceGate_; 3634514f5e3Sopenharmony_ci} 3644514f5e3Sopenharmony_ci 3654514f5e3Sopenharmony_ci 3664514f5e3Sopenharmony_ciGateRef EscapeAnalysis::VisitStoreProperty(GateRef gate, GateInfo* info) 3674514f5e3Sopenharmony_ci{ 3684514f5e3Sopenharmony_ci GateRef object = acc_.GetValueIn(gate, 0); 3694514f5e3Sopenharmony_ci GateRef offset = acc_.GetValueIn(gate, 1); 3704514f5e3Sopenharmony_ci GateRef value = acc_.GetValueIn(gate, 2); 3714514f5e3Sopenharmony_ci VirtualObject* vObj = TryGetVirtualObjectAndAddUser(object, gate); 3724514f5e3Sopenharmony_ci PropertyLookupResult plr(acc_.GetConstantValue(offset)); 3734514f5e3Sopenharmony_ci 3744514f5e3Sopenharmony_ci if (vObj != nullptr && !vObj->IsEscaped() && vObj->GetField(plr.GetOffset()) != FieldLocation::Invalid()) { 3754514f5e3Sopenharmony_ci info->SetFieldValue(vObj->GetField(plr.GetOffset()), value); 3764514f5e3Sopenharmony_ci info->SetEliminated(); 3774514f5e3Sopenharmony_ci } else { 3784514f5e3Sopenharmony_ci SetEscaped(value); 3794514f5e3Sopenharmony_ci SetEscaped(object); 3804514f5e3Sopenharmony_ci } 3814514f5e3Sopenharmony_ci return replaceGate_; 3824514f5e3Sopenharmony_ci} 3834514f5e3Sopenharmony_ci 3844514f5e3Sopenharmony_ciGateRef EscapeAnalysis::VisitObjectTypeCheck(GateRef gate, GateInfo* info) 3854514f5e3Sopenharmony_ci{ 3864514f5e3Sopenharmony_ci info->SetVirtualObject(TryGetVirtualObject(acc_.GetValueIn(gate))); 3874514f5e3Sopenharmony_ci return Circuit::NullGate(); 3884514f5e3Sopenharmony_ci} 3894514f5e3Sopenharmony_ci 3904514f5e3Sopenharmony_ciState& EscapeAnalysis::GetOrCreateState(GateRef gate) 3914514f5e3Sopenharmony_ci{ 3924514f5e3Sopenharmony_ci auto it = gateToState_.find(gate); 3934514f5e3Sopenharmony_ci if (it == gateToState_.end()) { 3944514f5e3Sopenharmony_ci State tmp(chunk_); 3954514f5e3Sopenharmony_ci auto result = gateToState_.insert(std::make_pair(gate, std::move(tmp))); 3964514f5e3Sopenharmony_ci return result.first->second; 3974514f5e3Sopenharmony_ci } 3984514f5e3Sopenharmony_ci return it->second; 3994514f5e3Sopenharmony_ci} 4004514f5e3Sopenharmony_ci 4014514f5e3Sopenharmony_civoid EscapeAnalysis::SetState(GateRef gate, State state) 4024514f5e3Sopenharmony_ci{ 4034514f5e3Sopenharmony_ci auto it = gateToState_.find(gate); 4044514f5e3Sopenharmony_ci if (it == gateToState_.end()) { 4054514f5e3Sopenharmony_ci gateToState_.insert(std::make_pair(gate, std::move(state))); 4064514f5e3Sopenharmony_ci } else { 4074514f5e3Sopenharmony_ci it->second = state; 4084514f5e3Sopenharmony_ci } 4094514f5e3Sopenharmony_ci} 4104514f5e3Sopenharmony_ci 4114514f5e3Sopenharmony_civoid EscapeAnalysis::RevisitGate(GateRef gate) 4124514f5e3Sopenharmony_ci{ 4134514f5e3Sopenharmony_ci visitor_->ReVisitGate(gate); 4144514f5e3Sopenharmony_ci} 4154514f5e3Sopenharmony_ci 4164514f5e3Sopenharmony_civoid EscapeAnalysis::SetReplaceGate(GateRef gate) 4174514f5e3Sopenharmony_ci{ 4184514f5e3Sopenharmony_ci replaceGate_ = gate; 4194514f5e3Sopenharmony_ci} 4204514f5e3Sopenharmony_ci 4214514f5e3Sopenharmony_ciGateRef EscapeAnalysis::VisitGate(GateRef gate) 4224514f5e3Sopenharmony_ci{ 4234514f5e3Sopenharmony_ci GateInfo info(circuit_, gate, this, chunk_); 4244514f5e3Sopenharmony_ci auto opcode = acc_.GetOpCode(gate); 4254514f5e3Sopenharmony_ci replaceGate_ = Circuit::NullGate(); 4264514f5e3Sopenharmony_ci switch (opcode) { 4274514f5e3Sopenharmony_ci case OpCode::STORE_PROPERTY: 4284514f5e3Sopenharmony_ci case OpCode::STORE_PROPERTY_NO_BARRIER: 4294514f5e3Sopenharmony_ci return VisitStoreProperty(gate, &info); 4304514f5e3Sopenharmony_ci case OpCode::LOAD_PROPERTY: 4314514f5e3Sopenharmony_ci return VisitLoadProperty(gate, &info); 4324514f5e3Sopenharmony_ci case OpCode::LOAD_CONST_OFFSET: 4334514f5e3Sopenharmony_ci return VisitLoadConstOffset(gate, &info); 4344514f5e3Sopenharmony_ci case OpCode::TYPED_CREATE_OBJ_WITH_BUFFER: 4354514f5e3Sopenharmony_ci return VisitCreateObjectWithBuffer(gate, &info); 4364514f5e3Sopenharmony_ci case OpCode::OBJECT_TYPE_CHECK: 4374514f5e3Sopenharmony_ci case OpCode::CHECK_AND_CONVERT: 4384514f5e3Sopenharmony_ci return VisitObjectTypeCheck(gate, &info); 4394514f5e3Sopenharmony_ci case OpCode::FRAME_VALUES: 4404514f5e3Sopenharmony_ci case OpCode::STATE_SPLIT: 4414514f5e3Sopenharmony_ci case OpCode::FRAME_STATE: 4424514f5e3Sopenharmony_ci break; 4434514f5e3Sopenharmony_ci default : { 4444514f5e3Sopenharmony_ci size_t numIns = acc_.GetNumValueIn(gate); 4454514f5e3Sopenharmony_ci for (size_t i = 0; i < numIns; i++) { 4464514f5e3Sopenharmony_ci GateRef in = GetCurrentGate(acc_.GetValueIn(gate, i)); 4474514f5e3Sopenharmony_ci SetEscaped(in); 4484514f5e3Sopenharmony_ci } 4494514f5e3Sopenharmony_ci } 4504514f5e3Sopenharmony_ci } 4514514f5e3Sopenharmony_ci return Circuit::NullGate(); 4524514f5e3Sopenharmony_ci} 4534514f5e3Sopenharmony_ci 4544514f5e3Sopenharmony_ci}